http://stackoverflow.com/questions/43821065

CSharp · Console

/Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
					
public class Program
{
	public static void Main()
	{
		string json = @"
            {
              ""name"": ""Joe Schmoe"",
              ""fan_count"": 435,
              ""feed"": {
                ""data"": [
                  {
                    ""id"": ""55874325"",
                    ""message"": ""War does not determine who is right, only who is left."",
                    ""created_time"": ""2017-05-05T11:33:51Z"",
                    ""comments"": {
                      ""summary"": {
                        ""total_count"": 6
                      }
                    }
                  },
                  {
                    ""id"": ""55874582"",
                    ""message"": ""Those who live in glass houses should not throw stones."",
                    ""created_time"": ""2017-05-06T12:05:45Z"",
                    ""comments"": {
                      ""summary"": {
                        ""total_count"": 3
                      }
                    }
                  }
                ]
              }
            }";
		
		FacebookFeed feed = JsonConvert.DeserializeObject<FacebookFeed>(json);
		
		string json2 = JsonConvert.SerializeObject(feed, Formatting.Indented);
        Console.WriteLine(json2);
	}
}


public class JsonPathAttribute : Attribute
{
	public JsonPathAttribute(string jsonPath)
	{
		JsonPath = jsonPath;
	}
	
	public string JsonPath { get; set; }
}

public class JsonPathConverter : JsonConverter
{
	public override object ReadJson(JsonReader reader, Type objectType,
									object existingValue, JsonSerializer serializer)
	{
		var jo = JObject.Load(reader);
		object targetObj = Activator.CreateInstance(objectType);
		
		foreach (var prop in objectType.GetProperties().Where(p => p.CanRead && p.CanWrite))
		{
			var att = prop.GetCustomAttributes(true).OfType<JsonPathAttribute>().FirstOrDefault();
			var jsonPath = (att != null ? att.JsonPath : prop.Name);
			var token = jo.SelectToken(jsonPath);
			if (token != null && token.Type != JTokenType.Null)
			{
				var value = token.ToObject(prop.PropertyType, serializer);
				prop.SetValue(targetObj, value, null);
			}
		}
		
		return targetObj;
	}
	
	public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
	{
		// WriteJson is not called when CanWrite returns false
		throw new NotImplementedException();
	}
	
	public override bool CanConvert(Type objectType)
	{
		// CanConvert is not called when [JsonConverter] attribute is used
		return false;
	}
	
	public override bool CanWrite
	{
		get { return false; }
	}
}

[JsonConverter(typeof(JsonPathConverter))]
public class FacebookFeed
{
	public FacebookFeed()
	{
		Posts = new List<FacebookFeedPost>();
	}
	
	[JsonPath("name")]
	public string Name { get; set; }
	
	[JsonPath("fan_count")]
	public int Likes { get; set; }
	
	[JsonPath("feed.data")]
	public List<FacebookFeedPost> Posts { get; set; }
}

[JsonConverter(typeof(JsonPathConverter))]
public class FacebookFeedPost
{
	[JsonPath("id")]
	public string Id { get; set; }
	
	[JsonPath("message")]
	public string Message { get; set; }
	
	[JsonPath("created_time")]
	public DateTime Date { get; set; }
	
	[JsonPath("comments.summary.total_count")]
	public int Comments { get; set; }
}
;