294

Is there an easy way to populate my C# object with the JSON object passed via AJAX?

This is the JSON object passed to a C# web method from the page using JSON.stringify:

{
    "user": {
        "name": "asdf",
        "teamname": "b",
        "email": "c",
        "players": ["1", "2"]
    }
}

The C# web method that receives the JSON object:

[WebMethod]
public static void SaveTeam(Object user)
{

}

The C# class that represents the object structure of JSON Object passed in to the web method

public class User
{
    public string name { get; set; }
    public string teamname { get; set; }
    public string email { get; set; }
    public Array players { get; set; }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
MHop
  • 3,053
  • 3
  • 17
  • 13

13 Answers13

266

Since we all love one liners code

Newtonsoft is faster than java script serializer. ... this one depends on the Newtonsoft NuGet package, which is popular and better than the default serializer.

if we have class then use below.

Mycustomclassname oMycustomclassname = Newtonsoft.Json.JsonConvert.DeserializeObject<Mycustomclassname>(jsonString);

no class then use dynamic

var oMycustomclassname = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(jsonString);
Duc Filan
  • 6,769
  • 3
  • 21
  • 26
MSTdev
  • 4,507
  • 2
  • 23
  • 40
  • This method made me see that, json object is casting to the `JToken` object in runtime and you can do a whole lot more with it – gurkan Jan 13 '23 at 09:11
240

A good way to use JSON in C# is with JSON.NET

Quick Starts & API Documentation from JSON.NET - Official site help you work with it.

An example of how to use it:

public class User
{
    public User(string json)
    {
        JObject jObject = JObject.Parse(json);
        JToken jUser = jObject["user"];
        name = (string) jUser["name"];
        teamname = (string) jUser["teamname"];
        email = (string) jUser["email"];
        players = jUser["players"].ToArray();
    }

    public string name { get; set; }
    public string teamname { get; set; }
    public string email { get; set; }
    public Array players { get; set; }
}

// Use
private void Run()
{
    string json = @"{""user"":{""name"":""asdf"",""teamname"":""b"",""email"":""c"",""players"":[""1"",""2""]}}";
    User user = new User(json);

    Console.WriteLine("Name : " + user.name);
    Console.WriteLine("Teamname : " + user.teamname);
    Console.WriteLine("Email : " + user.email);
    Console.WriteLine("Players:");

    foreach (var player in user.players)
        Console.WriteLine(player);
 }
Community
  • 1
  • 1
AndreyAkinshin
  • 18,603
  • 29
  • 96
  • 155
  • 7
    This works like a champ, but what if i have multiple items in my json and i want to make an object list? – Djeroen Feb 15 '16 at 17:41
  • @Djeroen: I see two ways for that. If items are not grouped try to find a way to split the string an repeat the process in a loop. If they are grouped make an object of objects – user1011138 Jun 23 '17 at 08:31
  • 1
    I prefer the one liners mentioned in other answers.. IMHO. – RayLoveless Oct 05 '17 at 20:04
  • Yes this is not a nice approach, the one below using DeserializeObject is much cleaner – Andrew Dec 03 '19 at 13:05
97

To keep your options open, if you're using .NET 3.5 or later, here is a wrapped up example you can use straight from the framework using Generics. As others have mentioned, if it's not just simple objects you should really use JSON.net.

public static string Serialize<T>(T obj)
{
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
    MemoryStream ms = new MemoryStream();
    serializer.WriteObject(ms, obj);
    string retVal = Encoding.UTF8.GetString(ms.ToArray());
    return retVal;
}

public static T Deserialize<T>(string json)
{
    T obj = Activator.CreateInstance<T>();
    MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
    obj = (T)serializer.ReadObject(ms);
    ms.Close();
    return obj;
}

You'll need:

using System.Runtime.Serialization;

using System.Runtime.Serialization.Json;
Nick Garvey
  • 2,980
  • 24
  • 31
Jammin
  • 3,050
  • 2
  • 23
  • 34
  • @ChristianPayne ha! Good point, yes these should be wrapped. With hindsight looking at this, just use JSON.NET! – Jammin Feb 17 '13 at 19:34
  • 2
    If DataContractJsonSerializer class is not visible, you have to add a reference to System.Runtime.Serialization by right clicking on the References in the solution, select the .NET tab and select System.Runtime.Serialization – DanKodi Sep 16 '13 at 15:08
  • 1
    One scenario where this one breaks. If your JSON object represents properties with single quotes, this function fails. e.g. it was not able to parse {'Subject': 'Emailing: Web User Activity Log11', 'EmbedAsImage': true} but it was able to parse {"Subject": "Emailing: Web User Activity Log11", "EmbedAsImage": true} – dreamerkumar Nov 12 '13 at 18:10
  • Plus I needed to decorate my simple class with DataContract and DataMember attributes. It won't parse without it. – dreamerkumar Nov 12 '13 at 18:11
  • Unlike Vishal, a POCO class worked perfectly for me... +1 as this avoids a dependency on JSON.NET. – Dunc Dec 12 '13 at 11:19
54

Given your code sample, you shouldn't need to do anything else.

If you pass that JSON string to your web method, it will automatically parse the JSON string and create a populated User object as the parameter for your SaveTeam method.

Generally though, you can use the JavascriptSerializer class as below, or for more flexibility, use any of the various Json frameworks out there (Jayrock JSON is a good one) for easy JSON manipulation.

 JavaScriptSerializer jss= new JavaScriptSerializer();
 User user = jss.Deserialize<User>(jsonResponse); 
womp
  • 115,835
  • 26
  • 236
  • 269
  • 1
    I think you must use an ienumerable type (so in this example List) – Dragouf Sep 19 '11 at 15:18
  • How can we deserialize if it contains sub view model – SrinivasNaidu Apr 29 '14 at 08:22
  • 1
    For those looking you need to reference the `System.Web.Extensions` assembly and add a `using System.Web.Script.Serialization` to get at the `JavaScriptSerializer`, but once you do, this seems like the cleanest way to deserialize yours `json` strings into c# concrete classes. – Serj Sagan Apr 29 '16 at 17:52
  • Anyone stumbling on this answer now should be cognizant of this general advice from MS's own documentation on `JavaScriptSerializer`: _For .NET Framework 4.7.2 and later versions, the APIs in the `System.Text.Json` namespace should be used for serialization and deserialization. For earlier versions of .NET Framework, use `Newtonsoft.Json`._ – Tawab Wakil May 11 '23 at 19:35
48

Another really simple solution is using the library Newtonsoft.Json:

User user = JsonConvert.DeserializeObject<User>(jsonString);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Daniel
  • 2,780
  • 23
  • 21
  • 1
    but if the User object has another JSon data in the property, this will fails... – gumuruh May 11 '20 at 08:07
  • @gumuruh I guess i did not understand your statement. If you have a complex object witch properties are another complex objects, they will also be converted, as long your Json String have the data correctly. – Daniel May 12 '20 at 15:54
36

The following 2 examples make use of either

  1. JavaScriptSerializer under System.Web.Script.Serialization Or
  2. Json.Decode under System.Web.Helpers

Example 1: using System.Web.Script.Serialization

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Script.Serialization;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void Test()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            dynamic jsonObject = serializer.Deserialize<dynamic>(json);

            dynamic x = jsonObject["user"]; // result is Dictionary<string,object> user with fields name, teamname, email and players with their values
            x = jsonObject["user"]["name"]; // result is asdf
            x = jsonObject["user"]["players"]; // result is object[] players with its values
        }
    }
}

Usage: JSON object to Custom C# object

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Script.Serialization;
using System.Linq;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void TestJavaScriptSerializer()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            User user = new User(json);
            Console.WriteLine("Name : " + user.name);
            Console.WriteLine("Teamname : " + user.teamname);
            Console.WriteLine("Email : " + user.email);
            Console.WriteLine("Players:");
            foreach (var player in user.players)
                Console.WriteLine(player);
        }
    }

    public class User {
        public User(string json) {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            var jsonObject = serializer.Deserialize<dynamic>(json);
            name = (string)jsonObject["user"]["name"];
            teamname = (string)jsonObject["user"]["teamname"];
            email = (string)jsonObject["user"]["email"];
            players = jsonObject["user"]["players"];
        }

        public string name { get; set; }
        public string teamname { get; set; }
        public string email { get; set; }
        public Array players { get; set; }
    }
}

Example 2: using System.Web.Helpers

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Helpers;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void TestJsonDecode()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            dynamic jsonObject = Json.Decode(json);

            dynamic x = jsonObject.user; // result is dynamic json object user with fields name, teamname, email and players with their values
            x = jsonObject.user.name; // result is asdf
            x = jsonObject.user.players; // result is dynamic json array players with its values
        }
    }
}

Usage: JSON object to Custom C# object

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Helpers;
using System.Linq;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void TestJsonDecode()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            User user = new User(json);
            Console.WriteLine("Name : " + user.name);
            Console.WriteLine("Teamname : " + user.teamname);
            Console.WriteLine("Email : " + user.email);
            Console.WriteLine("Players:");
            foreach (var player in user.players)
                Console.WriteLine(player);
        }
    }

    public class User {
        public User(string json) {
            var jsonObject = Json.Decode(json);
            name = (string)jsonObject.user.name;
            teamname = (string)jsonObject.user.teamname;
            email = (string)jsonObject.user.email;
            players = (DynamicJsonArray) jsonObject.user.players;
        }

        public string name { get; set; }
        public string teamname { get; set; }
        public string email { get; set; }
        public Array players { get; set; }
    }
}

This code requires adding System.Web.Helpers namespace found in,

%ProgramFiles%\Microsoft ASP.NET\ASP.NET Web Pages{VERSION}\Assemblies\System.Web.Helpers.dll

Or

%ProgramFiles(x86)%\Microsoft ASP.NET\ASP.NET Web Pages{VERSION}\Assemblies\System.Web.Helpers.dll

Hope this helps!

  • This is a very good answer, but the tricky thing is that with `dynamic` types, you don't get any true type checking. For example, if your JSON contains `"Name" : "Ahmed"` and you mistype "Name" in your C# code, it's a runtime error (bleh). – Jess Jun 05 '14 at 13:11
  • Thanks! Please update the answer to state that for Example 1, you need to reference System.Web.Extensions.dll – Valamas Oct 19 '14 at 23:45
  • 1
    super great answer, the dynamic typing works w/ json.net v6.0.6 too! – stackuser83 Nov 20 '14 at 21:55
8
public static class Utilities
{
    public static T Deserialize<T>(string jsonString)
    {
        using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
        {    
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
            return (T)serializer.ReadObject(ms);
        }
    }
}

More information go to following link http://ishareidea.blogspot.in/2012/05/json-conversion.html

About DataContractJsonSerializer Class you can read here.

NoWar
  • 36,338
  • 80
  • 323
  • 498
7

Using JavaScriptSerializer() is less strict than the generic solution offered :

public static T Deserialize<T>(string json)

That might come handy when passing json to the server that does not match exactly the Object definition you are trying to convert to.

shA.t
  • 16,580
  • 5
  • 54
  • 111
Ioannis Suarez
  • 587
  • 6
  • 5
2

Performance-wise, I found the ServiceStack's serializer a bit faster than then others. It's JsonSerializer class in ServiceStack.Text namespace.

https://github.com/ServiceStack/ServiceStack.Text

ServiceStack is available through NuGet package: https://www.nuget.org/packages/ServiceStack/

akardon
  • 43,164
  • 4
  • 34
  • 42
1

The JSON C# class generator on codeplex generates classes which work well with NewtonSoftJS.

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
1

JSON.Net is your best bet but, depending on the shape of the objects and whether there are circular dependencies, you could use JavaScriptSerializer or DataContractSerializer.

Sky Sanders
  • 36,396
  • 8
  • 69
  • 90
1

JavaScript Serializer: requires using System.Web.Script.Serialization;

public class JavaScriptSerializerDeSerializer<T>
{
    private readonly JavaScriptSerializer serializer;

    public JavaScriptSerializerDeSerializer()
    {
        this.serializer = new JavaScriptSerializer();
    }

    public string Serialize(T t)
    {
        return this.serializer.Serialize(t);
    }

    public T Deseralize(string stringObject)
    {
        return this.serializer.Deserialize<T>(stringObject);
    }
}

Data Contract Serializer: requires using System.Runtime.Serialization.Json; - The generic type T should be serializable more on Data Contract

public class JsonSerializerDeserializer<T> where T : class
{
    private readonly DataContractJsonSerializer jsonSerializer;

    public JsonSerializerDeserializer()
    {
        this.jsonSerializer = new DataContractJsonSerializer(typeof(T));
    }

    public string Serialize(T t)
    {
        using (var memoryStream = new MemoryStream())
        {
            this.jsonSerializer.WriteObject(memoryStream, t);
            memoryStream.Position = 0;
            using (var sr = new StreamReader(memoryStream))
            {
                return sr.ReadToEnd();
            }
        }
    }

    public T Deserialize(string objectString)
    {
        using (var ms = new MemoryStream(System.Text.ASCIIEncoding.ASCII.GetBytes((objectString))))
        {
            return (T)this.jsonSerializer.ReadObject(ms);
        }
    }
}
Biniam Eyakem
  • 545
  • 5
  • 18
0

Rather than sending as just an object, create a public class of properties that is accessible and send the data to the Webmethod.

[WebMethod]
public static void SaveTeam(useSomeClassHere user)
{
}

Use the same parameters names in the Ajax call to send the data.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131