My requirement is use JsonProperty during de-serializing and ignore JsonProperty during serialization. My model,
[JsonConverter(typeof(JsonPathConverter))]
public class FacebookFeed
{
public FacebookFeed()
{
Posts = new List<FacebookFeedPost>();
}
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("fan_count")]
public int Likes { get; set; }
[JsonProperty("feed.data")]
public List<FacebookFeedPost> Posts { get; set; }
}
public class FacebookFeedPost
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("message")]
public string Message { get; set; }
[JsonProperty("created_time")]
public DateTime Date { get; set; }
[JsonProperty("comments.summary.total_count")]
public int Comments { get; set; }
}
class IgnoreJsonPropertyContractResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
var list = base.CreateProperties(type, memberSerialization);
foreach (JsonProperty prop in list)
{
prop.PropertyName = prop.UnderlyingName;
}
return list;
}
}
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<JsonPropertyAttribute>().FirstOrDefault();
var jsonPath = (att != null ? att.PropertyName : 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)
{
var s = new JsonSerializer();
serializer.ContractResolver = new IgnoreJsonPropertyContractResolver();
var t = JToken.FromObject(value, s);
t.WriteTo(writer);
}
public override bool CanConvert(Type objectType)
{
// CanConvert is not called when [JsonConverter] attribute is used
return false;
}
public override bool CanWrite
{
get { return true; }
}
}
The problem is WriteJson. Note that I am using ASP.NET Web Api which internally serialize my objects that's why I am using JsonConverter. I dont wanna change global web api settings.
var t = JToken.FromObject(value, s);
at this line. No Stack trace. – Imran Qadir Baksh - BalochJToken.FromObject(value, s);
will call theWriteJson()
of a 2nd instance of the converter. One possibility to avoid this is shown inJSON.Net throws StackOverflowException when using [JsonConvert()]
. – dbc