6

Trying to deserialize this JSON:

    {
        "result":"success"
        "arguments": {
            "activeTorrentCount":22,
             "cumulative-stats": {
                  "downloadedBytes":1111,
             }
         }
     }

My class:

        private class DeserializationMain
        {
            public string result; //works

            public args arguments; //works, has deserialized activeTorrentCount
            public class args
            {
                public int activeTorrentCount;

                public current cumulative_stats; //doesn't work, equals null
                public class current
                {
                    public long downloadedBytes;
                }
            }
        }

I guess cumulative-stats doesn't get deserialized because it has cumulative_stats variable name in my class, how to deserialize that thing with a dash?

Lars
  • 1,699
  • 2
  • 22
  • 32
  • don't do that - most .net coding guidelines would have it as CumulativeStats. If it's a private member var then _cumulativeStats or m_cumulativeStats. – bryanmac Sep 21 '11 at 03:38
  • @bryanmac: I think that the JSON format is completely out of his control. – BalusC Sep 21 '11 at 03:41
  • I believe this depends on the features of the JSON serialization library you choose, but in some there are C# attributes that you can use to define a string of the mapped name that is different that the C# class name. – Jason Kleban Sep 21 '11 at 03:41
  • Yes, JSON responses are out of my control. Ofcourse I could tweak sources of Transmission torrent daemon and change response to cumulative_stats, but still I won't know answer to this problem. :-/ – Lars Sep 21 '11 at 03:45

2 Answers2

17

One alternative is to use the DataContractJsonSerializer instead of the JavascriptSerializer.

If you declare your classes like this:

        [DataContract]
        private class DeserializationMain
        {
            [DataMember(Name = "result")]
            public string result; //works
            [DataMember(Name = "arguments")]
            public args arguments; //works, has deserialized activeTorrentCount
            [DataContract]
            public class args
            {
                [DataMember(Name = "activeTorrentCount")]
                public int activeTorrentCount;

                [DataMember(Name = "cumulative-stats")]
                public current cumulative_stats; //doesn't work, equals null
                [DataContract]
                public class current
                {
                    [DataMember(Name = "downloadedBytes")]
                    public long downloadedBytes;
                }
            }
        }

You can deserialize it like this:

string json = "{\"result\":\"success\"   ,    \"arguments\": {  \"activeTorrentCount\":22,  \"cumulative-stats\": {   \"downloadedBytes\":1111      }       }     }";

DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(DeserializationMain));
MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
DeserializationMain result = serializer.ReadObject(ms) as DeserializationMain;

Console.WriteLine("Cumulative-stats.downloadedBytes: "+result.arguments.cumulative_stats.downloadedBytes); 

Will produce: Cumulative-stats.downloadedBytes: 1111

Icarus
  • 63,293
  • 14
  • 100
  • 115
4

I think most of the JSON serialization libraries support alias for properties, like custom attribute:

public class SomeClass {
    [JsonProperty("cumulative-stats")]
    public int CumulativeStats;
}

My suggestion is, keep your C# code with standard C# coding conventions and mapping to the property name in JSON.

Jeffrey Zhao
  • 4,923
  • 4
  • 30
  • 52
  • I'm not using any outside libraries, just the ones included in .NET framework, in this case "using System.Web.Script.Serialization;" and then: JavaScriptSerializer ser = new JavaScriptSerializer(); var des = ser.Deserialize(jsonString); And .NET doesn't has "JsonProperty". Anyways, without 3rd party lib I'm screwed? Meh. – Lars Sep 21 '11 at 04:10
  • 1
    @JeffreyZhao I tried the XmlElement suggestion, but this doesn't work. I have a json property called uu which I remap to SourceUrl but SourceUrl ends up null. – KingOfHypocrites Jun 08 '12 at 17:14
  • 1
    JavaScriptSerializer does not support this kind of mapping. – Jamie Aug 22 '16 at 19:24
  • As I can remember it uses `[DataMember]` attribute? – Jeffrey Zhao Aug 22 '16 at 20:48