2016-10-04 55 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); 
    } 
} 
相關問題