Some deserialization workarounds (DateTime, Enum, Lists)
hardcodet opened this issue · 1 comments
Since the lib doesn't seem to be supported anymore, here's a few fixes and workarounds I added to get me going to deserialize some simple DTOs that were created through Json.net:
DateTime/DateTimeOffset parsing
The format used by Json.net caused me exceptions when trying to deserialize them. I replaced the DateTime/DateTimeOffset parsing as follows, which makes Json.net's IsoDateTimeConverter:
return DateTime.Parse(str, CultureInfo.CurrentCulture, DateTimeStyles.RoundtripKind);
Enum deserialization
In DeserializeObject, I added this (before the string evaluation):
if (type.GetTypeInfo().IsEnum)
{
if (value is double || value is int || value is long)
{
return Enum.ToObject(type, Convert.ToInt32(value.ToString()));
}
if (str != null)
{
return Enum.Parse(type, value.ToString());
}
}
List instantiation handling
That looked like a bug and crashed on me at runtime. The parser seems to try and create lists with a capacity parameter, but it appears that at runtime, the wrong constructor is invoked, me a TargetParameterCountException
. In DeserializeObject
, find the line where the lists are being created and just remove the constructor parameter like so:
Type innerType = ReflectionUtils.GetGenericListElementType(type);
list = (IList)(ConstructorCache[type] ?? ConstructorCache[typeof(List<>).MakeGenericType(innerType)])();
Then make sure the constructor cache works without parameters by adjusting this method and removing the distinction between arrays and other types:
internal virtual ReflectionUtils.ConstructorDelegate ContructorDelegateFactory(Type key)
{
return ReflectionUtils.GetContructor(key, EmptyTypes);
}
List instantiation handling:
Alternatively you can update ContructorDelegateFactory to check whether the type is an IList:
internal virtual ReflectionUtils.ConstructorDelegate ContructorDelegateFactory(Type key)
{
bool isArray = key.IsArray || typeof(IList).IsAssignableFrom(key);
return ReflectionUtils.GetContructor(key, isArray ? ArrayConstructorParameterTypes : EmptyTypes);
}