with tutorial net framework example asp c# asp.net-mvc-4 json.net asp.net-web-api

tutorial - web api rest c#



Prevenga $ id/$ ref al serializar objetos usando Web API y JSON.NET (4)

Parece que no puedo evitar que Web API / JSON.NET use Newtonsoft.Json.PreserveReferencesHandling.Objects al serializar objetos. En otras palabras, $ id / $ ref siempre se usan en los objetos serializados a pesar de utilizar las siguientes configuraciones:

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<JsonMediaTypeFormatter>().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; } }

¿Algunas ideas?


Coloque esto en Global.asax para configurar el manejo de referencias. PreserveReferencesHandling no debe ser ''Todo''

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


Aquí hay algunos javascript que estoy usando para manejar los objetos $ id / $ ref en el lado del cliente:

// 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 usa atributos de serialización en sus objetos (como DataContract), desde la documentación de JSON.Net en Atributos de serialización :

Además de usar los atributos incorporados de Json.NET, Json.NET también busca el [SerializableAttribute] [2] (si IgnoreSerializableAttribute en DefaultContractResolver se establece en falso) [DataContractAttribute] [3], [DataMemberAttribute] [4] y [NonSerializedAttribute] [5] ... al determinar cómo se serializará y deserializará JSON.

También dice esto:

Nota

Los atributos Json.NET toman presidencia sobre los atributos de serialización .NET estándar, por ejemplo, si ambos JsonPropertyAttribute y DataMemberAttribute están presentes en una propiedad y ambos personalizan el nombre, se usará el nombre de JsonPropertyAttribute.

Parece que la solución al problema es agregar [JsonObject(IsReference = false)] a su (s) objeto (s) como este:

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


[JsonIgnore] funcionó para mí. Dentro del modelo, incluye:

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

Lamentablemente, esto debe hacerse para cada caso donde sea necesario.