在ASP.NET Core 1.1上使用自定义验证器和Fluent验证

时间:2017-06-04 01:43:54

标签: c# asp.net-mvc asp.net-core-mvc simple-injector fluentvalidation

我无法让自定义验证程序在客户端工作。在 ASP.NET MVC5 中,我曾使用 Simple Injector 来注册validatiors:

var assemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
container.Register<IValidatorFactory, ApplicationValidatorFactory>(Lifestyle.Singleton);
container.Register(typeof(IValidator<>), assemblies);
container.RegisterConditional(typeof(IValidator<>),
    typeof(ValidateNothingDecorator<>), 
    Lifestyle.Singleton, 
    context => !context.Handled);

并注册所有自定义验证器:

// Register Simple Injector validation factory in FV
FluentValidationModelValidatorProvider.Configure(provider =>
{
    provider.ValidatorFactory = new ApplicationValidatorFactory(container);
    provider.AddImplicitRequiredValidator = false;
    provider.Add(typeof(UniqueEmailValidator),
        (m, c, d, v) => new UniqueEmailPropertyValidator(m, c, d, v));
    provider.Add(typeof(UniqueUsernameValidator),
        (m, c, d, v) => new UniqueUsernamePropertyValidator(m, c, d, v));
    provider.Add(typeof(StringNoSpacesValidator),
        (m, c, d, v) => new StringNoSpacesPropertyValidator(m, c, d, v));
    provider.Add(typeof(PasswordStrengthValidator),
        (m, c, d, v) => new PasswordStrengthPropertyValidator(m, c, d, v));
});

在JS方面添加这些方法:

jQuery.validator.addMethod("nospaces", function(value, element)   {
    return value.indexOf(" ") < 0 && value != ""; 
    }, language.username_has_spaces); 

jQuery.validator.unobtrusive.adapters.add("nospaces", function (options) {
    options.rules["nospaces"] = true;
    if (options.message) {
        options.messages["nospaces"] = options.message;
    }
});

jQuery.validator.unobtrusive.adapters.add("passwordmeter", function (options) {
    options.rules["passwordmeter"] = true;
    if (options.message) {
        options.messages["passwordmeter"] = options.message;
    }
});

那就是它!它完美无缺!

如何对ASP.NET Core 1.1执行相同的操作?

我已按照文档提及使用Microsoft的DI注册它

services.AddMvc().AddFluentValidation(
    fv => fv.RegisterValidatorsFromAssemblyContaining<Startup>());

但这有几个问题:

  • 无法在客户端上使用自定义验证程序(内置工具很棒)
  • 已经在SimpleInjector中注册的自定义验证器中使用的服务必须使用Microsoft的DI逐个注册。 services.AddTransient<IUserRegistrationService, UserRegistrationService>();

1 个答案:

答案 0 :(得分:1)

感谢这是一篇较老的帖子,但我使用FluentValidation(7.2.1)与Core 2有类似的问题/困惑。我无法弄清楚如何将客户端data-属性放到元素上与我的自定义PropertyValidator相关联。

首先我创建了PropertyValidator实现...

public class MyCustomValidator : PropertyValidator
{
    public MyCustomValidator()
        : base("{PropertyName} must do something.") { }

    protected override bool IsValid(PropertyValidatorContext context)
    {
        // Removed for brevity
        return true;
    }
}

...然后IClientModelValidator实现提供客户端data-属性...

public class MyCustomPropertyValidator : ClientValidatorBase, IClientModelValidator
{
    public MyCustomPropertyValidator(PropertyRule rule, IPropertyValidator validator)
        : base(rule, validator)
    {
    }

    public override void AddValidation(ClientModelValidationContext context)
    {
        var validator = (MyCustomValidator)Validator;

        MergeAttribute(context.Attributes, "data-val", "true");
        MergeAttribute(context.Attributes, "data-val-whatever", "...");

        // Add other attributes
    }
}   

...然后在注册Fluent验证时使用ConfigureClientsideValidation方法将其挂钩...

services
.AddMvc()
.AddFluentValidation(cfg =>
{
    cfg.ConfigureClientsideValidation(x =>
    {
        x.Add(typeof(MyCustomValidator), (context, rule, validator) => new MyCustomPropertyValidator(rule, validator));
        // other types ...
    });
    cfg.RegisterValidatorsFromAssemblyContaining<Startup>();
});

最后,像原始帖子一样,连接JS验证。