Json.net在MVC4中使用循环引用反序列化json

Roy*_*del 7 c# asp.net-mvc serialization json.net asp.net-mvc-4

我试图用圆形引用反序列化对象图,没有运气,

序列化循环引用时Json.net运行良好:向对象添加$ id并用$ ref =*objectId替换对象,当我将相同的数据发送回MVC动作时,它将不会正确反序列化 - 将$ ref替换为空物.

我使用json.net来序列化和反序列化,反序列化是在自定义IValueProvider中实现的 - https://json.codeplex.com/discussions/347099

我注意到反序列化为匿名对象时

JsonConverter.Deserialize(json);
Run Code Online (Sandbox Code Playgroud)

它不会处理循环引用.但是在使用泛型类型进行反序列化时

JsonConverter.Deserialize<EntityType>(json) 
Run Code Online (Sandbox Code Playgroud)

它会正确反序列化.

但我找不到GetValueProvider中的类型(ControllerContext controllerContext)

任何帮助将不胜感激

编辑 - 在我目前的修复中,我将整个json作为字符串传递并使用

JsonConverter.Deserialize<EntityType>(json) 
Run Code Online (Sandbox Code Playgroud)

在控制器的动作中使用正确的类型,但这绝对不是使用json + mvc4的正确方法...我需要一种更好的方法将它集成到mvc中,开始赏金

编辑 - 更多代码类型:

[JsonObject(IsReference = true)]
public class DynamicEntity : EntityWithID<Guid>
{
    ....

    public virtual IList<DynamicEntity> ReferenceFields { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

要反序列化的json是Json.net的Serialize方法的输出.

{"$id":"1","ReferenceFields":[{"$ref":"1"}],"Id":"9f9de7f3-865e-4511-aeac-a2ff01193b06"}
Run Code Online (Sandbox Code Playgroud)

问题是与MVC的集成,因为json在服务器和客户端之间来回传递.我已经有了js方法来改变它来回到相同的格式 - 经过测试,我现在就像这样使用它:

public ActionResult EntitySaveOrUpdate(string entity)
    {
        var entityToSave = JsonConvert.DeserializeObject<DynamicEntity>(entity);
        ...
    }
Run Code Online (Sandbox Code Playgroud)

它工作正常,但我需要与MVC更好的集成,而不是在我的所有行动中反序列化...

Dav*_*ich 2

The challenge is dynamically typing at compile-time an un-typed languages (JSON).
Run Code Online (Sandbox Code Playgroud)

由于JSON实际上是Java 脚本对象表示法,而JavaScript是弱类型(或非类型),因此编译时解释器不确定“1”是否指的是intdoublestring类型。

请注意,当您使用DynamicEntity时,您不会遇到相同的问题,因为允许运行时以与JavaScript类似的方式进行解释。

  • 这篇关于动态和静态匿名类型如何处理反序列化的文章有点旧,但仍然相关。他们的方法是使用JsonConvert.DeserializeAnonymousType()一种动态方法来返回匿名。

  • 这篇文章扩展了Web ApiDataContractJsonSerializer内容,以及它如何限制您使用匿名类型的选项。建议的答案是

“替换 MediaTypeFormatter 并插入我们自己的 JSON 序列化器”

对于您有限的需求来说,这相当于大量的工作。

您会发现,除了使用Linq投影之外,您的DynamicEntity可能也是您会发现的最好方法。