使用Web API和JSON.NET序列化对象时,防止$ id / $ ref

在序列化对象时,我似乎无法阻止Web API / JSON.NET使用Newtonsoft.Json.PreserveReferencesHandling.Objects 。 换句话说,尽管使用了以下设置,但$ id / $ ref总是在序列化对象中使用:

 public class MvcApplication : System.Web.HttpApplication { protected void Application_Start () { WebApiConfig.Register(GlobalConfiguration.Configuration); } } public static class WebApiConfig { public static void Register (HttpConfiguration config) { JsonMediaTypeFormatter jsonFormatter = config.Formatters.OfType().Single(); jsonFormatter.UseDataContractJsonSerializer = false; jsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented; jsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; jsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None; } } 

有任何想法吗?

将其放在Global.asax中以配置引用处理。 PreserveReferencesHandling不应该是’All’

 GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None; 

这里有一些javascript我用来处理客户端的$ id / $ ref对象:

 // function to return a JSON object form a JSON.NET serialized object with $id/$ref key-values // obj: the obj of interest. // parentObj: the top level object containing all child objects as serialized by JSON.NET. function getJsonNetObject(obj, parentObj) { // check if obj has $id key. var objId = obj["$id"]; if (typeof (objId) !== "undefined" && objId != null) { // $id key exists, so you have the actual object... return it return obj; } // $id did not exist, so check if $ref key exists. objId = obj["$ref"]; if (typeof (objId) !== "undefined" && objId != null) { // $ref exists, we need to get the actual object by searching the parent object for $id return getJsonNetObjectById(parentObj, objId); } // $id and $ref did not exist... return null return null; } // function to return a JSON object by $id // parentObj: the top level object containing all child objects as serialized by JSON.NET. // id: the $id value of interest function getJsonNetObjectById(parentObj, id) { // check if $id key exists. var objId = parentObj["$id"]; if (typeof (objId) !== "undefined" && objId != null && objId == id) { // $id key exists, and the id matches the id of interest, so you have the object... return it return parentObj; } for (var i in parentObj) { if (typeof (parentObj[i]) == "object" && parentObj[i] != null) { //going one step down in the object tree var result = getJsonNetObjectById(parentObj[i], id); if (result != null) { // return found object return result; } } } return null; } 

如果在对象上使用序列化属性(例如DataContract),请参阅序列化属性上的JSON.Net文档 :

除了使用内置的Json.NET属性外,Json.NET还会查找[SerializableAttribute] [2](如果DefaultContractResolver上的IgnoreSerializableAttribute设置为false)[DataContractAttribute] [3],[DataMemberAttribute] [4]和[NonSerializedAttribute] [5] …确定如何序列化和反序列化JSON。

它还说:

注意

Json.NET属性主要使用标准.NET序列化属性,例如,如果属性上存在JsonPropertyAttribute和DataMemberAttribute,并且都自定义名称,则将使用JsonPropertyAttribute中的名称。

似乎问题的解决方案是将[JsonObject(IsReference = false)]到您的对象中,如下所示:

 [DataContract(IsReference = true)] [JsonObject(IsReference = false)] public class MyObject { [DataMember] public int MyProperty { get; set; } } 

我的应用程序导致错误我调试我的asp.net应用程序,直到它给我模型的集合导致此问题。 刚放置[JsonIgnore]标签,它工作正常。

 [JsonIgnore] public virtual ICollection customer_details { get; set; } 

您可以通过将[JsonIgnore]分配给模型中的所有ICollection来手动测试,以发现问题的根源。

[JsonIgnore]为我工作。 在模型中,包括:

  [JsonIgnore] public virtual ICollection cell_order { get; set; } 

不幸的是,必须针对每种情况进行此操作。