多くのソースを掘り下げた後、私は自分の問題を解決しました。 コメントで提案されているすべてのソリューションは、文字列であるプロパティを含む複雑なオブジェクトを逆シリアル化する場合にのみ機能します。 この場合、はい、単に契約レゾルバを変更するだけです[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はTokenType
のJsonToken.StartObject
をリーダーに割り当てます。これにより、デシリアライズはproperty.ValueProvider.SetValue(target, value);
という特定のパスに従います。
ただし、オブジェクトが単なる文字列の場合、TokenType
はJsonToken.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);
}
}
http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_NullValueHandling.htm – garfbradaz
@garfbradazどのようにそれは彼の問題を解決できますか?その設定は、空の文字列を処理する方法ではなく、nullを処理する方法を示します。 – dman2306
@garfbradaz私は処理する必要があるnull値を持っていない、私はnullに変換する必要がある空の文字列があります。 – victor