Deserializing JSON using a custom deserializer with JSON.Net

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 am trying to deserialize it into IEnumerable classes that look like this:

 public class MobileSiteContentsContentSectionItem : ContentSectionItem { public string[] Urls { get; set; } } public abstract class ContentSectionItem { public string Culture { get; set; } } 

Is it possible?
I understand that I will probably need to use a custom JsonConverter for this, but cannot find any examples.

I started writing a conversion method using JObject.Parse , but not sure if this is the right / 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; } 
+6
source share
2 answers

You are on the right track. Here are the corrections you need to make:

  • You iterate over top-level children, expecting to get data that is actually at the same level below. You need to go to the value of the MobileSiteContents property and iterate over the children of this.
  • When you take Children() JObject , use an overload that allows them to be assigned to JProperty objects; which will facilitate the extraction of the necessary data.
  • Get culture from Name of JProperty element
  • To get urls , enter the Value of the JProperty element and use ToObject<string[]>() to convert it to an array of strings.

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 need a short code, you can reduce it to "single-line":

 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 
+6
source

I tried this with Json.Net and worked great.

 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; } 
+3
source

Source: https://habr.com/ru/post/956184/


All Articles