禁用asp.net核心

时间:2018-04-12 20:38:37

标签: c# asp.net-core fluentvalidation

我想在Controller中的特定Action方法上禁用模型验证。我有这种情况:

public class SomeDto
{
    public string Name { get; set; }
}

public class SomeDtoValidator : AbstractValidator<SomeDto>, ISomeDtoValidator
{
    public SomeDtoValidator ()
    {
        RuleFor(someDto=> someDto.Name).NotNull().WithMessage("Name property can't be null.");
    }
}

我有ISomeDtoValidator,因为我以自己的方式注册所有验证器:

public class Startup
{
    // .... constructor ....

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddOptions();
        services.AddMvc(setup => {
        //...others setups...
        }).AddFluentValidation();

        services.RegisterTypes(Configuration)
                .RegisterFluentValidation()
                .RegisterMappingsWithAutomapper()
                .RegisterMvcConfigurations();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, IConfiguration configuration)
    {
        // ...
    }
}

我在Controller中有这个Action方法:

[DisableFormValueModelBinding]
public async Task<IActionResult> CreateSome(Guid someId, SomeDto someDto)
{
    //..... Manually binding someDto...

    var validator = new SomeValidator();
    validator.Validate(someDto);

    // Doing something more ........

    return Ok();
}       

我禁用了modelBinding的MVC,因为我想在绑定SomeDto之前做一些事情,因此,我也不想在SomeDto上应用任何验证器。那么,有什么方法可以实现这一点?例如,像这样:

[DisableValidator] // Or [DisableValidator(typeof(SomeDtoValidator))] whatever
[DisableFormValueModelBinding]
public async Task<IActionResult> CreateSome(Guid someId, SomeDto someDto)
{
    //..... Manually binding someDto...

    var validator = new SomeValidator();
    validator.Validate(someDto);

    // Doing something more ........

    return Ok();
}   

3 个答案:

答案 0 :(得分:3)

您可以通过将以下属性添加到您的操作方法参数来跳过验证:

public ActionResult Save([CustomizeValidator(Skip = true)] Customer model) {
  // ...
}

此处的文档中对此进行了描述: https://docs.fluentvalidation.net/en/latest/aspnet.html#validator-customization

答案 1 :(得分:1)

您可以使用RuleSet。

请参阅:https://github.com/JeremySkinner/FluentValidation/wiki/b.-Creating-a-Validator#rulesets

public class CustomerValidator : AbstractValidator<Customer>
{
    public CustomerValidator()
    {
        RuleFor(customer => customer.Surname).NotEmpty();
        RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
        RuleFor(customer => customer.Address).Length(20, 250);

        RuleSet("Names", () =>
        {
            RuleFor(x => x.Surname).NotNull();
            RuleFor(x => x.Forename).NotNull();
        });

        RuleSet("Empty", () =>
        {
        });
    }
}

测试代码:

        Customer customer = new Customer();
        var validator = new CustomerValidator();
        var validationResult = validator.Validate(customer, ruleSet: "Names");
        // 2 errors: Surname and Forname
        validationResult = validator.Validate(customer, ruleSet: "Empty");
        // no errors

您可以在控制器中配置RuleSet:

public ActionResult SaveNoValidate([CustomizeValidator(RuleSet="Empty")] Customer customer) {
// ...
}

public ActionResult SaveValidateNames([CustomizeValidator(RuleSet="Names")] Customer customer ) {
// ...
}

答案 2 :(得分:1)

我通过@Alexey.Petriashev的帮助达到了我的目标,只在验证器中放置了一个RuleSet。当管道调用验证器时,它没有进行验证,因为管道调用没有RuleSet。贝娄是我如何解决这个问题的一个例子:

public class CustomerValidator : AbstractValidator<Customer>
{
    public CustomerValidator()
    {
        RuleSet("Manually", () =>
        {
            RuleFor(x => x.Surname).NotNull();
            RuleFor(x => x.Forename).NotNull();
        });
    }
}

public ActionResult ActionWithoutValidationExecuted(Customer customer) 
{
    //..... Manually binding customer...

    var validator = new CustomerValidator();
    var validResult = validator.Validate(customer, ruleSet: "Manually");

    // Doing something more ........

    return Ok();
}