Json转换空字符串而不是null

我正在尝试序列化我的结构,以便没有获得值的字符串获得其默认值“”而不是null

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

我在Json字符串中的结果:

 "myProperty": null, 

我想要的是

 "myProperty": "", 

我也试过创建一个没有任何影响的转换器,因为某些原因,转换和写入JJ函数甚至都没有触发:

 [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(""); } } 

这不利于Json.Net如何将null反序列化为空字符串?

这应该工作:

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

虽然接受的答案指出我正确的方向,但它看起来很脆弱。 我不想担心解决JsonProperty对象列表并自己实现IValueResolver ,因为在Json.NET中可以使用完美的function工具(可以在基本reflection中构建各种优化和角落案例处理 -基于重新实现不会)。

我的解决方案执行最小的覆盖和解析器替换,以确保只有绝对需要更改的部分才会被实际更改:

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

好吧,我的解决方案非常简单,但不使用JSON.NETfunction,只需将backend字段添加到您的属性:

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

编辑:

在c#6.0中,属性初始化将可用:

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

@Kirill Shlenskiy的解决方案很棒,但它没有考虑NullValueHandling属性。

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

这是一个改进的版本,将负责它。 如果设置了NullValueHandling.Ignore且值为null,则将在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); } } }