流利验证:如何检查电子邮件是否已经存在

发布于 2025-02-11 23:00:07 字数 7466 浏览 1 评论 0原文

我正在开发具有Fluent验证的大型应用程序。

我正在使用一个管理个人资料页面,他们可以在其中更改其名字,姓氏和电子邮件。

这是我的剃须刀:

<EditForm Model="Input" OnValidSubmit="@UpdateProfile">
    <FluentValidator TValidator="InputModelValidator" />
    <div class="form-row">
        <div class="form-group col-md-6">
            <h2>Manage Profile</h2>
        </div>
    </div>
    <div class="form-row">
        <div class="form-group col-md-4">
            <SfTextBox FloatLabelType="FloatLabelType.Auto" Placeholder="First Name" @bind-Value="Input.FirstName"></SfTextBox>
        </div>
        <div class="form-group col-md-4">
            <SfTextBox FloatLabelType="FloatLabelType.Auto" Placeholder="Last Name" @bind-Value="Input.LastName"></SfTextBox>
        </div>
    </div>
    <div class="form-row">
        <div class="form-group col-md-4">
            <SfTextBox FloatLabelType="FloatLabelType.Auto" Placeholder="Email Address" @bind-Value="Input.Email"></SfTextBox>
        </div>
    </div>
    <div class="form-row btn-update">
        <div class="form-group col-md-4">
            <SfButton IsPrimary="true">Update</SfButton>
            <SfToast ID="toast_customDupemail" @ref="@toastDuplicateEmail" Title="Invalid Email" Content="@toastDupEmailErrorMsg" CssClass="e-toast-danger" Timeout=6000>
                <ToastPosition X="Center" Y="Top"></ToastPosition>
             </SfToast>
        </div>
    </div>
</EditForm>

这是我的验证者:

    public class InputModelValidator : AbstractValidator<InputModel>
    {
        public InputModelValidator()
        {
            
            RuleFor(e => e.FirstName).NotEmpty().WithMessage("First name is required.");
            RuleFor(e => e.LastName).NotEmpty().WithMessage("Last name is required.");
            RuleFor(e => e.Email).NotEmpty().WithMessage("Email is required.");
            RuleFor(e => e.Email).EmailAddress().WithMessage("Email is not valid.");
            RuleFor(x => x.Email).Custom((email, context) => {
                if (IsEmailValid(email) == false)
                {
                    context.AddFailure("The email is not valid.");
                }
            });
        }

        private bool IsEmailValid(string email)
        {
            var userInfo = Task.Run(async () => await utilities.GetApplicationUser().ConfigureAwait(false)).Result;

            if (string.Equals(userInfo.Email, email, StringComparison.OrdinalIgnoreCase) == true)
            {
                return true;
            }

            return false;
        }
    }

我有空白和有效电子邮件等的初步检查。这些工作很棒!

我需要添加一个自定义消息,以确保尚未使用该电子邮件。

在验证器类中,与数据库 / ASP.NET身份< / code>交谈的正确方法是什么?

我试图注入我的依赖项,但是当我尝试时它们的依赖性为零。

谢谢。

更新:

每个响应需要在处理程序中发生,这是可能的吗?

    public partial class ManageProfile
    {
        public InputModel Input { get; set; } = new InputModel();
        private EditContext _editContext;

        protected override async Task OnInitializedAsync() // = On Page Load
        {

            var userInfo = await utilities.GetApplicationUser().ConfigureAwait(false);

            Input = new InputModel
            {
                FirstName = userInfo.FirstName,
                LastName = userInfo.LastName,
                Email = userInfo.Email
            };

            await InvokeAsync(StateHasChanged).ConfigureAwait(false);
        }

        private async Task<EditContext> UpdateProfile()
        {
            _editContext = new EditContext(Input);
            var messages = new ValidationMessageStore(_editContext);

            messages.Clear();

            if (IsEmailValid(Input.Email) == false)
            {
                messages.Add(() => Input.Email, "Name should start with a capital.");
                _editContext.NotifyValidationStateChanged();
                return _editContext;
            }


            return _editContext;
        }

        private void ValidateFields(EditContext editContext, ValidationMessageStore messages, FieldIdentifier field)
        {
            messages.Clear();

            if (IsEmailValid(Input.Email) == false)
            {
                messages.Add(() => Input.Email, "Name should start with a capital.");
                editContext.NotifyValidationStateChanged();
            }
        }

        private bool IsEmailValid(string email)
        {
            var userInfo = Task.Run(async () => await utilities.GetApplicationUser().ConfigureAwait(false)).Result;

            if (string.Equals(userInfo.Email, email, StringComparison.OrdinalIgnoreCase) == true)
            {
                return true;
            }

            return false;
        }
    }

    public class InputModel
    {
        [Required]
        [MaxLength(250)]
        [Display(Name = "First Name", Prompt = "Enter first name")]
        public string FirstName { get; set; }

        [Required]
        [MaxLength(250)]
        [Display(Name = "Last Name", Prompt = "Enter last name")]
        public string LastName { get; set; }

        /// <summary>
        ///     This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        [Required]
        [EmailAddress]
        [Display(Name = "Email", Prompt = "Enter email")]
        public string Email { get; set; }
    }

    public class InputModelValidator : AbstractValidator<InputModel>
    {
        public InputModelValidator()
        {
            
            RuleFor(e => e.FirstName).NotEmpty().WithMessage("First name is required.");
            RuleFor(e => e.LastName).NotEmpty().WithMessage("Last name is required.");
            RuleFor(e => e.Email).NotEmpty().WithMessage("Email is required.");
            RuleFor(e => e.Email).EmailAddress().WithMessage("Email is not valid.");
        }
    }

更新3:

    public class InputModelValidator : AbstractValidator<InputModel>
    {
        public InputModelValidator(UserManager<ApplicationUser> user)
        {         
            RuleFor(e => e.FirstName).NotEmpty().WithMessage("First name is required.");
            RuleFor(e => e.LastName).NotEmpty().WithMessage("Last name is required.");
            RuleFor(e => e.Email).NotEmpty().WithMessage("Email is required.");
            RuleFor(e => e.Email).EmailAddress().WithMessage("Email is not valid.");
            //RuleFor(e => e.Email).EmailAddress().WithMessage("Email is not valid.").Must(IsEmailexist).WithMessage("{PropertyName} Is Already Exist.");
        }

        private async Task<bool> IsEmailexist(string Email)
        {
            return false;
        }
    }

我尝试注入usermanager&lt;&gt;,但是我有此错误:

严重性代码描述项目文件行抑制状态 错误的CS0310'InputModelValidator'必须是具有公共参数无参数构造函数的非抽象类型,以便将其用作通用类型或方法“ fluentValidator” C:... \ Microsoft.net.net.net.sdk.razor。 sourceGenerators \ Microsoft.net.sdk.razor.sourcegenerators.razorsourcegenerator \ region_Identity_pages_Account_ManageProfile_razor.g.cs 200活跃

I'm working on a Blazor application with fluent validation.

I'm working on a manage profile page where they can change their first name, last name, and email.

Here is my Razor:

<EditForm Model="Input" OnValidSubmit="@UpdateProfile">
    <FluentValidator TValidator="InputModelValidator" />
    <div class="form-row">
        <div class="form-group col-md-6">
            <h2>Manage Profile</h2>
        </div>
    </div>
    <div class="form-row">
        <div class="form-group col-md-4">
            <SfTextBox FloatLabelType="FloatLabelType.Auto" Placeholder="First Name" @bind-Value="Input.FirstName"></SfTextBox>
        </div>
        <div class="form-group col-md-4">
            <SfTextBox FloatLabelType="FloatLabelType.Auto" Placeholder="Last Name" @bind-Value="Input.LastName"></SfTextBox>
        </div>
    </div>
    <div class="form-row">
        <div class="form-group col-md-4">
            <SfTextBox FloatLabelType="FloatLabelType.Auto" Placeholder="Email Address" @bind-Value="Input.Email"></SfTextBox>
        </div>
    </div>
    <div class="form-row btn-update">
        <div class="form-group col-md-4">
            <SfButton IsPrimary="true">Update</SfButton>
            <SfToast ID="toast_customDupemail" @ref="@toastDuplicateEmail" Title="Invalid Email" Content="@toastDupEmailErrorMsg" CssClass="e-toast-danger" Timeout=6000>
                <ToastPosition X="Center" Y="Top"></ToastPosition>
             </SfToast>
        </div>
    </div>
</EditForm>

Here is my validator:

    public class InputModelValidator : AbstractValidator<InputModel>
    {
        public InputModelValidator()
        {
            
            RuleFor(e => e.FirstName).NotEmpty().WithMessage("First name is required.");
            RuleFor(e => e.LastName).NotEmpty().WithMessage("Last name is required.");
            RuleFor(e => e.Email).NotEmpty().WithMessage("Email is required.");
            RuleFor(e => e.Email).EmailAddress().WithMessage("Email is not valid.");
            RuleFor(x => x.Email).Custom((email, context) => {
                if (IsEmailValid(email) == false)
                {
                    context.AddFailure("The email is not valid.");
                }
            });
        }

        private bool IsEmailValid(string email)
        {
            var userInfo = Task.Run(async () => await utilities.GetApplicationUser().ConfigureAwait(false)).Result;

            if (string.Equals(userInfo.Email, email, StringComparison.OrdinalIgnoreCase) == true)
            {
                return true;
            }

            return false;
        }
    }

I have the initial checks for empty, and valid email and such. Those work great!

I need to add a custom message to make sure the email is not already in use.

What is the proper way to talk to the database / asp.net identity UserManager within the validator class?

I'm tried to inject my dependencies, but they are coming in null when I try that.

Thanks.

UPDATE:

Per response that this needs to happen in the handler, is something like this possible?

    public partial class ManageProfile
    {
        public InputModel Input { get; set; } = new InputModel();
        private EditContext _editContext;

        protected override async Task OnInitializedAsync() // = On Page Load
        {

            var userInfo = await utilities.GetApplicationUser().ConfigureAwait(false);

            Input = new InputModel
            {
                FirstName = userInfo.FirstName,
                LastName = userInfo.LastName,
                Email = userInfo.Email
            };

            await InvokeAsync(StateHasChanged).ConfigureAwait(false);
        }

        private async Task<EditContext> UpdateProfile()
        {
            _editContext = new EditContext(Input);
            var messages = new ValidationMessageStore(_editContext);

            messages.Clear();

            if (IsEmailValid(Input.Email) == false)
            {
                messages.Add(() => Input.Email, "Name should start with a capital.");
                _editContext.NotifyValidationStateChanged();
                return _editContext;
            }


            return _editContext;
        }

        private void ValidateFields(EditContext editContext, ValidationMessageStore messages, FieldIdentifier field)
        {
            messages.Clear();

            if (IsEmailValid(Input.Email) == false)
            {
                messages.Add(() => Input.Email, "Name should start with a capital.");
                editContext.NotifyValidationStateChanged();
            }
        }

        private bool IsEmailValid(string email)
        {
            var userInfo = Task.Run(async () => await utilities.GetApplicationUser().ConfigureAwait(false)).Result;

            if (string.Equals(userInfo.Email, email, StringComparison.OrdinalIgnoreCase) == true)
            {
                return true;
            }

            return false;
        }
    }

    public class InputModel
    {
        [Required]
        [MaxLength(250)]
        [Display(Name = "First Name", Prompt = "Enter first name")]
        public string FirstName { get; set; }

        [Required]
        [MaxLength(250)]
        [Display(Name = "Last Name", Prompt = "Enter last name")]
        public string LastName { get; set; }

        /// <summary>
        ///     This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        [Required]
        [EmailAddress]
        [Display(Name = "Email", Prompt = "Enter email")]
        public string Email { get; set; }
    }

    public class InputModelValidator : AbstractValidator<InputModel>
    {
        public InputModelValidator()
        {
            
            RuleFor(e => e.FirstName).NotEmpty().WithMessage("First name is required.");
            RuleFor(e => e.LastName).NotEmpty().WithMessage("Last name is required.");
            RuleFor(e => e.Email).NotEmpty().WithMessage("Email is required.");
            RuleFor(e => e.Email).EmailAddress().WithMessage("Email is not valid.");
        }
    }

UPDATE 3:

    public class InputModelValidator : AbstractValidator<InputModel>
    {
        public InputModelValidator(UserManager<ApplicationUser> user)
        {         
            RuleFor(e => e.FirstName).NotEmpty().WithMessage("First name is required.");
            RuleFor(e => e.LastName).NotEmpty().WithMessage("Last name is required.");
            RuleFor(e => e.Email).NotEmpty().WithMessage("Email is required.");
            RuleFor(e => e.Email).EmailAddress().WithMessage("Email is not valid.");
            //RuleFor(e => e.Email).EmailAddress().WithMessage("Email is not valid.").Must(IsEmailexist).WithMessage("{PropertyName} Is Already Exist.");
        }

        private async Task<bool> IsEmailexist(string Email)
        {
            return false;
        }
    }

I tried injecting UserManager<>, but I have this error:

Severity Code Description Project File Line Suppression State
Error CS0310 'InputModelValidator' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'TValidator' in the generic type or method 'FluentValidator' C:...\Microsoft.NET.Sdk.Razor.SourceGenerators\Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator\Areas_Identity_Pages_Account_ManageProfile_razor.g.cs 200 Active

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

生活了然无味 2025-02-18 23:00:08

检查重复的不是属性或价值验证,最好在处理程序或控制方面检查此验证

checking for duplication is not property or value validation, it's better to check this validation in handler or control-action

养猫人 2025-02-18 23:00:08

在中间件中的数据库中检查电子邮件已经存在以下流程

    public class InputModelValidator : AbstractValidator<InputModel>
     {
    private EditContext _editContext;
    public InputModelValidator(EditContext editContext)
    {
        _editContext=editContext;
        RuleFor(e => e.FirstName).NotEmpty().WithMessage("First name is required.");
        RuleFor(e => e.LastName).NotEmpty().WithMessage("Last name is required.");
        RuleFor(e => e.Email).NotEmpty().WithMessage("Email is required.");
        RuleFor(e => e.Email).EmailAddress().WithMessage("Email is not valid.").Must(IsEmailexist).WithMessage("{PropertyName} Is Already Exist.");;
    }


    private bool IsEmailexist(string Email)
    {
        return _editContext.userInfo.where(em=>em.EmailId==Email).FirstOrDefault()!=null?true:false;
    }
   }

checking email already exist in DB in middleware follow below process

    public class InputModelValidator : AbstractValidator<InputModel>
     {
    private EditContext _editContext;
    public InputModelValidator(EditContext editContext)
    {
        _editContext=editContext;
        RuleFor(e => e.FirstName).NotEmpty().WithMessage("First name is required.");
        RuleFor(e => e.LastName).NotEmpty().WithMessage("Last name is required.");
        RuleFor(e => e.Email).NotEmpty().WithMessage("Email is required.");
        RuleFor(e => e.Email).EmailAddress().WithMessage("Email is not valid.").Must(IsEmailexist).WithMessage("{PropertyName} Is Already Exist.");;
    }


    private bool IsEmailexist(string Email)
    {
        return _editContext.userInfo.where(em=>em.EmailId==Email).FirstOrDefault()!=null?true:false;
    }
   }
巴黎夜雨 2025-02-18 23:00:08

请参阅此答案: https://stackoverflow.com/a/a/a/72848675/72848675/9594249

摘要:我需要做一个自定义形式验证与荧光效果分开。

<EditForm Model="@Input" OnValidSubmit="@UpdateProfile">
    <FluentValidator TValidator="InputModelValidator" />
    <UI.Models.Other.CustomFormValidator @ref="@customFormValidator" />

https://wwww.syncfusion.com/blogs/blogs/blogs/邮政/外汇形式和形式validation.aspx

Please refer to this answer: https://stackoverflow.com/a/72848675/9594249

Summary: I needed to make a custom form validation that was seperate from FluentValidation.

<EditForm Model="@Input" OnValidSubmit="@UpdateProfile">
    <FluentValidator TValidator="InputModelValidator" />
    <UI.Models.Other.CustomFormValidator @ref="@customFormValidator" />

https://www.syncfusion.com/blogs/post/blazor-forms-and-form-validation.aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文