2016-10-04 52 views
0

我无法自动找到方法反序列化(服务器端)全部EmptyOrWhiteSpace字符串到null。 Json.Net默认情况下简单地赋值给对象属性,我需要通过字符串验证字符串是空白还是空白,然后将其设置为null。使用Json.Net将空字符串转换为null

我需要这样做反序列化,所以我不必记得验证来自客户端的每一个字符串。

我该如何在Json Net上覆盖这个?

+1

http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_NullValueHandling.htm – garfbradaz

+2

@garfbradaz请问该怎么解决他的问题?该设置告诉它如何处理null,而不是如何处理空白字符串。 – dman2306

+2

@garfbradaz我没有需要处理的空值,我有需要转换为空的空字符串。 – victor

回答

3

经过大量的源代码挖掘,我解决了我的问题。 原来,在注释中提出的所有解决方案只有在反序列化包含属性为字符串的复杂对象时才有效。 在这种情况下,是的,只需修改合同解析器[1]。

不过,我需要的是转换任何串的方式在反序列化空,修改合同的情况下,这种方式会失败在我的对象只是一个字符串,即

public void MyMethod(string jsonSomeInfo) 
{ 
    // At this point, jsonSomeInfo is "\"\"", 
    // an emmpty string. 

    var deserialized = new JsonSerializer().Deserialize(new StringReader(jsonSomeInfo), typeof(string)); 

    // deserialized = "", event if I used the modified contract resolver [1]. 
} 

当我们处理一个复杂的对象时,会发生什么?内部的JSON.NET将JsonToken.StartObjectTokenType分配给阅读器,这将导致反序列化遵循调用property.ValueProvider.SetValue(target, value);的某个路径。

但是,如果对象只是一个字符串,则TokenType将为JsonToken.String,路径将不同,并且值提供程序将永远不会被调用。

无论如何,我的解决方案是构建一个自定义转换器,将JsonReader转换为TokenType == JsonToken.String(代码如下)。

public class StringConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(string); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
      if (reader.Value == null) return null; 

      string text = reader.Value.ToString(); 

      if (string.IsNullOrWhiteSpace(text)) 
      { 
       return null; 
      } 

      return text; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException("Not needed because this converter cannot write json"); 
    } 

    public override bool CanWrite 
    { 
     get { return false; } 
    } 
} 

[1]贷记@圣拉斐尔Althaus的。

public class NullToEmptyStringResolver : DefaultContractResolver 
{ 
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) 
    { 
     return type.GetProperties() 
     .Select(p => { 
      var jp = base.CreateProperty(p, memberSerialization); 
      jp.ValueProvider = new EmptyToNullStringValueProvider(p); 
      return jp; 
     }).ToList(); 
    } 
} 

public class EmptyToNullStringValueProvider : IValueProvider 
{ 
    PropertyInfo _MemberInfo; 

    public EmptyToNullStringValueProvider(PropertyInfo memberInfo) 
    { 
     _MemberInfo = memberInfo; 
    } 

    public object GetValue(object target) 
    { 
     object result = _MemberInfo.GetValue(target); 

     if (_MemberInfo.PropertyType == typeof(string) && result != null && string.IsNullOrWhiteSpace(result.ToString())) 
     { 
      result = null; 
     } 

     return result; 
    } 

    public void SetValue(object target, object value) 
    { 
     if (_MemberInfo.PropertyType == typeof(string) && value != null && string.IsNullOrWhiteSpace(value.ToString())) 
     { 
      value = null; 
     } 

     _MemberInfo.SetValue(target, value); 
    } 
} 
相关问题