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