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

如何在.NET System.Text.Json中编写基于属性名的自定义序列化转换器

可行实现方案

JsonConverter<T>的Write方法设计上确实不包含当前序列化属性的元数据,无法直接获取属性名,可通过以下方案实现需求:

方案1:使用JsonTypeInfo修饰器(推荐,适用于.NET 6+)

这是System.Text.Json官方提供的元数据自定义能力,可以在序列化前全局配置所有类型的属性序列化规则,不需要修改业务类代码。

  1. 先实现两种不同格式的DateTime转换器
// 保留时间部分的转换器
internal class DateTimeWithTimeConverter : JsonConverter<DateTime>
{
    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return DateTime.Parse(reader.GetString() ?? string.Empty);
    }

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString("yyyy-MM-dd HH:mm:ss"));
    }
}

// 仅保留日期部分的转换器
internal class DateTimeOnlyDateConverter : JsonConverter<DateTime>
{
    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return DateTime.Parse(reader.GetString() ?? string.Empty);
    }

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString("yyyy-MM-dd"));
    }
}
  1. 实现全局属性规则匹配逻辑
public static void DateTimeFormatRuleModifier(JsonTypeInfo typeInfo)
{
    // 只处理普通类类型
    if (typeInfo.Kind != JsonTypeInfoKind.Object)
        return;

    foreach (var property in typeInfo.Properties)
    {
        // 只处理DateTime类型的属性
        if (property.PropertyType != typeof(DateTime))
            continue;

        // 根据属性名后缀绑定对应转换器
        if (property.Name.EndsWith("DateTime", StringComparison.OrdinalIgnoreCase))
        {
            property.CustomConverter = new DateTimeWithTimeConverter();
        }
        else
        {
            property.CustomConverter = new DateTimeOnlyDateConverter();
        }
    }
}
  1. 序列化时注入配置
var serializeOptions = new JsonSerializerOptions
{
    TypeInfoResolver = new DefaultJsonTypeInfoResolver
    {
        Modifiers = { DateTimeFormatRuleModifier }
    }
};

// 后续序列化直接使用该options即可
var json = JsonSerializer.Serialize(yourObject, serializeOptions);

方案2:.NET 6以下版本兼容方案

如果使用的是.NET 5及更早版本,没有TypeInfo修饰器能力,可以改用JsonConverterFactory结合特性标记的方式实现:

  • 自定义DateTimeFormatAttribute特性,标记是否保留时间
  • 转换器工厂在创建转换器时读取属性上的特性,返回对应格式的转换器
    该方案需要给每个DateTime属性加特性,性能和易用性略低于方案1。

效果验证

定义测试类:

public class TestDemo
{
    public DateTime CreateTime { get; set; } = new DateTime(2024,5,20,13,14,15);
    public DateTime PayDateTime { get; set; } = new DateTime(2024,5,20,13,14,15);
}

序列化结果:

{"CreateTime":"2024-05-20","PayDateTime":"2024-05-20 13:14:15"}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 09:15:03