I am using JsonConvert.DeserializeObject to deserialize an object, and the routine came across a date field that it did not know how to handle. Here is the error:
Error converting value \"2018-08-22\" to type
'System.Nullable`1[Microsoft.OData.Edm.Date]'. Path 'value[3].actualclosedate'
Microsoft.OData.Edm.Date is a struct object used by Microsoft to hold date-only data.
I am trying to build a custom converter for this type of field, but not getting it to work properly.
Here is my converter code:
public class EdmDateConverter : DateTimeConverterBase
{
public override bool CanConvert(Type objectType) { return objectType == typeof(global::Microsoft.OData.Edm.Date); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return (global::Microsoft.OData.Edm.Date)global::Microsoft.OData.Edm.Date.Parse(reader.ReadAsString());
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
string myDate = ((global::Microsoft.OData.Edm.Date)value).Year.ToString("D4");
myDate += "-";
myDate += ((global::Microsoft.OData.Edm.Date)value).Month.ToString("D2");
myDate += "-";
myDate += ((global::Microsoft.OData.Edm.Date)value).Day.ToString("D2");
writer.WriteValue(myDate);
}
}
And here is how I tried to link it into the global list of converters:
JsonConvert.DefaultSettings = () =>
{
var settings = new JsonSerializerSettings();
settings.Converters.Add(new EdmDateConverter());
//settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
return settings;
};
I am getting the same error as before, so either the converter is not getting added correctly or I don't have it written properly.
Can anyone give me some guidance on this issue?
Your error message indicates that the member type being deserialized is a Nullable<Microsoft.OData.Edm.Date>
, but your CanConvert
method is not accounting for the possibility that objectType
might be nullable.
You can fix this by modifying CanConvert
as follows:
public class EdmDateConverter : DateTimeConverterBase
{
public override bool CanConvert(Type objectType)
{
var type = Nullable.GetUnderlyingType(objectType) ?? objectType;
return type == typeof(global::Microsoft.OData.Edm.Date);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.SkipComments().TokenType == JsonToken.Null)
return null;
return (global::Microsoft.OData.Edm.Date)global::Microsoft.OData.Edm.Date.Parse(reader.ReadAsString());
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
string myDate = ((global::Microsoft.OData.Edm.Date)value).Year.ToString("D4");
myDate += "-";
myDate += ((global::Microsoft.OData.Edm.Date)value).Month.ToString("D2");
myDate += "-";
myDate += ((global::Microsoft.OData.Edm.Date)value).Day.ToString("D2");
writer.WriteValue(myDate);
}
}
public static partial class JsonExtensions
{
public static JsonReader SkipComments(this JsonReader reader)
{
while (reader.TokenType == JsonToken.Comment && reader.Read())
;
return reader;
}
}
Notes:
It is also necessary for check for a null
token in ReadJson()
. WriteJson()
, on the other hand, is never called for a null
value; instead Json.NET writes null
automatically.
There may be other issues with your code since your question does not include sample JSON, deserialization code or c# classes.
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