System.FormatException: JSON 值不是受支持的 DateTimeOffset 格式
System.FormatException: The JSON value is not in a supported DateTimeOffset format
我正在阅读这篇关于 DateTime 相关格式支持的 MSDocs 文章
https://docs.microsoft.com/en-us/dotnet/standard/datetime/system-text-json-support#support-for-the-iso-8601-12019-format
我尝试着弄清楚默认配置没有按预期工作,或者我一定是遗漏了什么。
我的意思是:
DateTimeOffset.Parse("2021-03-17T12:03:14+0000");
工作正常。
但是
JsonSerializer.Deserialize<TestType>(@"{ ""CreationDate"": ""2021-03-17T12:03:14+0000"" }");
不会。
示例:
using System;
using System.Text.Json;
using System.Threading.Tasks;
namespace CSharpPlayground
{
public record TestType(DateTimeOffset CreationDate);
public static class Program
{
public static void Main()
{
var dto = DateTimeOffset.Parse("2021-03-17T12:03:14+0000");
Console.WriteLine(dto);
var testType = JsonSerializer.Deserialize<TestType>(@"{ ""CreationDate"": ""2021-03-17T12:03:14+0000"" }");
Console.WriteLine(testType.CreationDate);
}
}
}
抛出以下异常:
System.Text.Json.JsonException: The JSON value could not be converted to CSharpPlayground.TestType. Path: $.CreationDate | LineNumber: 0 | BytePositionInLine: 44.
---> System.FormatException: The JSON value is not in a supported DateTimeOffset format.
使用 System.Text.Json
实现自定义 JSON 行为通常使用自定义转换器来完成。不幸的是,没有多少开箱即用的不同日期格式,所以如果你需要反序列化一些不是默认 ISO 8601-1:2019
格式的东西,你需要自己动手。
幸运的是,这并不难:
using System.Text.Json;
using System.Text.Json.Serialization;
public class DateTimeOffsetConverterUsingDateTimeParse : JsonConverter<DateTimeOffset >
{
public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
Debug.Assert(typeToConvert == typeof(DateTimeOffset));
return DateTimeOffset .Parse(reader.GetString());
}
public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
}
}
这样,您的行为与使用 DateTimeOffset.Parse()
时相同。
你可以这样使用它
public record TestType(DateTimeOffset CreationDate);
public class Program
{
public static void Main(string[] args)
{
JsonSerializerOptions options = new JsonSerializerOptions();
options.Converters.Add(new DateTimeOffsetConverterUsingDateTimeParse());
var testType = JsonSerializer.Deserialize<TestType>(@"{ ""CreationDate"": ""2021-03-17T12:03:14+0000"" }",options);
Console.WriteLine(testType.CreationDate);
}
}
我正在阅读这篇关于 DateTime 相关格式支持的 MSDocs 文章 https://docs.microsoft.com/en-us/dotnet/standard/datetime/system-text-json-support#support-for-the-iso-8601-12019-format
我尝试着弄清楚默认配置没有按预期工作,或者我一定是遗漏了什么。
我的意思是:
DateTimeOffset.Parse("2021-03-17T12:03:14+0000");
工作正常。
但是
JsonSerializer.Deserialize<TestType>(@"{ ""CreationDate"": ""2021-03-17T12:03:14+0000"" }");
不会。
示例:
using System;
using System.Text.Json;
using System.Threading.Tasks;
namespace CSharpPlayground
{
public record TestType(DateTimeOffset CreationDate);
public static class Program
{
public static void Main()
{
var dto = DateTimeOffset.Parse("2021-03-17T12:03:14+0000");
Console.WriteLine(dto);
var testType = JsonSerializer.Deserialize<TestType>(@"{ ""CreationDate"": ""2021-03-17T12:03:14+0000"" }");
Console.WriteLine(testType.CreationDate);
}
}
}
抛出以下异常:
System.Text.Json.JsonException: The JSON value could not be converted to CSharpPlayground.TestType. Path: $.CreationDate | LineNumber: 0 | BytePositionInLine: 44.
---> System.FormatException: The JSON value is not in a supported DateTimeOffset format.
使用 System.Text.Json
实现自定义 JSON 行为通常使用自定义转换器来完成。不幸的是,没有多少开箱即用的不同日期格式,所以如果你需要反序列化一些不是默认 ISO 8601-1:2019
格式的东西,你需要自己动手。
幸运的是,这并不难:
using System.Text.Json;
using System.Text.Json.Serialization;
public class DateTimeOffsetConverterUsingDateTimeParse : JsonConverter<DateTimeOffset >
{
public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
Debug.Assert(typeToConvert == typeof(DateTimeOffset));
return DateTimeOffset .Parse(reader.GetString());
}
public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
}
}
这样,您的行为与使用 DateTimeOffset.Parse()
时相同。
你可以这样使用它
public record TestType(DateTimeOffset CreationDate);
public class Program
{
public static void Main(string[] args)
{
JsonSerializerOptions options = new JsonSerializerOptions();
options.Converters.Add(new DateTimeOffsetConverterUsingDateTimeParse());
var testType = JsonSerializer.Deserialize<TestType>(@"{ ""CreationDate"": ""2021-03-17T12:03:14+0000"" }",options);
Console.WriteLine(testType.CreationDate);
}
}