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

迁移至System.Text.Json:如何处理嵌套序列化DateTime的格式转换?

解决方法

1. 强类型处理(推荐,更安全)

既然SerializedClass本来就是OtherClass的序列化结果,直接反序列化成OtherClass实例,再用配置好的JsonSerializerOptions重新序列化,就能自动把DateTime格式修正过来:

// 配置序列化选项:指定DateTime格式为三位毫秒带Z,保持驼峰命名(如果原JSON是驼峰格式的话)
var options = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    DateTimeFormat = new DateTimeFormatInfo
    {
        FullDateTimePattern = "yyyy-MM-dd'T'HH:mm:ss.fffZ"
    }
};

// 处理你的MyClass对象
var myClass = ...; // 你的MyClass实例
// 把SerializedClass反序列成OtherClass
var otherObj = JsonSerializer.Deserialize<OtherClass>(myClass.SerializedClass, options);
// 重新序列化回字符串,此时DateTime的多余零已经被去掉
myClass.SerializedClass = JsonSerializer.Serialize(otherObj, options);

要是需要更灵活的DateTime控制,也可以自定义转换器:

public class DateTimeTrimmingConverter : JsonConverter<DateTime>
{
    private const string TargetFormat = "yyyy-MM-dd'T'HH:mm:ss.fffZ";

    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 读取时兼容原格式,不管末尾有几个零,自动识别
        return DateTime.Parse(reader.GetString()!, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);
    }

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        // 写入时强制输出三位毫秒的格式
        writer.WriteStringValue(value.ToString(TargetFormat, CultureInfo.InvariantCulture));
    }
}

// 然后在options里添加这个转换器:
options.Converters.Add(new DateTimeTrimmingConverter());

2. 动态JSON操作(类似Newtonsoft的JObject)

如果不想用强类型,要像JObject那样动态操作JSON,在.NET 6及以上版本可以用JsonObject(属于JsonNode体系),结合配置好的选项序列化就能修正格式:

var options = new JsonSerializerOptions
{
    DateTimeFormat = new DateTimeFormatInfo
    {
        FullDateTimePattern = "yyyy-MM-dd'T'HH:mm:ss.fffZ"
    }
};

// 把SerializedClass解析成JsonObject,就能像JObject一样动态修改字段
var jsonObj = JsonNode.Parse(myClass.SerializedClass) as JsonObject;
// 这里可以做任意JSON操作,比如修改某个字段:jsonObj["someKey"] = "newValue";

// 重新序列化时用配置好的options,DateTime格式会自动修正
myClass.SerializedClass = jsonObj!.ToJsonString(options);

为什么之前自定义DateTime转换器没用?

因为你之前是直接解析字符串(SerializedClass),而不是反序列化为包含DateTime字段的类型。只有当反序列化的目标类型里有DateTime字段时,转换器才会被触发。上面两种方案要么反序列成强类型OtherClass(触发转换器),要么解析成JsonNode后,通过序列化选项的配置来统一处理DateTime格式。

注意事项

  • JsonNode(包括JsonObject)是.NET 6才新增的API,如果你用的是更早的.NET版本,得用JsonElement,但操作起来没那么方便,还是升级到.NET 6+更省心。
  • 配置fff格式刚好对应三位毫秒,完美匹配你要的输出格式。
  • 读取DateTime时用DateTimeStyles.RoundtripKind可以保留原时间的Utc标记,避免序列化时出现时区偏移问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 10:34:57