Как перехватить ответ об ошибке 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;
});