You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在NativeAOT C#应用中用源生成指定DateTime格式解析JSON

解决.NET 8 NativeAOT应用中DateTime反序列化失败问题

问题原因

System.Text.Json默认仅支持ISO 8601格式的日期字符串(如2024-05-30T09:17:26.003Z),而你传入的05/30/2024 09:17:26.003属于MM/dd/yyyy HH:mm:ss.fff格式,因此反序列化时抛出格式不匹配的异常。

方案1:通过JsonSourceGenerationOptions全局配置日期格式

直接在源生成配置中指定目标日期格式,让序列化上下文自动适配该格式,无需修改实体类:

[JsonSourceGenerationOptions(
    WriteIndented = true,
    DateFormatString = "MM/dd/yyyy HH:mm:ss.fff",
    DateTimeStyles = DateTimeStyles.AllowWhiteSpaces // 允许字符串中存在额外空白字符
)]
[JsonSerializable(typeof(StateRequest))]
[JsonSerializable(typeof(bool))]
[JsonSerializable(typeof(string))]
[JsonSerializable(typeof(DateTime))]
public partial class StateRequestJsonContext : JsonSerializerContext
{
}

此方案适合所有DateTime类型属性都使用同一格式的场景,配置简单且全局生效。

方案2:自定义DateTime转换器(支持多格式或特定属性)

如果需要支持多种日期格式,或仅针对特定属性处理,可自定义转换器并集成到源生成上下文:

步骤1:实现自定义转换器

using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;

public class CustomDateTimeConverter : JsonConverter<DateTime>
{
    // 可根据需求添加更多支持的日期格式
    private static readonly string[] _supportedFormats = 
    {
        "MM/dd/yyyy HH:mm:ss.fff",
        "MM/dd/yyyy HH:mm:ss"
    };

    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType != JsonTokenType.String)
        {
            throw new JsonException("预期字符串类型的日期值");
        }

        var dateStr = reader.GetString();
        if (DateTime.TryParseExact(dateStr, _supportedFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTime))
        {
            return dateTime;
        }

        throw new JsonException($"无法解析日期:{dateStr},支持的格式为:{string.Join(", ", _supportedFormats)}");
    }

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString(_supportedFormats[0], CultureInfo.InvariantCulture));
    }
}

步骤2:将转换器纳入源生成配置

修改JsonSourceGenerationOptions,让上下文识别并使用自定义转换器:

[JsonSourceGenerationOptions(
    WriteIndented = true,
    Converters = new[] { typeof(CustomDateTimeConverter) }
)]
[JsonSerializable(typeof(StateRequest))]
[JsonSerializable(typeof(bool))]
[JsonSerializable(typeof(string))]
[JsonSerializable(typeof(DateTime))]
public partial class StateRequestJsonContext : JsonSerializerContext
{
}

可选:仅针对特定属性应用转换器

如果只需处理StateRequest中的ClientTime属性,可直接在该属性上添加特性,无需修改全局配置:

public class StateRequest
{
    [JsonConverter(typeof(CustomDateTimeConverter))]
    public DateTime ClientTime { get; set; }

    // 其他属性...
}

注意事项

  • 由于使用NativeAOT,所有Json转换器必须是具体类型且可被源生成器静态分析,避免使用依赖反射的动态转换器。
  • 示例中使用CultureInfo.InvariantCulture确保格式解析不受系统区域设置影响,若需适配特定语言环境,可替换为对应CultureInfo实例。

内容的提问来源于stack exchange,提问作者Alex Zaitsev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 03:07:04