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

使用特性为枚举类型模型属性返回自定义错误消息

问题

我的API请求体JSON会被解析为模型,模型包含多个枚举类型属性,示例属性代码如下:

public Enums.YesNo Indicator { get; set; }

我已在Program.cs中配置:

options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());

当JSON中未提供合法的Yes/No值时,我希望返回自定义错误消息“Invalid Indicator value”,但尝试使用[StringEnumValidation(typeof(Enums.YesNo), "Invalid Indicator value.")]和[EnumDataType(typeof(Enums.YesNo), ErrorMessage = "Invalid Indicator value.")]特性验证后,均未实现预期效果。

解决方案

默认的JsonStringEnumConverter解析失败时会直接抛出异常,不会触发数据注解验证,因此需要通过以下两种方式实现需求:

方法一:自定义JSON枚举转换器

实现带错误提示的自定义转换器,替换默认枚举转换器:

public class CustomStringEnumConverter : JsonStringEnumConverter
{
    private readonly Type _enumType;
    private readonly string _errorMessage;

    public CustomStringEnumConverter(Type enumType, string errorMessage)
    {
        _enumType = enumType;
        _errorMessage = errorMessage;
    }

    public override object? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        try
        {
            return base.Read(ref reader, typeToConvert, options);
        }
        catch (JsonException)
        {
            throw new ValidationException(_errorMessage);
        }
    }
}

在模型属性上指定该转换器:

[JsonConverter(typeof(CustomStringEnumConverter), typeof(Enums.YesNo), "Invalid Indicator value")]
public Enums.YesNo Indicator { get; set; }

注意:需移除Program.cs中原来的JsonStringEnumConverter全局配置,避免冲突。

方法二:全局异常过滤器捕获枚举解析错误

通过全局过滤器统一处理所有枚举解析失败的情况:

  1. 实现异常过滤器:
public class EnumValidationExceptionFilter : IExceptionFilter
{
    public void OnException(ExceptionContext context)
    {
        if (context.Exception is JsonException jsonEx && jsonEx.Message.Contains("was not recognized as a valid enum"))
        {
            var propertyName = ExtractInvalidEnumProperty(jsonEx);
            var errorMessage = $"Invalid {propertyName} value";
            
            context.Result = new BadRequestObjectResult(new ValidationProblemDetails
            {
                Errors = new Dictionary<string, string[]>
                {
                    { propertyName, new[] { errorMessage } }
                }
            });
            context.ExceptionHandled = true;
        }
    }

    private string ExtractInvalidEnumProperty(JsonException ex)
    {
        // 从错误消息中提取属性路径,示例错误消息格式:"The JSON value could not be converted to Enums.YesNo. Path: $.Indicator | LineNumber: 2 | BytePositionInLine: 18."
        var pathStart = ex.Message.IndexOf("Path: $.", StringComparison.Ordinal) + 7;
        var pathEnd = ex.Message.IndexOf(" | ", pathStart, StringComparison.Ordinal);
        return pathEnd > pathStart ? ex.Message.Substring(pathStart, pathEnd - pathStart) : "value";
    }
}
  1. 在Program.cs注册过滤器:
builder.Services.AddControllers(options =>
{
    options.Filters.Add<EnumValidationExceptionFilter>();
});

该方式无需修改模型属性,可全局处理所有枚举类型的解析错误,自动返回对应属性的自定义提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 08:05:28