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

反序列化ASP.NET生成的JSON DateTime时出错的技术问询

问题分析与解决方案

核心问题根源

你遇到的差异本质是数据传输方式的区别:

  • 常规API端点接收的是请求体JSON,ASP.NET Core会直接解析原始请求内容,不会做URL编码转换,因此序列化后的标准日期格式(如2023-05-24T20:20:46.9351772+01:00)能被框架默认反序列化逻辑正确处理。
  • 而你当前是从QueryString参数中提取JSON,QueryString中的+符号会被自动解析为空格,导致日期格式变成2023-05-24T20:20:46.9351772 01:00——这种格式不符合JSON标准的日期规范,直接触发反序列化失败。

你自定义的转换器之所以无效,是因为传入的日期字符串里的偏移符号已被替换为空格,DateTime.Parse无法识别带空格的偏移格式。


解决方案

方案1:修复URL编码问题(推荐)

这是最根本的解决方式,QueryString参数必须经过URL编码才能保证特殊字符不被篡改。

MAUI端发送时编码JSON:

string json = JsonSerializer.Serialize(new MyDto(DateTime.Now));
// 对JSON进行URL编码,避免+符号被解析为空格
string encodedJson = Uri.EscapeDataString(json);
// 发送时将encodedJson作为data参数的值传递

API中间件接收时解码:

string encodedData = httpContext.Request.Query["data"].ToString();
// 先解码还原原始JSON
string json = Uri.UnescapeDataString(encodedData);
MyDto dto = JsonHelpers.Deserialise<MyDto>(json);

方案2:统一使用UTC日期格式,规避偏移符号冲突

强制序列化和反序列化都使用UTC格式的日期,彻底避免偏移符号的URL编码问题。

MAUI端序列化配置:

var serializeOptions = new JsonSerializerOptions
{
    DateTimeFormat = new DateTimeFormatInfo
    {
        // 使用UTC后缀Z的格式,无需偏移符号
        FullDateTimePattern = "yyyy-MM-dd'T'HH:mm:ss.fffffffZ"
    }
};
string json = JsonSerializer.Serialize(new MyDto(DateTime.Now.ToUniversalTime()), serializeOptions);

API端反序列化配置:

var deserializeOptions = new JsonSerializerOptions
{
    DateTimeFormat = new DateTimeFormatInfo
    {
        FullDateTimePattern = "yyyy-MM-dd'T'HH:mm:ss.fffffffZ"
    }
};
MyDto dto = JsonSerializer.Deserialize<MyDto>(json, deserializeOptions);
// 如果JsonHelpers.Deserialise支持传入配置,直接传递deserializeOptions即可

方案3:修改自定义转换器兼容空格偏移格式

如果无法修改发送逻辑,可以调整自定义转换器,先修复被篡改的日期字符串:

public class CustomDateTimeConverter : JsonConverter<DateTime?> 
{
    const string Format = "yyyy-MM-dd hh:mm:ss.fffffff zzz";

    public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) 
    {
        // 将空格替换回+符号,还原原始偏移格式
        var dateStr = reader.GetString()?.Replace(' ', '+');
        return DateTime.Parse(dateStr, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
    }

    public override void Write(Utf8JsonWriter writer, DateTime? value, JsonSerializerOptions options) =>
        writer.WriteStringValue(value?.ToUniversalTime().ToString(Format, CultureInfo.InvariantCulture));
}

反序列化时记得传入带该转换器的配置:

var options = new JsonSerializerOptions { Converters = { new CustomDateTimeConverter() } };
MyDto dto = JsonHelpers.Deserialise<MyDto>(json, options);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 20:10:26