2016-10-04 42 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私は処理する必要があるnull値を持っていない、私はnullに変換する必要がある空の文字列があります。 – victor

答えて

3

多くのソースを掘り下げた後、私は自分の問題を解決しました。 コメントで提案されているすべてのソリューションは、文字列であるプロパティを含む複雑なオブジェクトを逆シリアル化する場合にのみ機能します。 この場合、はい、単に契約レゾルバを変更するだけです[1]。

しかし、私が必要とすることは、逆シリアル化時にnullに任意の文字列を変換するための方法だった、と私のオブジェクトは単なる文字列である。この方法はケースのために失敗する契約、すなわち、修正

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はTokenTypeJsonToken.StartObjectをリーダーに割り当てます。これにより、デシリアライズはproperty.ValueProvider.SetValue(target, value);という特定のパスに従います。

ただし、オブジェクトが単なる文字列の場合、TokenTypeJsonToken.Stringになり、パスは異なり、値プロバイダは決して呼び出されません。

私の解決策はTokenType == JsonToken.String(下のコード)を持つJsonReaderに変換するカスタムコンバータをビルドすることでした。

ソリューション

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); 
    } 
} 
関連する問題