我正在尝试使用循环引用反序列化对象图,但没有运气,
Json.net 在序列化循环引用时效果很好:向对象添加$id并将对象替换为 $ref = *objectId,当我将相同的数据发送回 MVC 操作时,它不会正确反序列化 - 将$refs替换为空对象。
我使用 json.net 来序列化和反序列化,反序列化是在自定义 IValueProvider 中实现的 - https://json.codeplex.com/discussions/347099
我注意到在反序列化为匿名对象时
JsonConverter.Deserialize(json);
它不会处理循环引用。但是当使用泛型类型反序列化时
JsonConverter.Deserialize<EntityType>(json)
它将正确反序列化。
但是我在 GetValueProvider(ControllerContext controllerContext) 中找不到该类型。
任何帮助将不胜感激
编辑-在我当前的修复中,我将整个 json 作为字符串传递并使用
JsonConverter.Deserialize<EntityType>(json)
在控制器的操作中使用正确的类型,但这绝对不是使用 JSON + MVC4 的正确方法......我需要一种更好的方法来将其集成到 mvc 中,开始赏金
编辑 - 更多代码类型:
[JsonObject(IsReference = true)]
public class DynamicEntity : EntityWithID<Guid>
{
....
public virtual IList<DynamicEntity> ReferenceFields { get; set; }
}
要反序列化的 json 是 Json.net 的序列化方法的输出。
{"$id":"1","ReferenceFields":[{"$ref":"1"}],"Id":"9f9de7f3-865e-4511-aeac-a2ff01193b06"}
问题是与MVC的集成,因为json在服务器和客户端之间来回切换。我已经有 js 方法将其来回更改为相同的确切格式 - 经过测试,因为我现在像这样使用它:
public ActionResult EntitySaveOrUpdate(string entity)
{
var entityToSave = JsonConvert.DeserializeObject<DynamicEntity>(entity);
...
}
它工作得很好,但我需要与 MVC 更好地集成,而不是在我的所有操作中反序列化......
The challenge is dynamically typing at compile-time an un-typed languages (JSON).
由于JSON实际上是Java脚本对象表示法,而JavaScript是弱类型(或非类型),因此编译时解释器不确定"1"是指整数,双精度还是字符串类型。
请注意,当您使用 DynamicEntity 时,您不会遇到同样的问题,因为允许运行时以与 JavaScript 类似的方式进行解释。
这篇关于动态和静态匿名类型如何处理反序列化的文章有点旧,但仍然相关。他们的方法是使用
JsonConvert.DeserializeAnonymousType()
(一种动态方法)匿名返回。这篇文章扩展了Web Api的
DataContractJsonSerializer
,以及它如何限制匿名类型的选择。建议的答案是
"替换 MediaTypeFormatter 并插入我们自己的 JSON 序列化程序"
这相当于满足您有限需求的大量工作。
你会发现,除了使用 Linq 投影之外,你的 DynamicEntity 可能是你能找到的好方法。
您是否尝试编写 JsonConverter 并将其注册到 ValueProviderFactory 中。
JSONSerializer.Converters.Add(new DynamicEntityObjectConverter());
在转换器内部,您可以手动使用适用于循环参考的JsonConverter.Deserialize<EntityType>(json)
。