c# json.net

c# - Cómo ignorar una propiedad en clase si es nulo, usando json.net



(10)

Estoy utilizando Json.NET para serializar una clase a JSON.

Tengo la clase como esta:

class Test1 { [JsonProperty("id")] public string ID { get; set; } [JsonProperty("label")] public string Label { get; set; } [JsonProperty("url")] public string URL { get; set; } [JsonProperty("item")] public List<Test2> Test2List { get; set; } }

Quiero agregar un JsonIgnore() a la propiedad Test2List solo cuando Test2List es null . Si no es nulo, quiero incluirlo en mi json.


Aquí hay una opción que es similar, pero proporciona otra opción:

public class DefaultJsonSerializer : JsonSerializerSettings { public DefaultJsonSerializer() { NullValueHandling = NullValueHandling.Ignore; } }

Entonces, lo uso así:

JsonConvert.SerializeObject(postObj, new DefaultJsonSerializer());

La diferencia aquí es que:

  • Reduce el código repetido mediante la JsonSerializerSettings instancias y la configuración de JsonSerializerSettings cada lugar donde se usa.
  • Ahorra tiempo en la configuración de cada propiedad de cada objeto para ser serializado.
  • Aún le da a otros desarrolladores flexibilidad en las opciones de serialización, en lugar de tener la propiedad específicamente especificada en un objeto reutilizable.
  • Mi caso de uso es que el código es una biblioteca de terceros y no quiero forzar las opciones de serialización en los desarrolladores que quieran reutilizar mis clases.
  • Los posibles inconvenientes son que es otro objeto que otros desarrolladores deberían conocer, o si su aplicación es pequeña y este enfoque no importaría para una única serialización.

Como se puede ver en este enlace en su sitio (http://james.newtonking.com/archive/2009/10/23/efficient-json-with-json-net-reducing-serialized-json-size.aspx) I admite el uso de [Predeterminado ()] para especificar valores predeterminados

Tomado del enlace.

public class Invoice { public string Company { get; set; } public decimal Amount { get; set; } // false is default value of bool public bool Paid { get; set; } // null is default value of nullable public DateTime? PaidDate { get; set; } // customize default values [DefaultValue(30)] public int FollowUpDays { get; set; } [DefaultValue("")] public string FollowUpEmailAddress { get; set; } } Invoice invoice = new Invoice { Company = "Acme Ltd.", Amount = 50.0m, Paid = false, FollowUpDays = 30, FollowUpEmailAddress = string.Empty, PaidDate = null }; string included = JsonConvert.SerializeObject(invoice, Formatting.Indented, new JsonSerializerSettings { }); // { // "Company": "Acme Ltd.", // "Amount": 50.0, // "Paid": false, // "PaidDate": null, // "FollowUpDays": 30, // "FollowUpEmailAddress": "" // } string ignored = JsonConvert.SerializeObject(invoice, Formatting.Indented, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }); // { // "Company": "Acme Ltd.", // "Amount": 50.0 // }


Para explicar ligeramente la muy útil respuesta de GlennG (traducir la sintaxis de C # a VB.Net no siempre es "obvio"), también puede decorar las propiedades de cada clase para administrar cómo se manejan los valores nulos. Si hace esto, no use el JsonSerializerSettings global de la sugerencia de GlennG, de lo contrario, anulará las decoraciones individuales. Esto es útil si desea que aparezca un elemento nulo en el JSON para que el consumidor no tenga que hacer ningún manejo especial. Si, por ejemplo, el consumidor necesita saber que una variedad de elementos opcionales está normalmente disponible, pero actualmente está vacío ... La decoración en la declaración de propiedad se ve así:

<JsonPropertyAttribute("MyProperty", DefaultValueHandling:=NullValueHandling.Include)> Public Property MyProperty As New List(of String)

Para aquellas propiedades que no desea que aparezcan en absoluto en el cambio de JSON : = NullValueHandling.Include en : = NullValueHandling.Ignore . Por cierto, he descubierto que puede decorar una propiedad para la serialización de XML y JSON muy bien (solo colóquelas una al lado de la otra). Esto me da la opción de llamar al serializador XML en dotnet o al serializador NewtonSoft a voluntad - tanto el trabajo lado a lado como el de mis clientes tienen la opción de trabajar con XML o JSON. ¡Esto está resbaladizo como un moco en un pomo de la puerta, ya que tengo clientes que requieren ambos!


Puede escribir: [JsonProperty("property_name",DefaultValueHandling = DefaultValueHandling.Ignore)]

También se encarga de no serializar propiedades con valores predeterminados (no solo nulos). Puede ser útil para enumeraciones por ejemplo.


Puede hacer esto para ignorar todos los valores nulos en un objeto que está serializando, y las propiedades nulas no aparecerán en el JSON

JsonSerializerSettings settings = new JsonSerializerSettings(); settings.NullValueHandling = NullValueHandling.Ignore; var myJson = JsonConvert.SerializeObject(myObject, settings);


Según James Newton King: si crea el serializador usted mismo en lugar de usar JavaScriptConvert, existe una propiedad NullValueHandling que puede configurar para ignorar.

Aquí hay una muestra:

JsonSerializer _jsonWriter = new JsonSerializer { NullValueHandling = NullValueHandling.Ignore };

Alternativamente, según lo sugerido por @amit

JsonConvert.SerializeObject(myObject, Newtonsoft.Json.Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });


Similar a la respuesta de @sirthomas, JSON.NET también respeta la propiedad DataMemberAttribute en DataMemberAttribute :

[DataMember(Name="property_name", EmitDefaultValue=false)]

Esto puede ser conveniente si ya está utilizando [DataContract] y [DataMember] en su tipo de modelo y no desea agregar atributos específicos de JSON.NET.



Una solución alternativa utilizando el atributo JsonProperty :

[JsonProperty(NullValueHandling=NullValueHandling.Ignore)] //or [JsonProperty("property_name", NullValueHandling=NullValueHandling.Ignore)]

Como se ve en este documento en línea .


var settings = new JsonSerializerSettings(); settings.ContractResolver = new CamelCasePropertyNamesContractResolver(); settings.NullValueHandling = NullValueHandling.Ignore; //you can add multiple settings and then use it var bodyAsJson = JsonConvert.SerializeObject(body, Formatting.Indented, settings);