Как перехватить ответ об ошибке FluentValidation, чтобы отформатировать его в соответствии со стандартом

Я работаю над ASP.NET Core 2.1 API, который в настоящее время имеет глобальный фильтр ValidateModelAttribute, который перехватывает context.ModelState в методе OnActionExecuting, поэтому он может форматировать любые ошибки состояния модели в соответствии со стандартом дизайна проекта для сообщений об ошибках.

Это работает хорошо. Однако я решил добавить FluentValidation в проект, и, хотя он также работает правильно, он возвращает отклик состояния модели, не обращаясь к методу OnActionExecuting в классе фильтра ValidateModelAttribute.

Вот код в запуске -> метод ConfigureServices для AddMvc

        services.AddMvc(config =>
            {
                config.Filters.Add(typeof(ValidateModelAttribute)); 
            })
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
            .AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<ServiceTypeCodeValidator>())
            .AddJsonOptions(opt =>
            {
                opt.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            });

Вот сам класс ValidateModelAttribute, просто для справки;

public class ValidateModelAttribute : ActionFilterAttribute
{
    /// <summary>
    /// Validates model state upon action execution
    /// </summary>
    /// <param name="context">ActionExecutingContext object</param>
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (context.ModelState.IsValid) return;
        var errorList = context.ModelState.Where(ms => ms.Value.Errors.Any()).ToDictionary(
            kvp => kvp.Key,
            kvp => kvp.Value.Errors.Select(e => string.IsNullOrEmpty(e.ErrorMessage) ? e.Exception.Message : e.ErrorMessage).ToArray()
        );

        var validationErrors = new ValidationErrors();
        foreach (var item in errorList)
        {
            foreach (var message in item.Value)
            {
                if (validationErrors.Errors.ContainsKey(item.Key))
                {
                    validationErrors.Errors[item.Key].Add(message);
                }
                else
                {
                    validationErrors.Errors.Add(item.Key, new List<string>() { message });
                }
            }
        }

        var globalError = new GlobalError { Errors = errorList };
        context.Result = new BadRequestObjectResult(globalError);
    }

}

Я предполагаю, что, поскольку это конвейер asp.net, а AddFluentValidation идет после строки config.filters.Add, именно поэтому я не могу переопределить сообщение об ошибке из FluentValidation через фильтр ValidateModelAttribute.

Поэтому мой вопрос: предоставляет ли FluentValidation какой-либо хук, который я могу переопределить, чтобы отформатировать ответ об ошибке состояния модели в соответствии со стандартом сообщения об ошибке проекта?

1 ответ

Когда вы говорите, что возвращает ответ ModelState, вы имеете в виду ответ .NET по умолчанию? Если это так, просто добавьте это в автозагрузку

      services.Configure<Microsoft.AspNetCore.Mvc.ApiBehaviorOptions>(options =>
{
    options.SuppressModelStateInvalidFilter = true;
});
Другие вопросы по тегам