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

C#中ISO8601格式DateTime转换失败问题及处理方案咨询

解决C#后端解析带逗号分隔毫秒的JSON DateTime问题

核心问题原因

默认的JSON DateTime解析器仅识别点分隔的毫秒格式(如2022-10-20T16:16:27.000-03:00),而JUCE库生成的新格式用逗号分隔毫秒(2022-10-20T16:16:27,154-03:00),导致模型绑定阶段直接触发转换错误。你之前尝试在模型set方法中替换字符串无效,是因为模型绑定的转换逻辑优先于属性set方法执行,错误在set操作前就已抛出。

推荐解决方案

方案1:自定义JSON DateTime转换器(优先选择)

创建兼容两种毫秒分隔格式的自定义转换器,全局注册后所有DateTime类型的解析都会自动处理该问题,精准且安全。

自定义转换器代码

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

public class MultiFormatDateTimeConverter : JsonConverter<DateTime>
{
    // 同时支持点分隔和逗号分隔的毫秒格式
    private readonly string[] _supportedFormats = new[]
    {
        "yyyy-MM-dd'T'HH:mm:ss.fffzzz",
        "yyyy-MM-dd'T'HH:mm:ss,fffzzz"
    };

    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var dateStr = reader.GetString();
        if (DateTime.TryParseExact(dateStr, _supportedFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime result))
        {
            return result;
        }
        throw new JsonException($"无法解析日期字符串:{dateStr}");
    }

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        // 统一输出标准的点分隔格式
        writer.WriteStringValue(value.ToString("yyyy-MM-dd'T'HH:mm:ss.fffzzz"));
    }
}

全局注册转换器

在Startup.cs(或.NET 6+的Program.cs)的服务配置中添加转换器:

// .NET Core 3.0+ 使用System.Text.Json的场景
services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Converters.Add(new MultiFormatDateTimeConverter());
    });

// 如果项目使用Newtonsoft.Json(旧版本或显式配置)
services.AddControllers()
    .AddNewtonsoftJson(options =>
    {
        options.SerializerSettings.Converters.Add(new MultiFormatDateTimeConverter());
    });

方案2:中间件全局替换请求体中的逗号

如果需要在请求到达模型绑定前修改JSON内容,可以通过中间件将DateTime格式中的逗号替换为点。需确保正则表达式仅匹配目标日期格式,避免误改其他字段的逗号。

中间件代码

using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Http;

public class DateTimeCommaFixMiddleware
{
    private readonly RequestDelegate _next;
    // 正则匹配带时区的日期格式,捕获毫秒前的逗号
    private readonly Regex _dateCommaRegex = new Regex(@"(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}),(\d{3})([+-]\d{2}:\d{2})", RegexOptions.Compiled);

    public DateTimeCommaFixMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        // 仅处理POST类型的JSON请求
        if (context.Request.Method == HttpMethods.Post && 
            context.Request.ContentType?.StartsWith("application/json") == true)
        {
            // 启用请求体缓冲,允许重复读取
            context.Request.EnableBuffering();
            
            using var reader = new StreamReader(context.Request.Body, Encoding.UTF8, leaveOpen: true);
            var requestBody = await reader.ReadToEndAsync();
            
            // 替换日期格式中的逗号为点
            var modifiedBody = _dateCommaRegex.Replace(requestBody, "$1.$2$3");
            
            // 重置请求体流位置,供后续组件读取
            var modifiedBytes = Encoding.UTF8.GetBytes(modifiedBody);
            context.Request.Body = new MemoryStream(modifiedBytes);
            context.Request.ContentLength = modifiedBytes.Length;
        }

        await _next(context);
    }
}

注册中间件

在Startup.cs的Configure方法(或.NET 6+的Program.cs)中,在UseRouting之后、UseAuthorization之前注册:

app.UseRouting();

// 添加自定义中间件
app.UseMiddleware<DateTimeCommaFixMiddleware>();

app.UseAuthorization();

方案对比

  • 自定义转换器:针对性强,仅处理DateTime类型,不会影响其他JSON字段,是最稳妥的方案。
  • 中间件方案:适合批量修改请求体的场景,但依赖正则表达式的准确性,若JSON中存在其他类似格式的逗号(如字符串中的日期)可能会误替换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 06:35:29