Impedisci $ id / $ ref durante la serializzazione di oggetti utilizzando Web API e JSON.NET

Non riesco a impedire a Web API / JSON.NET di utilizzare Newtonsoft.Json.PreserveReferencesHandling.Objects durante la serializzazione di oggetti. In altre parole, $ id / $ ref vengono sempre utilizzati negli oggetti serializzati nonostante utilizzino le seguenti impostazioni:

 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; } } 

Qualche idea?

Metti questo nel Global.asax per configurare la gestione dei riferimenti. PreserveReferencesHandling non dovrebbe essere ‘All’

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

Ecco alcuni javascript che sto usando per gestire gli oggetti $ id / $ ref sul lato client:

 // 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; } 

Se si utilizzano gli attributi di serializzazione sugli oggetti (come DataContract), dalla documentazione JSON.Net sugli attributi di serializzazione :

Oltre a utilizzare gli attributi Json.NET incorporati, Json.NET cerca anche [SerializableAttribute] [2] (se IgnoreSerializableAttribute su DefaultContractResolver è impostato su false) [DataContractAttribute] [3], [DataMemberAttribute] [4] e [NonSerializedAttribute] [5] … quando si determina come serializzare e deserializzare JSON.

Dice anche questo:

Nota

Gli attributi di Json.NET prendono presunzione rispetto agli attributi di serializzazione .NET standard, ad esempio se sia JsonPropertyAttribute che DataMemberAttribute sono presenti su una proprietà ed entrambi personalizzano il nome, verrà utilizzato il nome da JsonPropertyAttribute.

Sembra che la soluzione al problema sia aggiungere [JsonObject(IsReference = false)] al tuo object (i) in questo modo:

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

La mia applicazione stava causando l’errore ho debugato la mia applicazione asp.net fino a quando non mi ha dato la collezione di modello che causa questo problema. ho appena inserito il tag [JsonIgnore] e ha funzionato correttamente.

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

È ansible testare manualmente assegnando [JSONIgnore] a tutti ICollection in Model per scoprire l’origine del problema.

[JsonIgnore] lavorato per me. All’interno del modello, includere:

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

Sfortunatamente, questo deve essere fatto per ogni caso dove necessario.