使用json.net反序列化null regex属性

时间:2016-07-15 15:31:34

标签: c# json.net

以下代码将引发异常:

class SimpleClassWithRegex
{
    public Regex RegProp { get; set; }
}

[TestMethod]
public void RegexTest()
{
    string json = JsonConvert.SerializeObject(new SimpleClassWithRegex {RegProp = null}); 
    // json = {"RegProp":null}
    SimpleClassWithRegex obj = JsonConvert.DeserializeObject<SimpleClassWithRegex>(json); 
    //Above line throws a JsonSerializationException
}

这对我来说似乎很奇怪,有人可以解释为什么这不是一个错误吗?或者也许建议一个解决方法? 实例化Regex对象代替null当然会阻止它抛出异常。

产生的例外是:

Newtonsoft.Json.JsonSerializationException: Unexpected token when reading Regex. Path 'RegProp', line 1, position 15.

1 个答案:

答案 0 :(得分:3)

<强>更新

此问题似乎已于release 10.0.1(2017年3月)修复。

这看起来像是Json.Net的RegexConverter课程中的一个错误。 ReadJson方法如下所示:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    if (reader.TokenType == JsonToken.StartObject)
    {
        return ReadRegexObject(reader, serializer);
    }

    if (reader.TokenType == JsonToken.String)
    {
        return ReadRegexString(reader);
    }

    throw JsonSerializationException.Create(reader, "Unexpected token when reading Regex.");
}

正如您所看到的,它并不期望或检查读取器中的空令牌,因此它会落到抛出JsonSerializationException的行。

您可能希望report an issue链接回此SO问题。

作为解决方法,您可以从RegexConverter派生自己的转换器并添加支票:

public class ImprovedRegexConverter : RegexConverter
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
        {
            return null;
        }
        return base.ReadJson(reader, objectType, existingValue, serializer);
    }
}

反序列化时,将自定义转换器的实例传递给DeserializeObject方法,如下所示:

SimpleClassWithRegex obj = 
   JsonConvert.DeserializeObject<SimpleClassWithRegex>(json, new ImprovedRegexConverter());

另外,您可以向[JsonConverter]类成员添加Regex属性,如下所示:

class SimpleClassWithRegex
{
    [JsonConverter(typeof(ImprovedRegexConverter))]
    public Regex RegProp { get; set; }
}

小提琴:https://dotnetfiddle.net/BIqmd6