The following code will throw an exception:
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
}
This seems like strange behavior to me, can someone explain why this isn't a bug? Or perhaps suggest a workaround?
Instantiating a Regex
object in place of the null will of course stop this from throwing an exception.
The exception produced is:
Newtonsoft.Json.JsonSerializationException: Unexpected token when reading Regex. Path 'RegProp', line 1, position 15.
UPDATE
It appears that this issue was fixed in release 10.0.1 (March 2017).
This looks like a bug in Json.Net's RegexConverter
class. The ReadJson
method looks like this:
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.");
}
As you can see, it is not expecting or checking for a null token from the reader, so it is falling through to the line which throws a JsonSerializationException
.
You may want to report an issue linking back to this SO question.
As a workaround, you can derive your own converter from the RegexConverter
and add the check:
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);
}
}
When you deserialize, pass an instance of your custom converter to the DeserializeObject
method like this:
SimpleClassWithRegex obj =
JsonConvert.DeserializeObject<SimpleClassWithRegex>(json, new ImprovedRegexConverter());
Alterntatively, you can add a [JsonConverter]
attribute to your Regex
class members like this:
class SimpleClassWithRegex
{
[JsonConverter(typeof(ImprovedRegexConverter))]
public Regex RegProp { get; set; }
}
Fiddle: https://dotnetfiddle.net/BIqmd6
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With