远程验证在 ASP.NET MVC 5 中不起作用

Posted

技术标签:

【中文标题】远程验证在 ASP.NET MVC 5 中不起作用【英文标题】:Remote validation not working in ASP.NET MVC 5 【发布时间】:2019-07-17 20:51:35 【问题描述】:

在这里,我创建了包含客户电子邮件字段的表单,我正在尝试检查输入的电子邮件是否已经退出,如果存在则显示电子邮件已存在消息。 为此,我尝试使用远程验证,但问题是即使存在电子邮件,它也没有显示任何错误,它甚至没有在用于远程验证的 IsEmailExists 方法中击中控制器 对我的代码有任何帮助都会有很大帮助。谢谢 以下是我在控制器中的操作

    public JsonResult IsEmailExists(string CustomerEmail)
    
        emedicineEntities _db = new emedicineEntities();
        return Json(!_db.Customers.Any(x => x.CustomerEmail == CustomerEmail), JsonRequestBehavior.AllowGet);
    

以下是我的元数据

namespace eMedicine.Model

    public class CustomerMetaDta
    
        [Remote("IsEmailExists", "Customers", ErrorMessage = "EmailId already exists.")]
        [Required(ErrorMessage = "Please Enter Emailw")]
        public string CustomerEmail  get; set; 
    

下面是我的部分课程

namespace eMedicine.Model

    [MetadataType(typeof(CustomerMetaDta))]
    public partial class Customer
    
    

以下是我的视图,包括客户电子邮件

<link href="~/Content/Site.css" rel="stylesheet" />
<script src="~/Scripts/jquery-3.3.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

@using (html.BeginForm("Create", "Customers", FormMethod.Post, new  @id = "register" ))

    @Html.AntiForgeryToken()
    <div class="form-horizontal">
    @Html.ValidationSummary(true, "", new  @class = "text-danger" )
    <div class="form-group">
        @Html.LabelFor(model => model.CustomerName, htmlAttributes: new  @class = "control-label col-md-2" )
        <div class="col-md-10">
            @Html.EditorFor(model => model.CustomerName, new  htmlAttributes = new  @class = "form-control"  )
            @Html.ValidationMessageFor(model => model.CustomerName, "", new  @class = "text-danger" )
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(model => model.CustomerEmail, htmlAttributes: new  @class = "control-label col-md-2" )
        <div class="col-md-10">
            @Html.EditorFor(model => model.CustomerEmail, new  htmlAttributes = new  @class = "form-control"  )
            @Html.ValidationMessageFor(model => model.CustomerEmail, "", new  @class = "text-danger" )
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(model => model.PasswordHash, htmlAttributes: new  @class = "control-label col-md-2" )
        <div class="col-md-10">
            @Html.EditorFor(model => model.PasswordHash, new  htmlAttributes = new  @class = "form-control"  )
            @Html.ValidationMessageFor(model => model.PasswordHash, "", new  @class = "text-danger" )
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
</div>

【问题讨论】:

只是一个评论:属性'[Remote]` 在服务器端验证。 @redcaper71 尝试将Remote 属性直接添加到Customer 类中的CustomerEmail,而不是使用元数据? @TanvirArjel 将在重新创建该类时消失,因此对元数据进行验证 @redcaper71 请更改方法签名如下并告诉我:public JsonResult IsEmailExists([Bind(Prefix="Customer.CustomerEmail")] string CustomerEmail) @redcaper71 有更新吗?它对你有用吗? 【参考方案1】:

如下更改您的方法签名以包含Bind Prefix 属性/属性。

public JsonResult IsEmailExists([Bind(Prefix="Customer.CustomerEmail")] string CustomerEmail)

    emedicineEntities _db = new emedicineEntities();
    return Json(!_db.Customers.Any(x => x.CustomerEmail == CustomerEmail), JsonRequestBehavior.AllowGet);

现在应该可以了!

【讨论】:

【参考方案2】:

不确定您的源代码有什么真正的问题,但我尝试在我身边重现,它运行良好。

这是我的源代码。

namespace WebApplication1.Controllers

    public class CustomerMetaDta
    
        [Remote("IsEmailExists", "Customer", ErrorMessage = "EmailId already exists.")]
        [Required(ErrorMessage = "Please Enter Emailw")]
        public string CustomerEmail  get; set; 
    

    [MetadataType(typeof(CustomerMetaDta))]
    public partial class Customer
    

    

    public partial class Customer
    
        public string CustomerEmail  get; set; 
        public string CustomerName  get; set; 
        public string PasswordHash  get; set; 
    
    public class CustomerController : Controller
    
        public JsonResult IsEmailExists(string CustomerEmail)
        
            //emedicineEntities _db = new emedicineEntities();
            List<Customer> _db = new List<Customer>
            
                new Customer  CustomerEmail  = "hien@gmail.com",
                new Customer  CustomerEmail  = "hien1@gmail.com"
            ;
            return Json(!_db.Any(x => x.CustomerEmail == CustomerEmail), JsonRequestBehavior.AllowGet);
        
        // GET: Customer
        public ActionResult Index()
        
            return View();
        
    

Index.cshtml 文件:

@model WebApplication1.Controllers.Customer

@
    ViewBag.Title = "Index";

<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.min.js"></script>

@using (Html.BeginForm("Create", "Customer", FormMethod.Post, new  @id = "register" ))

    @Html.AntiForgeryToken()
    <div class="form-horizontal">
        @Html.ValidationSummary(true, "", new  @class = "text-danger" )
        <div class="form-group">
            @Html.LabelFor(model => model.CustomerName, htmlAttributes: new  @class = "control-label col-md-2" )
            <div class="col-md-10">
                @Html.EditorFor(model => model.CustomerName, new  htmlAttributes = new  @class = "form-control"  )
                @Html.ValidationMessageFor(model => model.CustomerName, "", new  @class = "text-danger" )
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(model => model.CustomerEmail, htmlAttributes: new  @class = "control-label col-md-2" )
            <div class="col-md-10">
                @Html.EditorFor(model => model.CustomerEmail, new  htmlAttributes = new  @class = "form-control"  )
                @Html.ValidationMessageFor(model => model.CustomerEmail, "", new  @class = "text-danger" )
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(model => model.PasswordHash, htmlAttributes: new  @class = "control-label col-md-2" )
            <div class="col-md-10">
                @Html.EditorFor(model => model.PasswordHash, new  htmlAttributes = new  @class = "form-control"  )
                @Html.ValidationMessageFor(model => model.PasswordHash, "", new  @class = "text-danger" )
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>

它跳转到方法 IsEmailExists(),这是结果输出

可能是你错过了设置

<add key="ClientValidationEnabled" value="true"/>
 <add key="UnobtrusivejavascriptEnabled" value="true"/>

在 web.config 中?

【讨论】:

【参考方案3】:

如果它没有击中控制器,则表明它不是实际验证逻辑的问题,而是您如何处理服务器的问题。

有几点需要检查:

您的远程验证码是否可供客户端使用?

首先要考虑的是这是否是一个安全/身份验证问题。您可以做一些简单的事情来检查:

如果您在控制器或方法上设置了身份验证属性,请尝试将其注释掉 尝试注释掉任何其他身份验证代码

如果这不能解决问题,那么当您在调试中运行应用时,尝试使用 Postman 调用您的远程验证端点并查看是否:

邮递员从你的方法中得到了 200 的回报。 如果是这样,请在您的代码中放置一个断点并检查它是否真正被执行。

如果 Postman 可以到达您的端点,那么...

你的代码有问题吗?

我看不出您的代码中有任何明显错误,但这与我编写验证代码的方式不同。这是一个直接从我的代码中进行远程验证的示例

这是带有远程验证集的模型属性:

    [System.Web.Mvc.Remote(
        action: "CheckExistingDocumentCode",
        controller: "Documents",
        AdditionalFields = "DocumentId",
        HttpMethod = "POST",
        ErrorMessage = "Code already exists")]
    public string DocumentCode  get; set; 

这是 Documents 控制器中对应的方法:

[HttpPost]
public async Task<ActionResult> CheckExistingDocumentCode(string DocumentCode, int DocumentId)

    try
    
        if (!await _documentValidationRules.IsExistingDocumentCodeAsync(DocumentCode, DocumentId))
        
            return Json(true, JsonRequestBehavior.AllowGet);
        
        return Json("This Document Code is already in use", JsonRequestBehavior.AllowGet);
    
    catch (Exception ex)
    
        return Json(ex.ToString(), JsonRequestBehavior.AllowGet);
    

您可以看到我已经明确命名了模型属性上的所有参数,只是为了清楚到底发生了什么。

比较我的代码和你的主要区别是:

地雷异步。这应该没什么区别。 我的控制器方法是 POST(HttpPost 属性也是如此,这也意味着我需要告诉模型 HttpMethod 也是 POST) 我的远程验证方法需要两个参数,所以我通过 AdditionalFields 参数传入了一个额外的属性

我看不出你的代码有什么问题,但是尝试一次更改它以使其更像我的工作(特别是尝试将其设置为 post 方法并命名参数)并查看是否会暴露任何问题问题。

希望以上内容能让你更接近。

【讨论】:

【参考方案4】:

没有人提到会导致您的症状的一件事:如果该方法需要由匿名用户执行并且您的方法没有 AllowAnonymous 属性,则该方法将不会触发(并且提交按钮不会做任何事。

【讨论】:

您好,请阅读how to write a good answer。【参考方案5】:

您可以尝试将此代码添加到视图底部:

@section Scripts 
    @await Html.RenderPartialAsync("_ValidationScriptsPartial");

这是我遇到的问题。

【讨论】:

以上是关于远程验证在 ASP.NET MVC 5 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

为啥 jQuery 验证函数在 ASP.NET MVC Core 应用程序中不起作用?

数据注释在部分 ASP.NET MVC 中不起作用 jquery 不显眼的验证

下拉列表的 jQuery 在布局 ASP.NET MVC 5 中不起作用

ValidateInputAttribute 在 ASP.NET MVC 控制器的发布请求中不起作用

javascript的“更改”函数在asp.net mvc中不起作用

为啥捆绑包在我的 asp.net mvc 项目中不起作用?