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

ServiceStack枚举序列化问题:EnumMember属性未按预期生效

解决EnumMember属性序列化不生效的问题

看起来你遇到的核心问题是:你给枚举值添加了[EnumMember(Value = "...")]属性,但序列化时并没有输出指定的自定义值,而是枚举的默认名称。这通常是因为你使用的JSON序列化框架没有正确识别EnumMember属性,或者缺少对应的转换器配置。

下面分两种常见的序列化场景给出针对性解决方案:

场景1:使用Newtonsoft.Json(Json.NET)

如果你的项目用的是经典的Newtonsoft.Json库,只需要启用StringEnumConverter,它会自动读取EnumMember的Value值。

方法1:序列化时指定配置

var jsonSettings = new JsonSerializerSettings
{
    // 添加StringEnumConverter,确保只输出字符串而非整数
    Converters = { new StringEnumConverter { AllowIntegerValues = false } }
};

// 序列化示例
Day today = Day.Monday;
string json = JsonConvert.SerializeObject(today, jsonSettings);
// 输出结果:"MONDAY"

方法2:给枚举标记全局转换器

直接在枚举类上添加转换器属性,后续序列化该枚举时会自动生效:

[DataContract]
[JsonConverter(typeof(StringEnumConverter))]
public enum Day {
    [EnumMember(Value = "MONDAY")]
    Monday,
    [EnumMember(Value = "TUESDAY")]
    Tuesday,
    // ... 其他枚举值
}

场景2:使用System.Text.Json(.NET Core 3.0+ 默认)

如果你的项目用的是.NET Core/.NET 5+自带的System.Text.Json,默认不识别EnumMember属性,需要自定义转换器或命名策略。

方法1:自定义EnumMember转换器

写一个通用转换器来处理枚举的EnumMember属性:

public class EnumMemberJsonConverter<TEnum> : JsonConverter<TEnum> where TEnum : struct, Enum
{
    public override TEnum Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        string value = reader.GetString();
        // 遍历枚举字段匹配EnumMember的Value
        foreach (FieldInfo field in typeof(TEnum).GetFields())
        {
            if (field.GetCustomAttribute<EnumMemberAttribute>() is EnumMemberAttribute attr && attr.Value == value)
            {
                return (TEnum)field.GetValue(null);
            }
        }
        // 匹配失败时回退到默认枚举解析
        return Enum.Parse<TEnum>(value);
    }

    public override void Write(Utf8JsonWriter writer, TEnum value, JsonSerializerOptions options)
    {
        FieldInfo field = value.GetType().GetField(value.ToString());
        EnumMemberAttribute attr = field?.GetCustomAttribute<EnumMemberAttribute>();
        // 优先输出EnumMember的Value,无匹配则输出默认名称
        writer.WriteStringValue(attr?.Value ?? value.ToString());
    }
}

序列化时配置该转换器:

var jsonOptions = new JsonSerializerOptions();
jsonOptions.Converters.Add(new EnumMemberJsonConverter<Day>());

Day today = Day.Monday;
string json = JsonSerializer.Serialize(today, jsonOptions);
// 输出结果:"MONDAY"

方法2:自定义命名策略(.NET 7+)

如果你使用的是.NET 7及以上版本,可以通过自定义命名策略简化实现:

public class EnumMemberNamingPolicy : JsonNamingPolicy
{
    public override string ConvertName(string name)
    {
        var field = typeof(Day).GetField(name);
        var enumMemberAttr = field?.GetCustomAttribute<EnumMemberAttribute>();
        return enumMemberAttr?.Value ?? name;
    }
}

配置序列化选项:

var jsonOptions = new JsonSerializerOptions
{
    Converters = { new JsonStringEnumConverter(new EnumMemberNamingPolicy()) }
};

string json = JsonSerializer.Serialize(Day.Monday, jsonOptions);
// 输出结果:"MONDAY"

最后建议你先确认项目中.ToJson()方法依赖的具体序列化库,再选择对应的方案解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:56:47