1

I don't want to use Newtonsoft's Json.Net library. I'm avoiding any third-party dependencies if I can help it in this project.

If I have JSON that looks like this:

{
    "has_more_items": false,
    "items_html": "...",
    "min_position": "1029839231781429248"
}

and I have a class that looks like this:

public class TwitterJson
{
    bool hasMore { get; set; } // has_more_items
    string rawText { get; set; } // items_html
    string nextKey { get; set; } // min_position
}

and I have a JsonObject containing the above JSON:

JsonObject theJson = JsonObject.Parse(result);

How do I deserialize the JsonObject into my class? I've been trying to find a clear example of this, and everything I've found uses Json.Net.

CXL
  • 1,094
  • 2
  • 15
  • 38
  • This is a valid question, but I'm curious why you need to avoid all third-party dependencies, even [the #1 most-downloaded package on NuGet.org](https://www.nuget.org/packages). – Matthew Aug 16 '18 at 00:33
  • 1
    [Windows.Data.Json](https://learn.microsoft.com/en-us/uwp/api/windows.data.json) is for parsing & formatting JSON, not (de)serializing. If you need a serializer see [How to Deserialize JSON data?](https://stackoverflow.com/q/18242429) and [Deserialize JSON with C#](https://stackoverflow.com/q/7895105) whose answers include several built-in options. – dbc Aug 16 '18 at 01:03

3 Answers3

3

I've been trying to find a clear example of this, and everything I've found uses Json.Net.

Because reinventing existing functionality is a waste of time especially when all the hard work has already been done for you.

If you insist on not using it then you will have to manually construct the object model based on the expected JSON.

For example, assuming publicly available properties

public class TwitterJson {
    public bool hasMore { get; set; } // has_more_items
    public string rawText { get; set; } // items_html
    public string nextKey { get; set; } // min_position
}

Then parsing the above to the desired object model

JsonObject theJson = JsonObject.Parse(result);
var model = new TwitterJson {
    hasMore = theJson.GetNamedBoolean("has_more_items"),
    rawText = theJson.GetNamedString("items_html"),
    nextKey = theJson.GetNamedString("min_position")
};
Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • That makes sense. I wasn't clear on whether or not `Windows.Data.Json` had a deserializer built in. – CXL Aug 16 '18 at 02:20
  • @ClairelyClaire No. Not to my knowledge. You could always write your own, but again it would be a lot of work with very little payoff. – Nkosi Aug 16 '18 at 02:35
0

You have to decorate your class with [DataContract] and [DataMember] attributes. Write the json into a memory stream and deserialize using DataContractJsonSerializer

Here is a more elaborated sample.

In addition to @Nkosi's answer below are some Comparisons between JSON.net and other alternatives:

Dimith
  • 379
  • 2
  • 12
  • Is `DataContractJsonSerializer` preferred? From what I'd read, it's a really inefficient implementation - is that still the case? – CXL Aug 16 '18 at 02:16
  • 1
    Preferred is json.net to be honest. But an alternative deserializer as you have asked would be `DataContractJsonSerializer`. I am not sure about the inefficiency though. I have seen some mention it as bit of a over-engineering. – Dimith Aug 16 '18 at 03:13
0

As mentioned by @Dimith, you need to decorate your class with [DataContract] and [DateMember], Please refer to below code which will convert your JSON into a given object.

 // Deserialize a JSON string to a given object.  
 public static T ReadToObject<T>(string json) where T: class, new()
 { 
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
    using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
    {
       return ser.ReadObject(stream) as T;
    }
 }

Class:

[DataContract]
    public class TwitterJson
    {
        [DataMember(Name = "has_more_items")]
        bool hasMore { get; set; } // has_more_items

        [DataMember(Name = "items_html")]
        string rawText { get; set; } // items_html

        [DataMember(Name = "min_position")]
        string nextKey { get; set; } // min_position
    }

Sample on how to use:

var result = "{\"has_more_items\": false, \"items_html\": \"...\",\"min_position\": \"1029839231781429248\"}";
var obj = ReadToObject<TwitterJson>(result);
Dishant
  • 1,545
  • 12
  • 29