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

如何用System.Text.Json将第三方枚举数组序列化为字符串数组?

使用System.Text.Json序列化第三方枚举数组为字符串值数组

问题背景

假设现有如下DTO:

public class FooDto
{
    public string Bar { get; set; }
    public DayOfWeek[] Days { get; set; }
}

需要将其序列化为符合API要求的JSON:

{
    "bar": "someString",
    "days": ["Monday", "Friday", "Sunday"]
}

但默认序列化结果会将枚举转为数值:

{
    "bar": "someString",
    "days": [1, 5, 0]
}

核心问题:如何用System.Text.Json将System.DayOfWeek这类第三方枚举数组序列化为字符串值数组,且不使用Newtonsoft.Json。

已尝试但无效的思路:

  • 在数组属性上标注[JsonConverter(typeof(JsonStringEnumConverter))]不生效
  • 无法直接修改第三方枚举DayOfWeek添加转换器特性
  • 枚举不支持继承,无法创建代理类
  • 自定义DTO并编写映射逻辑不够优雅

解决方案

方法一:全局配置JsonSerializerOptions(最简洁)

直接在序列化时配置JsonSerializerOptions,添加JsonStringEnumConverter并启用驼峰命名(匹配目标JSON格式),该配置会自动处理所有枚举类型(包括数组中的枚举元素):

var fooDto = new FooDto
{
    Bar = "someString",
    Days = new[] { DayOfWeek.Monday, DayOfWeek.Friday, DayOfWeek.Sunday }
};

var options = new JsonSerializerOptions
{
    // 添加枚举转字符串的转换器
    Converters = { new JsonStringEnumConverter() },
    // 启用驼峰命名,匹配目标JSON的属性名格式
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};

string json = JsonSerializer.Serialize(fooDto, options);

序列化结果完全符合需求:

{
    "bar": "someString",
    "days": ["Monday", "Friday", "Sunday"]
}

方法二:自定义针对DayOfWeek[]的JsonConverter

如果只需要针对特定的枚举数组属性处理,而非全局配置,可以自定义转换器:

public class DayOfWeekArrayConverter : JsonConverter<DayOfWeek[]>
{
    private readonly JsonStringEnumConverter _enumConverter = new JsonStringEnumConverter();

    public override DayOfWeek[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType != JsonTokenType.StartArray)
            throw new JsonException("JSON token is not an array.");

        var dayList = new List<DayOfWeek>();
        while (reader.Read())
        {
            if (reader.TokenType == JsonTokenType.EndArray)
                break;

            // 复用JsonStringEnumConverter处理单个枚举元素的反序列化
            var day = (DayOfWeek)_enumConverter.Read(ref reader, typeof(DayOfWeek), options);
            dayList.Add(day);
        }
        return dayList.ToArray();
    }

    public override void Write(Utf8JsonWriter writer, DayOfWeek[] value, JsonSerializerOptions options)
    {
        writer.WriteStartArray();
        foreach (var day in value)
        {
            // 复用JsonStringEnumConverter处理单个枚举元素的序列化
            _enumConverter.Write(writer, day, options);
        }
        writer.WriteEndArray();
    }
}

然后在DTO的属性上标注该转换器(同时记得配置驼峰命名):

public class FooDto
{
    public string Bar { get; set; }
    [JsonConverter(typeof(DayOfWeekArrayConverter))]
    public DayOfWeek[] Days { get; set; }
}

// 序列化时配置驼峰命名
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
string json = JsonSerializer.Serialize(fooDto, options);

说明

方法一的全局配置方式最为简洁,无需额外编写自定义转换器,且能统一处理所有枚举类型的序列化/反序列化;方法二则适用于仅需针对特定枚举数组属性做特殊处理的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 20:36:38