2016-10-04 8 views
0

(서버 쪽)으로 역 직렬화하는 방법을 찾는 데 어려움이 있습니다. null에 문자열을 모두 EmptyOrWhiteSpace으로 지정합니다. 기본적으로 Json.Net은 단순히 객체 속성에 값을 할당하기 때문에 문자열이 공백인지 공백인지를 문자열로 확인한 다음 null로 설정해야합니다.빈 문자열을 null로 변환합니다.

deserialization 할 때이 작업이 필요하므로 클라이언트에서 오는 모든 단일 문자열을 확인하는 것을 기억할 필요가 없습니다.

어떻게 이것을 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

소스 파기가 많이 발생한 후 문제가 해결되었습니다. 문자열에있는 속성이 포함 된 복잡한 개체를 deserialize하는 경우에만 주석에 제안 된 모든 솔루션이 작동합니다. 이 경우, 계약 확인자를 수정하면됩니다. [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); 
    } 
} 
관련 문제