82

I'm trying to build a Metro application for Windows 8 on Visual Studio 2011. and while I'm trying to do that, I'm having some issues on how to parse JSON without JSON.NET library (It doesn't support the metro applications yet).

Anyway, I want to parse this:

{
   "name":"Prince Charming",
   "artist":"Metallica",
   "genre":"Rock and Metal",
   "album":"Reload",
   "album_image":"http:\/\/up203.siz.co.il\/up2\/u2zzzw4mjayz.png",
   "link":"http:\/\/f2h.co.il\/7779182246886"
}
Eli Revah
  • 3,626
  • 7
  • 27
  • 33
  • 1
    You can do it with string manipulation like those of us did before `JSON.NET` and other libraries came about. – M.Babcock Mar 05 '12 at 20:01
  • Use JavascriptSerializer. Take a look at this answer: http://stackoverflow.com/questions/8405458/return-json-data-from-asmx-web-service – frenchie Mar 05 '12 at 20:06
  • 5
    You shouldn't be asking this, MS has not shown more love for anything like it has to Json. There's `Json` in `System.Web.Helpers`, there's `JsonQueryStringConverter` in `System.ServiceModel.Web`, there's `JavascriptSerializer` in `System.Web.Script.Serialization`, `DataContractJsonSerializer` in `System.Runtime.Serialization.Json`... Not at all confusing. – nawfal Jun 15 '15 at 11:03
  • 3
    Heck MS has even decided to include third party `Json.NET` in its ASP.NET Web API. If you thought that wasn't enough, MS is coming up with `System.Json` but currently is unfit for consumption. And Windows 8 is a special case for MS, so there is also `JsonValue` in `Windows.Data.Json` which is only for Windows 8 and above. – nawfal Aug 03 '15 at 17:26
  • 1
    As of late 2016: It seems that [Microsoft has embraced Json.NET](https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx) and possibly abandoned the never-officially-released `System.Json`: https://msdn.microsoft.com/en-us/library/system.json%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396 talks about "preview" and the [Nuget package](http://www.nuget.org/packages/System.Json) is both (still) labeled "Beta" and has been _unlisted_, suggesting deprecation. (There is a released `System.Json`, but it is Silverlight-only). – mklement0 Nov 28 '16 at 20:11

8 Answers8

99

You can use the classes found in the System.Json Namespace which were added in .NET 4.5. You need to add a reference to the System.Runtime.Serialization assembly

The JsonValue.Parse() Method parses JSON text and returns a JsonValue:

JsonValue value = JsonValue.Parse(@"{ ""name"":""Prince Charming"", ...");

If you pass a string with a JSON object, you should be able to cast the value to a JsonObject:

using System.Json;


JsonObject result = value as JsonObject;

Console.WriteLine("Name .... {0}", (string)result["name"]);
Console.WriteLine("Artist .. {0}", (string)result["artist"]);
Console.WriteLine("Genre ... {0}", (string)result["genre"]);
Console.WriteLine("Album ... {0}", (string)result["album"]);

The classes are quite similar to those found in the System.Xml.Linq Namespace.

Andrey Rubshtein
  • 20,795
  • 11
  • 69
  • 104
dtb
  • 213,145
  • 36
  • 401
  • 431
  • 1
    I dont have System.Json namespace... I'm using visual studio 2011 ultimate and when im trying to add reference it gives me an empty list... – Eli Revah Mar 05 '12 at 21:47
  • 21
    You need to add a reference to the System.Runtime.Serialization assembly. – dtb Mar 05 '12 at 22:02
  • 1
    It seems to be in the Windows.Data.Json; now as I can see in my Metro App. – René Stalder Jun 30 '12 at 22:42
  • 8
    Use Nuget to install system.json : Install-Package System.Json – GordonBy Aug 28 '12 at 13:49
  • Is there an example of this strongly-typed with generics? Would like to not waste the time writing something that I don't have to. :) – Jaxidian Oct 28 '12 at 04:15
  • 3
    If the package cannot be found, make sure you add the version number. Example: `PM> Install-Package System.Json -Version 4.0.20126.16343`. Find the current version here: http://nuget.org/packages/System.Json – Adam K Dean Mar 30 '13 at 12:12
  • 6
    System.Json is still in beta and so Nuget package seems to be the way to get it. It is not built-in the most recent full Framework V 4.5.1. Personally I like Json.Net's API which is much less verbose and faster than Windows.Data.Json or System.Json. See http://james.newtonking.com/json/help/html/JsonNetVsWindowsDataJson.htm – Shital Shah Jan 14 '14 at 22:49
  • 4
    cant find system.json – kuldeep Feb 09 '18 at 09:19
  • 1
    @krowe2 - Last time I checked Json.NET was MIT licenced: https://github.com/JamesNK/Newtonsoft.Json/blob/master/LICENSE.md – Shital Shah Mar 14 '18 at 02:20
  • The type or namespace name 'JsonValue' could not be found (are you missing a using directive or an assembly reference?) I'm targeting .NET Framework 4.7.2 and I have added a reference to the System.Runtime.Serialization assembly. I want to avoid using any NuGet packages, otherwise I might as well just use NewtonSoft. – user3700562 Oct 19 '21 at 10:22
41

I use this...but have never done any metro app development, so I don't know of any restrictions on libraries available to you. (note, you'll need to mark your classes as with DataContract and DataMember attributes)

public static class JSONSerializer<TType> where TType : class
{
    /// <summary>
    /// Serializes an object to JSON
    /// </summary>
    public static string Serialize(TType instance)
    {
        var serializer = new DataContractJsonSerializer(typeof(TType));
        using (var stream = new MemoryStream())
        {
            serializer.WriteObject(stream, instance);
            return Encoding.Default.GetString(stream.ToArray());
        }
    }

    /// <summary>
    /// DeSerializes an object from JSON
    /// </summary>
    public static TType DeSerialize(string json)
    {
        using (var stream = new MemoryStream(Encoding.Default.GetBytes(json)))
        {
            var serializer = new DataContractJsonSerializer(typeof(TType));
            return serializer.ReadObject(stream) as TType;
        }
    }
}

So, if you had a class like this...

[DataContract]
public class MusicInfo
{
    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public string Artist { get; set; }

    [DataMember]
    public string Genre { get; set; }

    [DataMember]
    public string Album { get; set; }

    [DataMember]
    public string AlbumImage { get; set; }

    [DataMember]
    public string Link { get; set; }

}

Then you would use it like this...

var musicInfo = new MusicInfo
{
     Name = "Prince Charming",
     Artist = "Metallica",
     Genre = "Rock and Metal",
     Album = "Reload",
     AlbumImage = "http://up203.siz.co.il/up2/u2zzzw4mjayz.png",
     Link = "http://f2h.co.il/7779182246886"
};

// This will produce a JSON String
var serialized = JSONSerializer<MusicInfo>.Serialize(musicInfo);

// This will produce a copy of the instance you created earlier
var deserialized = JSONSerializer<MusicInfo>.DeSerialize(serialized);
mklement0
  • 382,024
  • 64
  • 607
  • 775
ctorx
  • 6,841
  • 8
  • 39
  • 53
  • how do I use it? it keeps asking me for TType, whats that? – Eli Revah Mar 05 '12 at 20:11
  • If your type (class) was called MyType, you would use it like this: JSONSerializer.Serialize() and JSONSerializer.Deserialize(myInstanceOfMyType) – ctorx Mar 05 '12 at 20:12
  • 2
    Looks like dtb has a newer native way (answered above) if you're using v4.5 of the Framework. – ctorx Mar 05 '12 at 20:14
  • You have to use Encoding.UTF8.GetString(stream.ToArray()); if you want to support unicode. – mrexodia Aug 17 '17 at 19:10
  • How do you deal, if you have an object inside your custom object that does not have a DataContract and DataMember attribute? – LEMUEL ADANE Nov 28 '17 at 04:24
  • @ctorx How to deal same problem for list of objects i.e. if we want to write 100s of objects to a file and then restore same file's contents into a list of same objects? – Dia Sheikh May 21 '20 at 07:29
11

For those who do not have 4.5, Here is my library function that reads json. It requires a project reference to System.Web.Extensions.

using System.Web.Script.Serialization;

public object DeserializeJson<T>(string Json)
{
    JavaScriptSerializer JavaScriptSerializer = new JavaScriptSerializer();
    return JavaScriptSerializer.Deserialize<T>(Json);
}

Usually, json is written out based on a contract. That contract can and usually will be codified in a class (T). Sometimes you can take a word from the json and search the object browser to find that type.

Example usage:

Given the json

{"logEntries":[],"value":"My Code","text":"My Text","enabled":true,"checkedIndices":[],"checkedItemsTextOverflows":false}

You could parse it into a RadComboBoxClientState object like this:

string ClientStateJson = Page.Request.Form("ReportGrid1_cboReportType_ClientState");
RadComboBoxClientState RadComboBoxClientState = DeserializeJson<RadComboBoxClientState>(ClientStateJson);
return RadComboBoxClientState.Value;

Link to docs

Ssh Quack
  • 647
  • 10
  • 13
toddmo
  • 20,682
  • 14
  • 97
  • 107
7

I needed a JSON serializer and deserializer without any 3rd party dependency or nuget, that can support old systems, so you don't have to choose between Newtonsoft.Json, System.Text.Json, DataContractSerializer, JavaScriptSerializer, etc. depending on the target platform.

So I have started this "ZeroDepJson" open source (MIT licensed) project here:

https://github.com/smourier/ZeroDepJson

It's just one C# file ZeroDepJson.cs, compatible with .NET Framework 4.x to .NET Core/5/6/7+.

Note absolute performance is not a goal. Although its performance is, I hope, decent, if you're after the best performing JSON serializer / deserializer ever, then don't use this.

Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
  • 2
    I love libraries like this. Probably will use this one for a SQL SSIS package script that needs to parse JSON from a REST response. Thanks!!! – pettys Mar 29 '22 at 15:24
6

Have you tried using JavaScriptSerializer ? There's also DataContractJsonSerializer

YS.
  • 1,808
  • 1
  • 19
  • 33
  • Nope, can you explain to me whats that? thanx dude – Eli Revah Mar 05 '12 at 20:03
  • 2
    DataContract: http://msdn.microsoft.com/en-us/library/bb908432.aspx JavaScriptSerializer: http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx – YS. Mar 05 '12 at 20:04
  • Re `JavaScriptSerializer`: As of this writing, its [MSDN page](https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx) recommends using [Json.NET](http://json.net) instead. – mklement0 Nov 28 '16 at 20:17
2

I have written a small construct to do that long back, it requires System.Runtime.Serialization.Json namespace. It uses DataContractJsonSerializer to serialize & deserialize object with a static method JConvert.

It works with small set of data but haven't tested with big data source.

JsonHelper.cs

// Json Serializer without NewtonSoft
public static class JsonHelper
{
    public static R JConvert<P,R>(this P t)
    {       
        if(typeof(P) == typeof(string))
        {
            var return1 =  (R)(JsonDeserializer<R>(t as string));
            return return1;
        }
        else
        {
            var return2 =  (JsonSerializer<P>(t));
            R result = (R)Convert.ChangeType(return2, typeof(R));
            return result;
        }   
    }
    
    private static String JsonSerializer<T>(T t)
    {
        var stream1 = new MemoryStream();
        var ser = new DataContractJsonSerializer(typeof(T));
        ser.WriteObject(stream1, t);
        stream1.Position = 0;
        var sr = new StreamReader(stream1);     
        return (sr.ReadToEnd());
    }
    
    private static T JsonDeserializer<T>(string jsonString)
    {
        T deserializedUser = default(T);
        var ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
        var ser = new DataContractJsonSerializer(typeof(T));
        deserializedUser = (T)ser.ReadObject(ms);// as T;
        ms.Close();
        return deserializedUser;
    }
}

Syntax:

To use the JsonHelper you need to call

JConvert<string,object>(str); //to Parse string to non anonymous <object>
JConvert<object,string>(obj); //to convert <obj> to string

Example:

Suppose we have a class person

public class person
{
    public string FirstName {get;set;}
    public string LastName {get;set;}
}

var obj = new person();//"vinod","srivastav");
obj.FirstName = "vinod";
obj.LastName = "srivastav";

To convert the person object we can call:

var asText = JsonHelper.JConvert<person,string>(obj); //to convert <obj> to string

var asObject = JsonHelper.JConvert<string,person>(asText); //to convert string to non-anonymous object
  

EDIT:2023

Since the construct & was a bit difficult to use & understand, here is another simple implementation to imitate Javascript JSON object withJSON.stringify() & JSON.parse(). It also have an extension function ToJson() to work with anonymous objects which uses System.Web.Script.Serialization from system.Web.Extensions.dll to serialize object tot json.

using System.Web.Script.Serialization;
using System.Runtime.Serialization.Json;

public static class JSON
{

    public static string ToJson(this object dataObject)
    {
        JavaScriptSerializer js = new JavaScriptSerializer();
        return js.Serialize(dataObject);        
    }
    
    public static T ToObject<T>(this string serializedData)
    {
        JavaScriptSerializer js = new JavaScriptSerializer();
        var deserializedResult = js.Deserialize<T>(serializedData);
        return deserializedResult;
    }
    
    public static String Stringify<T>(T t)
    {
        var inmemory = new MemoryStream();
        var ser = new DataContractJsonSerializer(typeof(T));
        ser.WriteObject(inmemory, t);
        return (Encoding.UTF8.GetString(inmemory.ToArray()));
    }
    
    public static T Parse<T>(string jsonString)
    {
        T deserializedUser = default(T);
        var ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
        var ser = new DataContractJsonSerializer(typeof(T));
        deserializedUser = (T)ser.ReadObject(ms);// as T;
        ms.Close();
        return deserializedUser;
    }
}

Now to use this one you simply have to write:

//to convert <obj> to string
var asText = JSON.Stringify(obj); 

//to convert string to non-anonymous object
var asObject = JSON.Parse<person>(asText); 

//for anonymous object
var ao = new {Name="Vinod", Surname = "Srivastav" };
var asText = ao.ToJson();


In .NET 6.0

With .NET 6.0 you just need to add

using System.Text.Json;
using System.Text.Json.Serialization;

Json.cs

public static class JSON
{
    public static string Stringify<T>(T t)
    {
        string jsonString = JsonSerializer.Serialize(t);
        return jsonString;
    }

    public static T Parse<T>(string jsonString)
    {
        T deserializedObject = JsonSerializer.Deserialize<T>(jsonString)!;
        return deserializedObject;
    }
}

And it still runs the above example: enter image description here

Vinod Srivastav
  • 3,644
  • 1
  • 27
  • 40
1
using System;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;

namespace OTL
{
    /// <summary>
    /// Before usage: Define your class, sample:
    /// [DataContract]
    ///public class MusicInfo
    ///{
    ///   [DataMember(Name="music_name")]
    ///   public string Name { get; set; }
    ///   [DataMember]
    ///   public string Artist{get; set;}
    ///}
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class OTLJSON<T> where T : class
    {
        /// <summary>
        /// Serializes an object to JSON
        /// Usage: string serialized = OTLJSON&lt;MusicInfo&gt;.Serialize(musicInfo);
        /// </summary>
        /// <param name="instance"></param>
        /// <returns></returns>
        public static string Serialize(T instance)
        {
            var serializer = new DataContractJsonSerializer(typeof(T));
            using (var stream = new MemoryStream())
            {
                serializer.WriteObject(stream, instance);
                return Encoding.Default.GetString(stream.ToArray());
            }
        }

        /// <summary>
        /// DeSerializes an object from JSON
        /// Usage:  MusicInfo deserialized = OTLJSON&lt;MusicInfo&gt;.Deserialize(json);
        /// </summary>
        /// <param name="json"></param>
        /// <returns></returns>
        public static T Deserialize(string json)
        {
            if (string.IsNullOrEmpty(json))
                throw new Exception("Json can't empty");
            else
                try
                {
                    using (var stream = new MemoryStream(Encoding.Default.GetBytes(json)))
                    {

                        var serializer = new DataContractJsonSerializer(typeof(T));
                        return serializer.ReadObject(stream) as T;
                    }
                }
                catch (Exception e)
                {
                    throw new Exception("Json can't convert to Object because it isn't correct format.");
                }
        }
    }
}
O Thạnh Ldt
  • 1,103
  • 10
  • 11
1

You can use DataContractJsonSerializer. See this link for more details.

TheBoyan
  • 6,802
  • 3
  • 45
  • 61
  • I tried that with this code { DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Song)); Song item = (Song)ser.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(song))); Debug.WriteLine(item.name); } and it gives me an error – Eli Revah Mar 05 '12 at 21:44
  • The error is Type 'Test1.Song' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types. – Eli Revah Mar 05 '12 at 21:44
  • 1
    @EliRevah - You need to define the data contract for the deserialization with the [DataContract] attribute for the class and add [DataMember] attribute for each member. – TheBoyan Mar 05 '12 at 21:56