. NET Проверка пользовательской модели Core 3.1 с проверкой fluentvalidation - PullRequest
1 голос
/ 14 июля 2020

Я пытаюсь научиться. net 3.1 путем создания небольшого тестового webapi, и в настоящее время моя цель - проверить dtos с помощью fluentvalidation, и в случае сбоя предоставить пользовательский json вызывающему. Проблем, которые я нашел и не могу решить, две;

  • Кажется, я не могу получить сообщения, которые я пишу, через fluentvalidation (они всегда - я предполагаю. net основные по умолчанию)
  • Кажется, я не могу изменить тип объекта, который json -ified, а затем выводить вызывающему.

Мой код выглядит следующим образом:

1. Контроллер

    [ApiController]
[Route("[controller]")]
public class AdminController : ControllerBase
{

    [HttpPost]
    [ProducesResponseType(StatusCodes.Status409Conflict)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status202Accepted)]
    public async Task<IActionResult> RegisterAccount(NewAccountInput dto)
    {

        return Ok();
    }        
}

2. Dto и пользовательский валидатор

 public class NewAccountInput
    {
        public string Username { get; set; }
        public string Email { get; set; }
        public string Phone { get; set; }
        public AccountType Type { get; set; }
    }

    public class NewAccountInputValidator : AbstractValidator<NewAccountInput>
    {
        public NewAccountInputValidator()
        {
            RuleFor(o => o.Email).NotNull().NotEmpty().WithMessage("Email vazio");
            RuleFor(o => o.Username).NotNull().NotEmpty().WithMessage("Username vazio");
        }
    }

3. Фильтр, который я использую для проверки

    public class ApiValidationFilter : ActionFilterAttribute
        {
            public override  void OnActionExecuting(ActionExecutingContext context)
            {
                if (!context.ModelState.IsValid)
                {
//the only output i want are the error descriptions, nothing else
                    var data = context.ModelState
                        .Values
                        .SelectMany(v => v.Errors.Select(b => b.ErrorMessage))
                        .ToList();
                    
                    context.Result = new JsonResult(data) { StatusCode = 400 };
                }
                //base.OnActionExecuting(context);
            }
        }

наконец, мои configureservices

 public void ConfigureServices(IServiceCollection services)
        {
            services
                //tried both lines and it doesnt seem to work either way
                .AddScoped<ApiValidationFilter>()
                .AddControllers(//config=>
                                //config.Filters.Add(new ApiValidationFilter())                
                )
                .AddFluentValidation(fv => {
                    fv.RunDefaultMvcValidationAfterFluentValidationExecutes = false;//i was hoping this did the trick
                    fv.RegisterValidatorsFromAssemblyContaining<NewAccountInputValidator>();
                    
                });

        }

Теперь, попробовав это с почтальоном, я получаю результат

img

, в котором освещены обе проблемы с атм

Это было сделано с помощью asp. net core 3.15 и visualstudio 16.6.3

1 Ответ

2 голосов
/ 14 июля 2020

Сообщение, которое вы видите, на самом деле исходит от FluentValidation - см. Источник .

Причина, по которой вы не видите настраиваемое сообщение, заключается в том, что FluentValidation покажет сообщение проверки от первого валидатора, который не работает в цепочке, в данном случае NotNull.

Этот вопрос дает некоторые варианты для указания одного настраиваемого сообщения проверки для всей цепочки валидаторов.

В этом случае фильтр действий, который вы описываете, никогда не срабатывает, поскольку сначала происходит сбой проверки. Чтобы предотвратить это, вы можете использовать:

services.Configure<ApiBehaviorOptions>(options =>
{
    options.SuppressModelStateInvalidFilter = true;
});

, который остановит автоматический c возврат BadRequest для недопустимой модели. Этот вопрос предлагает некоторые альтернативные решения, в том числе настройку InvalidModelStateResponseFactory на то, что вам нужно.

...