0

I am trying to figure out how to use a custom JsonConverter as an Attribute. The problem is that I cannot figure out how to get the FOO object within the converter.

Example

[Newtonsoft.Json.JsonConverter(typeof(FOOConverter))] public interface IFOO { ... } public class FOOConverter : Newtonsoft.Json.JsonConverter { public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var jobj = serializer.Deserialize<JObject>(reader); ... var foo = jobj.ToObject<IFOO>() // Calls the converter again? } } 

The .ToObject() will run the converter again and cause a stack overflow, which makes sense since it looks at the attribute, but how can I get the IFOO object then?

Edit: The WriteJson will be simular, but with JObject.FromObject(value);

The usage needs to be flexible, for ex: some properties might be encrypted/encrypted during serialization, other times, there may be property values that needs to be cached. To think of a few use cases.

1 Answer 1

2

JSON classes:

[KnownType(typeof(B))] public class A { public string Name { get; set; } } public class B : A { public string LastName { get; set; } } 

Converter code:

 public class KnownTypeConverter : JsonConverter { public override bool CanConvert(Type objectType) { return System.Attribute.GetCustomAttributes(objectType).Any(v => v is KnownTypeAttribute); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { // Load JObject from stream JObject jObject = JObject.Load(reader); // Create target object based on JObject System.Attribute[] attrs = System.Attribute.GetCustomAttributes(objectType); // Reflection. // Displaying output. foreach (System.Attribute attr in attrs) { if (attr is KnownTypeAttribute) { KnownTypeAttribute k = (KnownTypeAttribute) attr; var props = k.Type.GetProperties(); bool found = true; foreach (var f in jObject) { if (!props.Any(z => z.Name == f.Key)) { found = false; break; } } if (found) { var target = Activator.CreateInstance(k.Type); serializer.Populate(jObject.CreateReader(),target); return target; } } } throw new ObjectNotFoundException(); // Populate the object properties } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); } } 

Usage:

var ret = JsonConvert.DeserializeObject<A>(json, new KnownTypeConverter()); 
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the idea, the problem with Activator.CreateInstance is that within the WriteJson I also need the IFoo object which needs to be converted with JObject.FromObject. FromObject does the same as ToObject

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.