ASP.NET 基于 Select 选项的带有自定义域的核心 MVC 自定义电子邮件验证

ASP.NET Core MVC Custom Email Validation with Custom Domains Based on Select Option

我正在使用 ASP.NET 核心 MVC 开发注册系统。我有一个 Select 字段,提示用户 select 他在哪家公司工作(例如 Microsoft、IBM),并且根据他的选择,我想根据该选择验证用户输入的电子邮件域.

例如: 如果用户选择微软那么邮件域必须是@microsoft.com,如果他选择IBM那么邮件域必须是@ibm.com.

我认为这不能使用 Regex 来完成,因为我有两个相关字段。最有可能的是,它需要通过实施自定义验证属性来完成,但我不知道如何从两个字段中捕获两个值并进行比较。

表单代码:

 <div class="row">
        <div class="col-md-6">
            <div class="form-group">
                <label asp-for="Input.Email"></label>
                <input asp-for="Input.Email" class="form-control" />
                <span asp-validation-for="Input.Email" class="text-danger"></span>
            </div>
        </div>

        <div class="col-md-6">
            <div class="form-group">
                <label asp-for="Input.Company"></label>
                <select asp-for="Input.Company" class="form-control">
                    <option value="">Please Choose a Company</option>
                    <option value="ibm" email-domain="ibm.com">IBM/option>
                    <option value="microsoft" email-domain="microsoft.com">Microsoft</option>
                    <option value="apple" email-domain="apple.com">Apple</option>
                </select>
                <span asp-validation-for="Input.Company" class="text-danger"></span>
            </div>
        </div>
    </div>

请注意,如果有帮助,我添加了自定义 HTML 属性 email-domain

Register.cshtml:

    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    public string Email { get; set; }

    [Required(ErrorMessage = "Please choose which Company you are working for")]
    [DataType(DataType.Text)]
    [Display(Name = "Company")]
    public string Company{ get; set; }

正如我所说,我认为 Regex 对此没有帮助,我认为它需要一个自定义验证属性,但我不知道如何针对这个用例实施它。

我还是ASP.NET

的新手

提前致谢!!

据我所知,您不能使用模型验证,即使尝试使用远程验证,它也将只对特定的 属性 有效,您将无法获得其他列的值那个方法。所以根据我的理解,你需要在Jquery或者提交按钮的代码中实现它。

这是一个工作演示:

public class Register
    {
        public Input Input { get; set; }
    }
    public class Input
    {
        [Required]
        [Remote(action: "VerifyEmail", controller: "B", AdditionalFields = nameof(Company))]
        [Display(Name = "Email")]
        public string Email { get; set; }
        [Required(ErrorMessage = "Please choose which Company you are working for")]
        [DataType(DataType.Text)]
        [Display(Name = "Company")]
        public string Company { get; set; }
    }

查看:

@model Register
<form method="post">
    <div class="row">
        <div class="col-md-6">
            <div class="form-group">
                <label asp-for="Input.Email"></label>
                <input asp-for="Input.Email" class="form-control" />
                <span asp-validation-for="Input.Email" class="text-danger"></span>
            </div>
        </div>

        <div class="col-md-6">
            <div class="form-group">
                <label asp-for="Input.Company"></label>
                <select asp-for="Input.Company" class="form-control">
                    <option value="">Please Choose a Company</option>
                    <option value="ibm" email-domain="ibm.com">IBM</option>
                    <option value="microsoft" email-domain="microsoft.com">Microsoft</option>
                    <option value="apple" email-domain="apple.com">Apple</option>
                </select>
                <span asp-validation-for="Input.Company" class="text-danger"></span>
            </div>
        </div>
    </div>
    <input type="submit" value="submit" />
</form>
@section scripts{ 
    <partial name="_ValidationScriptsPartial" />
}

操作:

[AcceptVerbs("GET", "POST")]
        public IActionResult VerifyEmail(Register register)
        {
            var s = "@" + register.Input.Company + ".com";
            if (!register.Input.Email.EndsWith(s))
            {
                return Json("The email address is not corresponding to the company.");
            }

            return Json(true);
        }

结果:

我通过以下方法成功解决了这个问题。

首先:将自定义 HTML 属性 email-domain 添加到 select HTML 标签

中的选项
            <select asp-for="Input.Company" class="form-control" id="company-name">
                <option value="">Please Choose a Company</option>
                <option value="ibm" email-domain="ibm.com">IBM</option>
                <option value="micrososft" email-domain="microsoft">Microsoft</option>
                <option value="apple" email-domain="apple">Apple</option>
                <option value="nic" email-domain="nic.gov.us">National Information Center</option>
            </select>

然后添加此自定义属性后,这是一个更动态的解决方案,因为并非所有公司的电子邮件域都与其自己的名称相同。 我们将读取电子邮件输入并通过 @ 符号拆分域,然后将用户输入域与 selected 选项 email-domain.

进行比较
/*
 * Read email input from the corresponding field
 * Take the domain by splitting the email into two parts
 * Read company input from the corresponding field
 * Read company email domain custom attribute
 * Validate email domain with the chosen company
 */
$(document).ready(function () {
    $('#register-button').click(function () {
        // read email input from field by ID
        var email = $('#user-email').val()
        // split the domain
        // @@ is escape character in C# it will be rendered as single at
        var splittedEmail = email.split('@@')
        // read the domain after the at sign
        var userDomain = splittedEmail[1]
        // read chosen company email domain by accessing custom attribute
        var companyEmail= $('#company-name option:selected').attr('email-domain')
        // compare email domain with selected hospital
        if (!(userDomain.toLowerCase() === comapnyEmail.toLocaleLowerCase())) {
            // display the hidden div that contains the error message
            $('#email-validation-error').show()
            // prevent submitting
            return false
        } else {
            // submit form
            return true
        }
    })
  
})

我添加了一个隐藏的 div 会在未匹配的情况下显示

<div class="text-danger" id="email-validation-error" style="display: none;">Email does not Match Company Domain</div>