Json.net deserialize json with circular reference in MVC4
I am trying with no luck to deserialize object graph with circular reference,
Json.net works well when serializing circular references : adding a $id to objects and replacing objects with $ref = *objectId, When i send the same data back to the MVC action, it won't deserialize correctly - replacing the $refs with empty objects.
I use json.net to both serialize and deserialize, deserializing is implemented in a custom IValueProvider - https://json.codeplex.com/discussions/347099
I noticed that when deserializing to an anonymous object
JsonConverter.Deserialize(json);
it will not deal with the circular references. but when deserializing using a generic type
JsonConverter.Deserialize<EntityType>(json)
it will deserialize correctly.
But i can't find the type in the GetValueProvider(ControllerContext controllerContext)
any help will be appreciated
Edit- In my current fix i pass the whole json as a string and use
JsonConverter.Deserialize<EntityType>(json)
with the right type in the controller's action, but that's definitely not the right way to work with json + mvc4... I need a better way to integrate it into mvc, started a bounty
Edit- More code The type :
[JsonObject(IsReference = true)]
public class DynamicEntity : EntityWithID<Guid>
{
....
public virtual IList<DynamicEntity> ReferenceFields { get; set; }
}
The json to deserialize is the output of the Serialize method of Json.net.
{"$id":"1","ReferenceFields":[{"$ref":"1"}],"Id":"9f9de7f3-865e-4511-aeac-a2ff01193b06"}
The issue is the integration with MVC because the json goes back and forth between the server and client. I already have js methods to change it back and forth to the same exact format - tested as i use it like this for now :
public ActionResult EntitySaveOrUpdate(string entity)
{
var entityToSave = JsonConvert.DeserializeObject<DynamicEntity>(entity);
...
}
And it works just fine, but i need a better integration with MVC and not deserialize in all of my actions...
The challenge is dynamically typing at compile-time an un-typed languages (JSON).
Since JSON is actually Java-Script Object Notation , and JavaScript is weakly typed (or un-typed), the compile-time interpreter isn't sure if "1" refers to an int , double , or string type.
Notice, you don't get the same problem when you use a DynamicEntity , because the Run-Time is allowed to interpret in similar manner to JavaScript .
This post of how dynamics and static-anonymous-types treat deserialization is a little old, but still relevant. Their approach is to use JsonConvert.DeserializeAnonymousType()
-- a dynamic method -- to return anonymous.
This post expands on Web Api 's DataContractJsonSerializer
, and how it limits your options with anonymous types. The answer suggested is to
"to replace the MediaTypeFormatter and plug in our own JSON serializer"
This amounts to a lot of work for your limited needs.
What you'll find is, short of using Linq projection, your DynamicEntity is probably as good approach as you will find.
Did you try to write JsonConverter and register it in your ValueProviderFactory.
JSONSerializer.Converters.Add(new DynamicEntityObjectConverter());
And inside your converter you can manualy use JsonConverter.Deserialize<EntityType>(json)
which works for circular reference.
上一篇: Rails回形针和SVG图像