Json Convertir cadena vacía en lugar de nula

Estoy intentando serializar mi estructura para que las cadenas que no obtuvieron un valor obtengan su valor predeterminado “” en lugar de nulo

[JsonProperty(PropertyName = "myProperty", DefaultValueHandling = DefaultValueHandling.Populate)] [DefaultValue("")] public string MyProperty{ get; set; } 

Mi resultado en la cadena Json:

 "myProperty": null, 

lo que quiero

 "myProperty": "", 

También intenté crear un convertidor sin ningún efecto, las funciones de conversión de Can y WriteJson no se disparan por alguna razón:

 [JsonProperty(PropertyName = "myProperty")] [JsonConverter(typeof(NullToEmptyStringConverter))] public string MyProperty{ get; set; } class NullToEmptyStringConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof(object[]); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException(); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { if (value == null) writer.WriteValue(""); } } 

Esto tampoco ayuda a Json.Net a deserializar el nulo como cadena vacía?

Esto debería funcionar:

 var settings = new JsonSerializerSettings() { ContractResolver= new NullToEmptyStringResolver() }; var str = JsonConvert.SerializeObject(yourObj, settings); 

 public class NullToEmptyStringResolver : Newtonsoft.Json.Serialization.DefaultContractResolver { protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) { return type.GetProperties() .Select(p=>{ var jp = base.CreateProperty(p, memberSerialization); jp.ValueProvider = new NullToEmptyStringValueProvider(p); return jp; }).ToList(); } } public class NullToEmptyStringValueProvider : IValueProvider { PropertyInfo _MemberInfo; public NullToEmptyStringValueProvider(PropertyInfo memberInfo) { _MemberInfo = memberInfo; } public object GetValue(object target) { object result = _MemberInfo.GetValue(target); if (_MemberInfo.PropertyType == typeof(string) && result == null) result = ""; return result; } public void SetValue(object target, object value) { _MemberInfo.SetValue(target, value); } } 

Bueno, mi solución es bastante simple, pero no usa las características de JSON.NET, solo agrega el campo de back-end a tu propiedad:

 public class Test { private string _myProperty = string.Empty; [JsonProperty(PropertyName = "myProperty")] public string MyProperty { get { return _myProperty; } set { _myProperty = value; } } } 

Editar:

En la inicialización de la propiedad c # 6.0 estará disponible:

 public class Test { [JsonProperty(PropertyName = "myProperty")] public string MyProperty { get; set;} = ""; } 

Si bien la respuesta aceptada me apuntó en la dirección correcta, parece bastante frágil. No quiero preocuparme por resolver la lista de objetos JsonProperty e implementar IValueResolver cuando hay herramientas perfectamente funcionales disponibles para hacerlo en Json.NET (que podría tener todo tipo de optimizaciones y manejo de casos en la esquina integrados que reflejen de manera básica). la reimplementación basada no lo hará).

Mi solución realiza una anulación mínima y una sustitución de resolución para garantizar que solo se modifiquen las partes que deben cambiar absolutamente :

 public sealed class SubstituteNullWithEmptyStringContractResolver : DefaultContractResolver { protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { JsonProperty property = base.CreateProperty(member, memberSerialization); if (property.PropertyType == typeof(string)) { // Wrap value provider supplied by Json.NET. property.ValueProvider = new NullToEmptyStringValueProvider(property.ValueProvider); } return property; } sealed class NullToEmptyStringValueProvider : IValueProvider { private readonly IValueProvider Provider; public NullToEmptyStringValueProvider(IValueProvider provider) { if (provider == null) throw new ArgumentNullException("provider"); Provider = provider; } public object GetValue(object target) { return Provider.GetValue(target) ?? ""; } public void SetValue(object target, object value) { Provider.SetValue(target, value); } } } 

La solución de @Kirill Shlenskiy es genial, pero no tiene en cuenta el atributo NullValueHandling .

 [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string Remark{ get; set; } 

Aquí hay una versión mejorada que se encargará de eso. Si se establece NullValueHandling.Ignore y el valor es nulo, se omitirá en la salida JSON.

 public sealed class SubstituteNullWithEmptyStringContractResolver : DefaultContractResolver { protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { JsonProperty property = base.CreateProperty(member, memberSerialization); if (property.PropertyType == typeof(string)) { // Wrap value provider supplied by Json.NET. property.ValueProvider = new NullToEmptyStringValueProvider(property.ValueProvider, property.NullValueHandling); } return property; } sealed class NullToEmptyStringValueProvider : IValueProvider { private readonly IValueProvider Provider; private readonly NullValueHandling? NullHandling; public NullToEmptyStringValueProvider(IValueProvider provider, NullValueHandling? nullValueHandling) { Provider = provider ?? throw new ArgumentNullException("provider"); NullHandling = nullValueHandling; } public object GetValue(object target) { if (NullHandling.HasValue && NullHandling.Value == NullValueHandling.Ignore && Provider.GetValue(target) == null ) { return null; } return Provider.GetValue(target) ?? ""; } public void SetValue(object target, object value) { Provider.SetValue(target, value); } } }