I have JSON that looks like this:
{
  "MobileSiteContents": {
    "au/en": [
      "http://www.url1.com",
      "http://www.url2.com",
    ],
    "cn/zh": [
      "http://www.url2643.com",
    ]
  }
}
I'm trying to deserialize it into an IEnumerable of classes that look like this:
public class MobileSiteContentsContentSectionItem : ContentSectionItem
{
    public string[] Urls { get; set; }
}
public abstract class ContentSectionItem
{
    public string Culture { get; set; }
}
Is that possible?
I realise I will probably need to use a Custom JsonConverter for this, but can't find any examples.
I started writing a method to convert using JObject.Parse but not sure if this is the correct / most efficient route to go down:
public IEnumerable<MobileSiteContentsContentSectionItem> Parse(string json)
{
    var jobject = JObject.Parse(json);
    var result = new List<MobileSiteContentsContentSectionItem>();
    foreach (var item in jobject.Children())
    {
        var culture = item.Path;
        string[] urls = new[] { "" }; //= this is the part I'm having troble with here...
        result.Add(new MobileSiteContentsContentSectionItem { Culture = culture, Urls = urls });
    }
    return result;
}
                A common way to deserialize JSON is to first create a class with properties and fields that represent one or more of the JSON properties. Then, to deserialize from a string or a file, call the JsonSerializer. Deserialize method.
JSON is a format that encodes objects in a string. Serialization means to convert an object into that string, and deserialization is its inverse operation (convert string -> object).
You're on the right track. Here are the corrections you need to make:
MobileSiteContents property and iterate over the children of that.Children() of the JObject, use the overload that lets you cast them to JProperty objects; that will make it much easier to extract the data you want.culture from the Name of the JProperty itemurls, get the Value of the JProperty item and use ToObject<string[]>() to convert it to a string array.Here is the corrected code:
public IEnumerable<MobileSiteContentsContentSectionItem> Parse(string json)
{
    var jObject = JObject.Parse(json);
    var result = new List<MobileSiteContentsContentSectionItem>();
    foreach (var item in jObject["MobileSiteContents"].Children<JProperty>())
    {
        var culture = item.Name;
        string[] urls = item.Value.ToObject<string[]>();
        result.Add(new MobileSiteContentsContentSectionItem { Culture = culture, Urls = urls });
    }
    return result;
}
If you like terse code, you can reduce this to a "one-liner":
public IEnumerable<MobileSiteContentsContentSectionItem> Parse(string json)
{
    return JObject.Parse(json)["MobileSiteContents"]
        .Children<JProperty>()
        .Select(prop => new MobileSiteContentsContentSectionItem
        {
            Culture = prop.Name,
            Urls = prop.Value.ToObject<string[]>()
        })
        .ToList();
}
Demo:
class Program
{
    static void Main(string[] args)
    {
        string json = @"
        {
            ""MobileSiteContents"": {
                ""au/en"": [
                    ""http://www.url1.com"",
                    ""http://www.url2.com"",
                ],
                ""cn/zh"": [
                    ""http://www.url2643.com"",
                ]
            }
        }";
        foreach (MobileSiteContentsContentSectionItem item in Parse(json))
        {
            Console.WriteLine(item.Culture);
            foreach (string url in item.Urls)
            {
                Console.WriteLine("  " + url);
            }
        }
    }
    public static IEnumerable<MobileSiteContentsContentSectionItem> Parse(string json)
    {
        return JObject.Parse(json)["MobileSiteContents"]
            .Children<JProperty>()
            .Select(prop => new MobileSiteContentsContentSectionItem()
            {
                Culture = prop.Name,
                Urls = prop.Value.ToObject<string[]>()
            })
            .ToList();
    }
    public class MobileSiteContentsContentSectionItem : ContentSectionItem
    {
        public string[] Urls { get; set; }
    }
    public abstract class ContentSectionItem
    {
        public string Culture { get; set; }
    }
}
Output:
au/en
  http://www.url1.com
  http://www.url2.com
cn/zh
  http://www.url2643.com
                        I tried this using Json.Net and works fine.
public IEnumerable<MobileSiteContentsContentSectionItem> Parse(string json)
{
     dynamic jobject = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
     var result = new List<MobileSiteContentsContentSectionItem>();
     var urls = new List<string>();
     foreach (var item in jobject.MobileSiteContents)
     {
         var culture = item.Name;
         foreach(var url in item.Value)
            urls.Add(url.Value);
         result.Add(new MobileSiteContentsContentSectionItem { Culture = culture, Urls = urls.ToArray() });
     }
     return result;
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With