我想在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();
}
答案 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();
}