在 Fluent Validation 中显示有效值

Show Valid Values in Fluent Validation

我正在使用 Fluent Validation 和 MVC 过滤器来验证请求。作为错误的一部分,我想显示一个有效值列表。我不确定如何让 ValidValues 属性 填充有效值列表,就像 FieldName 和 Message 被验证过滤器填充一样。

目前的错误信息是这样的:

{
    "errors": [
        {
            "fieldName": "Make",
            "message": "Invalid Make"
        }
    ]
}

我希望它显示如下内容:

{
    "errors": [
        {
            "fieldName": "Make",
            "message": "Invalid Make",
            "validValues": ["Ford", "Honda"]
        }
    ]
}

我的错误模型:

public class Error
{
    public string FieldName { get; set; }
    public string Message { get; set; }
    public string[] ValidValues { get; set; }
}

验证者:

RuleFor(car => car.Make)
    .Must(BeAValidMake)
    .WithMessage("Invalid Make.");
    //Add Valid values some how so they can be used by the validation filter to populate the error model.

验证过滤器:

public class ValidationFilter : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        if (!context.ModelState.IsValid)
        {
            var errorsInModelState = context.ModelState
                .Where(x => x.Value.Errors.Count > 0)
                .ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Errors.Select(e => e.ErrorMessage)).ToArray();

            var errorResponse = new ErrorResponse();

            foreach (var error in errorsInModelState)
            {
                foreach (var subError in error.Value)
                {
                    var errorModel = new Error()
                    {
                        FieldName = error.Key,
                        Message = subError
                    };

                    errorResponse.Errors.Add(errorModel);
                }
            }

            context.Result = new BadRequestObjectResult(errorResponse);
            return;
        }

        await next();
    }
}

我还没有找到任何有用的内置 属性 等,但快速解决方案是这样的,

 public class InputModelValidator : AbstractValidator<InputModel>
{
    public InputModelValidator()
    {
        RuleFor(x => x.Name)
            .Length(1, 10);
        RuleFor(x => x.Email)
            .EmailAddress()
            .WithMessage("My Error Message %Split% Possible Values");
    }
}

你的动作过滤器看起来像这样,

public class ValidationFilter : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        if (!context.ModelState.IsValid)
        {
            var errorsInModelState = context.ModelState
                .Where(x => x.Value.Errors.Count > 0)
                .ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Errors.Select(e => e.ErrorMessage)).ToArray();

            var errorResponse = new ErrorResponse();

            foreach (var error in errorsInModelState)
            {
                foreach (var subError in error.Value)
                {
                    var errorModel = new Error()
                    {
                        FieldName = error.Key,
                        Message = subError.Split("%Split%")[0],
                        ValidValues = subError.Split("%Split%")[1],
                    };

                    errorResponse.Errors.Add(errorModel);
                }
            }

            context.Result = new BadRequestObjectResult(errorResponse);
            return;
        }

        await next();
    }
}

示例响应

{
    "errors": [
        {
            "fieldName": "Email",
            "message": "My Error Message ",
            "validValues": " Possible Values"
        }
    ]
}