在Asp.Net核心MVC中使用Fluent验证进行远程验证?

在Asp.Net核心MVC中使用Fluent验证进行远程验证?,asp.net,asp.net-core-mvc,Asp.net,Asp.net Core Mvc,我的代码是: public class UniqueEmailPropertyValidator : FluentValidationModelValidatorProvider { public UniqueEmailPropertyValidator(ModelMetadata metadata, ControllerContext controllerContext, PropertyRule rule, IPropertyValidator validator)

我的代码是:

public class UniqueEmailPropertyValidator : FluentValidationModelValidatorProvider
{

    public UniqueEmailPropertyValidator(ModelMetadata metadata, ControllerContext controllerContext, PropertyRule rule, IPropertyValidator validator)
         : base(metadata, controllerContext, rule, validator)
    {
    }

    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
    {
        if (!this.ShouldGenerateClientSideRules())
            yield break;

        var formatter = new MessageFormatter().AppendPropertyName(Rule.PropertyName);
        string message = formatter.BuildMessage(Validator.ErrorMessageSource.GetString());

        var rule = new ModelClientValidationRule
        {
            ValidationType = "remote",
            ErrorMessage = message
        };
        rule.ValidationParameters.Add("url", "/api/validation/uniqueemail");

        yield return rule;
    }
公共类UniqueEmailPropertyValidator:FluentValidationModelValidatorProvider
{
公共UniqueEmailPropertyValidator(ModelMetadata元数据、ControllerContext ControllerContext、PropertyRule规则、IPropertyValidator验证器)
:base(元数据、controllerContext、规则、验证器)
{
}
公共重写IEnumerable GetClientValidationRules()
{
如果(!this.ShouldGenerateClientSideRules())
屈服断裂;
var formatter=new MessageFormatter().AppendPropertyName(Rule.PropertyName);
string message=formatter.BuildMessage(Validator.ErrorMessageSource.GetString());
var规则=新ModelClientValidationRule
{
ValidationType=“远程”,
ErrorMessage=消息
};
rule.ValidationParameters.Add(“url”,“/api/validation/uniquemail”);
收益率-收益率规则;
}
现在的错误是:

FluentValidationModelValidatorProvider由于其 保护级别


首先创建服务器端验证程序

using FluentValidation.Validators;
using FluentValidationSample.Services;

namespace FluentValidationSample.ModelsValidations
{
    public class UniqueEmailValidator : PropertyValidator
    {
        private readonly IUsersService _usersService;

        public UniqueEmailValidator(IUsersService usersService)
                : base("It's already in use.")
        {
            _usersService = usersService;
        }

        protected override bool IsValid(PropertyValidatorContext context)
        {
            return context.PropertyValue != null &&
                    _usersService.IsUniqueEmail((string)context.PropertyValue);
        }
    }
}
然后创建ClientValidator以生成所需的元数据:

using FluentValidation;
using FluentValidation.AspNetCore;
using FluentValidation.Internal;
using FluentValidation.Resources;
using FluentValidation.Validators;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;

namespace FluentValidationSample.ModelsValidations
{
    public class RemoteClientValidator : ClientValidatorBase
    {
        public string RemoteUrl { set; get; }

        public RemoteClientValidator(PropertyRule rule, IPropertyValidator validator) :
            base(rule, validator)
        {
        }

        public override void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "true");
            MergeAttribute(context.Attributes, "data-val-remote", GetErrorMessage(context));
            MergeAttribute(context.Attributes, "data-val-remote-url", RemoteUrl);
        }

        private string GetErrorMessage(ClientModelValidationContext context)
        {
            var formatter = ValidatorOptions.MessageFormatterFactory().AppendPropertyName(Rule.GetDisplayName());
            string messageTemplate;
            try
            {
                messageTemplate = Validator.Options.ErrorMessageSource.GetString(null);
            }
            catch (FluentValidationMessageFormatException)
            {
                messageTemplate = ValidatorOptions.LanguageManager.GetStringForValidator<NotEmptyValidator>();
            }
            return formatter.BuildMessage(messageTemplate);
        }
    }
}
使用FluentValidation;
使用FluentValidation.AspNetCore;
使用FluentValidation.Internal;
使用FluentValidation.Resources;
使用FluentValidation.validator;
使用Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
命名空间FluentValidationSample.ModelsValidations
{
公共类RemoteClientValidator:ClientValidatorBase
{
公共字符串RemoteUrl{set;get;}
公共RemoteClientValidator(PropertyRule规则,IPropertyValidator验证器):
基本(规则、验证器)
{
}
public override void AddValidation(ClientModelValidationContext上下文)
{
MergeAttribute(context.Attributes,“数据值”、“真”);
MergeAttribute(context.Attributes,“数据值远程”,GetErrorMessage(context));
MergeAttribute(context.Attributes,“数据值远程url”,远程url);
}
私有字符串GetErrorMessage(ClientModelValidationContext上下文)
{
var formatter=ValidatorOptions.MessageFormatterFactory().AppendPropertyName(Rule.GetDisplayName());
字符串消息模板;
尝试
{
messageTemplate=Validator.Options.ErrorMessageSource.GetString(null);
}
捕获(FluentValidationMessageFormatException)
{
messageTemplate=ValidatorOptions.LanguageManager.GetStringForValidator();
}
返回formatter.BuildMessage(messageTemplate);
}
}
}
最后,将它们介绍给系统:

namespace FluentValidationSample.Web
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddScoped<IUsersService, UsersService>();

            services.AddControllersWithViews().AddFluentValidation(
                fv =>
                {
                    fv.RegisterValidatorsFromAssembly(Assembly.GetExecutingAssembly());
                    fv.RegisterValidatorsFromAssemblyContaining<RegisterModelValidator>();
                    fv.RunDefaultMvcValidationAfterFluentValidationExecutes = false;

                    fv.ConfigureClientsideValidation(clientSideValidation =>
                    {
                        // ...

                        clientSideValidation.Add(
                            validatorType: typeof(UniqueEmailValidator),
                            factory: (context, rule, validator) =>
                                        new RemoteClientValidator(rule, validator)
                                        {
                                            RemoteUrl = "/Home/ValidateUniqueEmail"
                                        });
                    });
                }
            );
        }
名称空间FluentValidationSample.Web
{
公营创业
{
public void配置服务(IServiceCollection服务)
{
services.addScope();
services.AddControllersWithViews().AddFluentValidation(
fv=>
{
RegisterValidatorsFromAssembly(Assembly.getExecutionGassembly());
fv.RegisterValidatorsFromAssemblyContaining();
fv.RunDefaultMvcValidationAfterFluentValidationExecutes=false;
fv.ConfigureClientsideValidation(clientSideValidation=>
{
// ...
clientSideValidation.Add(
validatorType:typeof(UniqueMailValidator),
工厂:(上下文、规则、验证器)=>
新的RemoteClientValidator(规则,验证器)
{
RemoteUrl=“/Home/ValidateUniqueEmail”
});
});
}
);
}

你检查过这篇文章了吗?是的,亲爱的,我检查过那篇文章,但它完全是针对asp.net mvc的,而不是针对core的。这是由于.net core管道的更改,你可能需要做一些更改,因为该基类在Source中是
内部的
,并且基于开发人员对core结构的评论mvc,这现在是不可能的。那么如何在asp.net核心mvc中进行远程验证或自定义验证呢?