Empêcher $ id / $ ref lors de la sérialisation d’objects à l’aide de l’API Web et de JSON.NET

Je n’arrive pas à empêcher Web API / JSON.NET d’utiliser Newtonsoft.Json.PreserveReferencesHandling.Objects lors de la sérialisation des objects. En d’autres termes, $ id / $ ref sont toujours utilisés dans les objects sérialisés malgré les parameters suivants:

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

Des idées?

Placez ceci dans le fichier Global.asax pour configurer la gestion des références. PreserveReferencesHandling ne doit pas être ‘All’

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

Voici quelques exemples de code javascript que j’utilise pour gérer les objects $ id / $ ref côté 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; } 

Si vous utilisez des atsortingbuts de sérialisation sur vos objects (tels que DataContract), consultez la documentation JSON.Net sur les atsortingbuts de sérialisation :

En plus d’utiliser les atsortingbuts Json.NET intégrés, Json.NET recherche également le [SerializableAtsortingbute] [2] (si IgnoreSerializableAtsortingbute sur DefaultContractResolver est défini sur false) [DataContractAtsortingbute] [3], [DataMemberAtsortingbute] [4] [NonSerializedAtsortingbute] [5] … lors de la détermination de la sérialisation et de la désérialisation de JSON.

Il dit aussi ceci:

Remarque

Les atsortingbuts Json.NET ont préséance sur les atsortingbuts de sérialisation standard .NET, par exemple, si JsonPropertyAtsortingbute et DataMemberAtsortingbute sont présents sur une propriété et qu’ils personnalisent le nom, le nom de JsonPropertyAtsortingbute sera utilisé.

Il semble que la solution au problème consiste à append [JsonObject(IsReference = false)] à votre ou vos objects comme ceci:

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

Mon application provoquait une erreur. J’ai débogué mon application asp.net jusqu’à ce qu’elle me donne la collection de modèles à l’origine de ce problème. vient de placer la balise [JsonIgnore] et cela a bien fonctionné.

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

Vous pouvez tester manuellement en affectant [JsonIgnore] à tous les ICollection dans Model pour découvrir la source du problème.

[JsonIgnore] travaillé pour moi. Dans le modèle, inclure:

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

Malheureusement, cela doit être fait pour chaque cas où cela est nécessaire.