Reputation: 353
I try pass data below.
{
"Name": "Test",
"Date": "1631149200826"
}
My Class as below:
public class MyClass
{
public string Name { get; set; }
public int qty { get; set; }
public DateTime Date { get; set; }
}
Everything works fine when using .NET Framework.
But I got 2 error when using .NET Core 3.1 and Microsoft.AspNetCore.Mvc.NewtonsoftJson 3.1.8.
error1:Could not convert string to DateTime: 1631149200826. Path 'data.Date'
error2:The Item field is required.
I know it could solve error2 if I add some "ignore property" on my class.
But I wonder if there are other solution?
For example, add some options on controller?
services.AddControllers().AddNewtonsoftJson().AddJsonOptions();
Upvotes: 1
Views: 2974
Reputation: 131641
The standard date format in JSON is ISO8601, ie 2021-09-09T10:52:01+00:00
or 2021-09-09T10:52:01Z
. JSON.NET never parsed raw numbers as dates. As the docs explain:
The default format used by Json.NET is the ISO 8601 standard: "2012-03-19T07:22Z".
Prior to Json.NET 4.5 dates were written using the Microsoft format: "/Date(1198908717056)/". If you want to use this format, or you want to maintain compatibility with Microsoft JSON serializers or older versions of Json.NET, then change the DateFormatHandling setting to MicrosoftDateFormat.
The only way "1631149200826"
can be converted to a DateTime
is through a custom type converter.
The correct solution would be to switch to the standard date format.
If you want to keep using JSON.NET, you'll have to add the custom type converter that handled "1631149200826"
.
It's possible to create a custom DateTime converter for System.Text.Json as well. It's used in a similar way as JSON.NET custom converters, either through serializer options or though JSON attibutes.
In this case, the converter could be:
public class DateTimeMilliJsonConverter : JsonConverter<DateTime>
{
public override DateTime Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options)
{
long millis=long.Parse(reader.GetString());
return DateTime.UnixEpoch.AddMilliseconds(millis);
}
public override void Write(
Utf8JsonWriter writer,
DateTime dateTimeValue,
JsonSerializerOptions options)
{
long millis=(long)dateTimeValue.Subtract(DateTime.UnixEpoch).TotalMilliseconds;
writer.WriteStringValue(millis.ToString());
}
}
The converter can be applied to a property through the JsonConverter
attribute
public class MyClass
{
public string Name { get; set; }
public int qty { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTime Date { get; set; }
}
Upvotes: 1
Reputation: 9492
Supposing the Date
value is the number of milliseconds since the start of epoch, you could do something similar to this:
public class MyClass
{
public string Name { get; set; }
public int qty { get; set; }
[JsonProperty("Date")]
public long DateAsMilliseconds { get; set; }
[JsonIgnore]
public DateTime Date => TimeUtils.UnixMillisecondsToDateTime(DateAsMilliseconds);
}
public class TimeUtils
{
public static DateTime UnixMillisecondsToDateTime(double unixTimeStamp)
{
DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
dateTime = dateTime.AddMilliseconds(unixTimeStamp).ToLocalTime();
return dateTime;
}
}
Update: as suggested in the comments a far better idea would be to use the standard date format ISO8601.
Upvotes: 1