Deserialize JSON with C#
Asked Answered
Q

10

245

I'm trying to deserialize a Facebook friend's Graph API call into a list of objects. The JSON object looks like:

{"data":[{"id":"518523721","name":"ftyft"},
         {"id":"527032438","name":"ftyftyf"},
         {"id":"527572047","name":"ftgft"},
         {"id":"531141884","name":"ftftft"},
         {"id":"532652067","name"...

List<EFacebook> facebooks = new JavaScriptSerializer().Deserialize<List<EFacebook>>(result);

It's not working, because the primitive object is invalid. How can I deserialize this?

Quarrel answered 25/10, 2011 at 20:0 Comment(4)
write a custom deserializer specifically to cater to such json ...Spyglass
or you can use an Dictionary<string,string>,check out: #7700472Hexaemeron
Your friend: json2csharp.comHaldas
Actually visual studios (as of 2013, or 2012 with web tools installed) has this exact functionality built in: Edit > Paste Special > Paste JSON As ClassesWaterscape
R
297

You need to create a structure like this:

public class Friends
{

    public List<FacebookFriend> data {get; set;}
}

public class FacebookFriend
{

    public string id {get; set;}
    public string name {get; set;}
}

Then you should be able to do:

Friends facebookFriends = new JavaScriptSerializer().Deserialize<Friends>(result);

The names of my classes are just an example. You should use proper names.

Adding a sample test:

string json =
    @"{""data"":[{""id"":""518523721"",""name"":""ftyft""}, {""id"":""527032438"",""name"":""ftyftyf""}, {""id"":""527572047"",""name"":""ftgft""}, {""id"":""531141884"",""name"":""ftftft""}]}";

Friends facebookFriends = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<Friends>(json);

foreach(var item in facebookFriends.data)
{
    Console.WriteLine("id: {0}, name: {1}", item.id, item.name);
}

Produces:

id: 518523721, name: ftyft
id: 527032438, name: ftyftyf
id: 527572047, name: ftgft
id: 531141884, name: ftftft
Ramachandra answered 25/10, 2011 at 20:4 Comment(5)
Yeh, its what I dont want to do, create a new object to hold the childs. I think Im gonna substring the json taking out the primitive object. Thank you.Quarrel
@Kevin Holditch thanks for the correction. I missed one important bit :)Ramachandra
What I don't like about this System.Web.Script.Serialization.JavaScriptSerializer() is that you always need a defined type T. In Java there is this org.java library (package) that remains all anonymous: "JSONObject["param"].JSONarray(5)" etcPrimipara
It is important to note that the setters for the id and name properties must be left public. If they are set to private or protected, the deserialization will execute without error but all data will be null.Birdwatcher
@sports, you can do that in C# by deserializing to a dynamic, but performance is much better if you deserialize to a known type.Ammeter
T
59

Sometimes I prefer dynamic objects:

public JsonResult GetJson()
{
  string res;
  WebClient client = new WebClient();

  // Download string
  string value = client.DownloadString("https://api.instagram.com/v1/users/000000000/media/recent/?client_id=clientId");

  // Write values
  res = value;
  dynamic dyn = JsonConvert.DeserializeObject(res);
  var lstInstagramObjects = new List<InstagramModel>();

  foreach(var obj in dyn.data)
  {
    lstInstagramObjects.Add(new InstagramModel()
    {
      Link = (obj.link != null) ? obj.link.ToString() : "",
      VideoUrl = (obj.videos != null) ? obj.videos.standard_resolution.url.ToString() : "",
      CommentsCount = int.Parse(obj.comments.count.ToString()),
      LikesCount = int.Parse(obj.likes.count.ToString()),
      CreatedTime = new System.DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds((double.Parse(obj.created_time.ToString()))),
      ImageUrl = (obj.images != null) ? obj.images.standard_resolution.url.ToString() : "",
      User = new InstagramModel.UserAccount()
             {
               username = obj.user.username,
               website = obj.user.website,
               profile_picture = obj.user.profile_picture,
               full_name = obj.user.full_name,
               bio = obj.user.bio,
               id = obj.user.id
             }
    });
  }

  return Json(lstInstagramObjects, JsonRequestBehavior.AllowGet);
}
Tiberius answered 25/2, 2014 at 6:22 Comment(4)
Once example of an instance where this was useful was when the object I was trying to deserialize into contained a property that was an interfaceSakai
An explanation would be in order.Kannada
Why would you prefer this over the accepted answer by @Icarus?Aimee
@Questioning, deserialising to strong types classes would neglect any properties that were not in your classes, while deserialising to dynamic objects would just return dynamic .Net object thats flexible to any new property created in the future without the requirement to update your classes. (as I said, sometimes not standard)Tiberius
M
51

A great way to automatically generate these classes for you is to copy your JSON output and throw it in here:

http://json2csharp.com/

It will provide you with a starting point to touch up your classes for deserialization.

Madewell answered 17/6, 2016 at 22:5 Comment(1)
Another way is in VisualStudio edit>paste special>paste json as classesDarelldarelle
S
33

Very easily we can parse JSON content with the help of dictionary and JavaScriptSerializer. Here is the sample code by which I parse JSON content from an ashx file.

var jss = new JavaScriptSerializer();
string json = new StreamReader(context.Request.InputStream).ReadToEnd();
Dictionary<string, string> sData = jss.Deserialize<Dictionary<string, string>>(json);
string _Name = sData["Name"].ToString();
string _Subject = sData["Subject"].ToString();
string _Email = sData["Email"].ToString();
string _Details = sData["Details"].ToString();
Shoshanashoshanna answered 29/1, 2013 at 6:59 Comment(2)
This solution is very useful if you do not have the time or need to create data contracts. Especially if you're interested in only a few attributes buried deep in the JSON structure. In that situation you may use a series of statements to navigate to what you need. Note: the type to deserialize might also be one of the following: Dictionary<string,object> or ArrayList (when a node has a repeating structure).Giotto
I get a run time exception with this: No parameterless constructor defined for type of 'System.String' on the Deserialize line of code.Cannae
A
25

Newtonsoft.JSON is a good solution for these kind of situations. Also Newtonsof.JSON is faster than others, such as JavaScriptSerializer, DataContractJsonSerializer.

In this sample, you can the following:

var jsonData = JObject.Parse("your JSON data here");

Then you can cast jsonData to JArray, and you can use a for loop to get data at each iteration.

Also, I want to add something:

for (int i = 0; (JArray)jsonData["data"].Count; i++)
{
    var data = jsonData[i - 1];
}

Working with dynamic object and using Newtonsoft serialize is a good choice.

Ardith answered 24/1, 2015 at 7:41 Comment(0)
D
16

I agree with Icarus (would have commented if I could), but instead of using a CustomObject class, I would use a Dictionary (in case Facebook adds something).

private class MyFacebookClass
{
    public IList<IDictionary<string, string>> data { get; set; }
}

or

private class MyFacebookClass
{
    public IList<IDictionary<string, object>> data { get; set; }
}
Drona answered 21/11, 2012 at 14:44 Comment(1)
Using dynamic works better in the new versions. public IList<IDictionary<string, dynmaic>> data { get; set; }Endopeptidase
C
13

Serialization:

// Convert an object to JSON string format
string jsonData = JsonConvert.SerializeObject(obj);

Response.Write(jsonData);

Deserialization::

To deserialize a dynamic object

  string json = @"{
      'Name': 'name',
      'Description': 'des'
    }";

var res = JsonConvert.DeserializeObject< dynamic>(json);

Response.Write(res.Name);
Castra answered 10/5, 2019 at 17:55 Comment(0)
D
10

If you're using .NET Core 3.0, you can use System.Text.Json (which is now built-in) to deserialize JSON.

The first step is to create classes to model the JSON. There are many tools which can help with this, and some of the answers here list them.

Some options are http://json2csharp.com, http://app.quicktype.io, or use Visual Studio (menu EditPaste SpecialPaste JSON as classes).

public class Person
{
    public string Id { get; set; }
    public string Name { get; set; }
}

public class Response
{
    public List<Person> Data { get; set; }
}

Then you can deserialize using:

var people = JsonSerializer.Deserialize<Response>(json);

If you need to add settings, such as camelCase handling, then pass serializer settings into the deserializer like this:

var options = new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
var person = JsonSerializer.Deserialize<Response>(json, options);
Dissertate answered 23/11, 2019 at 16:29 Comment(0)
S
3

You can use this extensions

public static class JsonExtensions
{
   public static T ToObject<T>(this string jsonText)
   {
       return JsonConvert.DeserializeObject<T>(jsonText);
   }

   public static string ToJson<T>(this T obj)
   {
       return JsonConvert.SerializeObject(obj);
   }
}
Syl answered 24/5, 2020 at 1:49 Comment(0)
L
1

Here is another site that will help you with all the code you need as long as you have a correctly formated JSON string available:

https://app.quicktype.io/

Lab answered 14/8, 2019 at 12:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.