37

the json file's structure which I will deserialize looks like below;

{
    "id" : "1lad07",
    "text" : "test",
    "url" : "http:\/\/twitpic.com\/1lacuz",
    "width" : 220,
    "height" : 84,
    "size" : 8722,
    "type" : "png",
    "timestamp" : "Wed, 05 May 2010 16:11:48 +0000",
    "user" : {
        "id" : 12345,
        "screen_name" : "twitpicuser"
    }
}

I have created a class which has the filed names as properties for JavaScriptSerializer. The code which I will use to Deserialize the json is as follows;

            using (var reader = new StreamReader(twitpicResponse.GetResponseStream())) {


                var responseBody = reader.ReadToEnd();
                var deserializer = new JavaScriptSerializer();
                var results = deserializer.Deserialize<Response>(responseBody);

            }

My problem is how I can read the user field on json file. which is like below;

"user" : {
    "id" : 12345,
    "screen_name" : "twitpicuser"
}

it has sub properties and values. how can I name them on my Response class. my response class now look like this;

public class Response {

    public string id { get; set; }
    public string text { get; set; }
    public string url { get; set; }
    public string width { get; set; }
    public string height { get; set; }
    public string size { get; set; }
    public string type { get; set; }
    public string timestamp { get; set; }

}

what is the best case to do it?

Brian Rasmussen
  • 114,645
  • 34
  • 221
  • 317
tugberk
  • 57,477
  • 67
  • 243
  • 335

6 Answers6

39
  1. You need to create a class that holds the user values, just like the response class User.
  2. Add a property to the Response class 'user' with the type of the new class for the user values User.

    public class Response {
    
        public string id { get; set; }
        public string text { get; set; }
        public string url { get; set; }
        public string width { get; set; }
        public string height { get; set; }
        public string size { get; set; }
        public string type { get; set; }
        public string timestamp { get; set; }
        public User user { get; set; }
    
    }
    
    public class User {
    
        public int id { get; set; }
        public string screen_name { get; set; }
    
    }
    

In general you should make sure the property types of the json and your CLR classes match up. It seems that the structure that you're trying to deserialize contains multiple number values (most likely int). I'm not sure if the JavaScriptSerializer is able to deserialize numbers into string fields automatically, but you should try to match your CLR type as close to the actual data as possible anyway.

Colin K
  • 317
  • 1
  • 10
ntziolis
  • 10,091
  • 1
  • 34
  • 50
  • 1
    @ntziolis thanks for the reply. so id propertery inside the Reponse class should also be int I guess? – tugberk Mar 31 '11 at 15:33
  • 1
    @ntziolis: You'll need to add a parameterless public constructor, if I am not mistaken – skarmats Mar 31 '11 at 15:36
  • 3
    @skarmats No the `JavaScriptSerializer` and the corresponding resolver do not require you to explicitly define constructors, its much simpler than the `XmlSerializer`. – ntziolis Mar 31 '11 at 15:55
  • @ntziolis: I'll never get used to these differences :d Thanks for the info :) – skarmats Mar 31 '11 at 15:57
  • 4
    @skarmats Actually the `JavaScriptSerializer` is the step-sibling of the other serializers, its not used anywhere within the .NET infrastructure e.g. WCF (even when using json as format). It's merely provided as a fast and simple way to serialize/deserialize json outside of WCF and other framework scenarios. – ntziolis Mar 31 '11 at 16:05
21

Assuming you don't want to create another class, you can always let the deserializer give you a dictionary of key-value-pairs, like so:

string s = //{ "user" : {    "id" : 12345,    "screen_name" : "twitpicuser"}};
var serializer = new JavaScriptSerializer();
var result = serializer.DeserializeObject(s);

You'll get back something, where you can do:

var userId = int.Parse(result["user"]["id"]); // or (int)result["user"]["id"] depending on how the JSON is serialized.
// etc.

Look at result in the debugger to see, what's in there.

skarmats
  • 1,907
  • 15
  • 18
11

For .Net 4+:

string s = "{ \"user\" : {    \"id\" : 12345,    \"screen_name\" : \"twitpicuser\"}}";

var serializer = new JavaScriptSerializer();
dynamic usr = serializer.DeserializeObject(s);
var UserId = usr["user"]["id"];

For .Net 2/3.5: This code should work on JSON with 1 level

samplejson.aspx

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Globalization" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>
<%@ Import Namespace="System.Collections.Generic" %>
<%
string s = "{ \"id\" : 12345,    \"screen_name\" : \"twitpicuser\"}";
var serializer = new JavaScriptSerializer();
Dictionary<string, object> result = (serializer.DeserializeObject(s) as Dictionary<string, object>);
var UserId = result["id"];
 %>
 <%=UserId %>

And for a 2 level JSON:

sample2.aspx

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Globalization" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>
<%@ Import Namespace="System.Collections.Generic" %>
<%
string s = "{ \"user\" : {    \"id\" : 12345,    \"screen_name\" : \"twitpicuser\"}}";
var serializer = new JavaScriptSerializer();
Dictionary<string, object> result = (serializer.DeserializeObject(s) as Dictionary<string, object>);
Dictionary<string, object> usr = (result["user"] as Dictionary<string, object>);
var UserId = usr["id"];
 %>
 <%= UserId %>
Paco Zarate
  • 1,925
  • 1
  • 15
  • 13
3
  public class User : List<UserData>
    {

        public int id { get; set; }
        public string screen_name { get; set; }

    }


    string json = client.DownloadString(url);
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    var Data = serializer.Deserialize<List<UserData>>(json);
cracker
  • 4,900
  • 3
  • 23
  • 41
3

Create a sub-class User with an id field and screen_name field, like this:

public class User
{
    public string id { get; set; }
    public string screen_name { get; set; }
}

public class Response {

    public string id { get; set; }
    public string text { get; set; }
    public string url { get; set; }
    public string width { get; set; }
    public string height { get; set; }
    public string size { get; set; }
    public string type { get; set; }
    public string timestamp { get; set; }
    public User user { get; set; }
}
James Michael Hare
  • 37,767
  • 9
  • 73
  • 83
1
//Page load starts here

var json = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(new
{
    api_key = "my key",
    action = "categories",
    store_id = "my store"
});

var json2 = "{\"api_key\":\"my key\",\"action\":\"categories\",\"store_id\":\"my store\",\"user\" : {\"id\" : 12345,\"screen_name\" : \"twitpicuser\"}}";
var list = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<FooBar>(json);
var list2 = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<FooBar>(json2);

string a = list2.action;
var b = list2.user;
string c = b.screen_name;

//Page load ends here

public class FooBar
{
    public string api_key { get; set; }
    public string action { get; set; }
    public string store_id { get; set; }
    public User user { get; set; }
}

public class User
{
    public int id { get; set; }
    public string screen_name { get; set; }
}
Max
  • 1,810
  • 3
  • 26
  • 37