提问人:Holland 提问时间:6/8/2017 最后编辑:Holland 更新时间:6/9/2017 访问量:1863
MVC/ASP.NET:客户端验证不起作用
MVC/ASP.NET: Client side validation not working
问:
编辑:考虑将整个问题替换为以下问题: ASP.NET/MVC:敲除绑定阻止客户端验证被执行?
在 ASP.NET/MVC 工作时,我很难让(不显眼甚至不显眼的)客户端验证正常工作。(是的,但这次是出于不同的原因。
注意:帖子底部的编辑很重要,尤其是编辑 2 和 3。
问题是,客户端验证绝对不做任何事情(见下文),即使所有成分似乎都已到位。我已经阅读了 Stack Overflow 上的很多问题和答案,似乎在我的项目中一切都正确完成,但仍然不起作用。我错过了什么?
在我的 Web.config 文件(根文件夹中的文件,而不是 View 文件夹中的文件)中,我显式启用了客户端验证:
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
所有相关的 Javascript 文件都在那里,顺序正确且加载正确(显然我没有对它们进行任何更改)。我已将它们包含在 bundle 中,在 BundleConfig 中:
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.validate.js", "~/Scripts/jquery.validate.unobtrusive.js"));
我在我的视图中添加了这些捆绑包(实际上在共享的 _Layout.cshtml 父视图中):
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryval")
@Scripts.Render("~/bundles/bootstrap")
@Scripts.Render("~/bundles/knockout")
在为 View 生成的源代码中,这些脚本(以及其他一些脚本)如下所示:
据我所知,这是正确的。(我还在同一视图的其他地方广泛使用 jQuery 和 knockout。此外,浏览器控制台中没有加载错误。
然后在我的 ViewModel 中,我有这个带注释的属性 Email(除其他外):
public class RegisterViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
// some other properties…
}
这是我的观点中相应的代码:
@Html.ValidationSummary("", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Email)
</div>
</div>
这将生成以下源代码(点击放大):
据我所知,这似乎也是正确的。
但是,当我在输入字段中输入明显不是有效电子邮件地址的内容,并使该字段失去焦点(通过跳转到下一个字段)时,会出现 NO ERROR MESSAGE。既不在摘要中,也不在电子邮件字段本身的特定错误消息中。如下图所示:
(红色小方块是 .field-validation-valid 元素,它应该包含错误消息,但不包含。出于测试目的,我用红色边框装饰了这个元素。
此外,当我按下提交按钮时,输入字段将简单地提交到服务器操作方法(然后正确确定输入无效)。但实际上,启用客户端验证后,除非客户端验证成功,否则不应进行提交。但是,这基本上就是整个问题:尽管生成了正确的 HTML(大概!
编辑1:
这是整个表单的 HTML/Razor:
@model Treinen2.Models.RegisterViewModel
@{
ViewBag.Title = "Register";
}
@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
<h4>Create a new account.</h4>
<hr />
@Html.ValidationSummary("", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Email)
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.Password, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" value="Register" />
</div>
</div>
}
这是在名为 Register.cshtml 的共享视图中,根据某些条件,通过从主视图 Index.cshtml 调用 @Html.Partial(“Register”) 来显示该视图。[我正在尝试构建一个单页 API 应用程序,作为一个练习,所以所有内容都包含在主页(索引)中,并且所有导航都发生在客户端(除了提交“注册”按钮本身的明显例外,它被发送到服务器 Action 方法,至少现在是这样)。显然,任何时候都只显示 Index.cshtml 的一个部分(“页面”),为此我使用了淘汰赛绑定。
编辑2:
好的,我注意到以下几点:如果我将相同的表单放在 Index.cshtml 中,并将相同的模型添加到该索引视图中,那么客户端验证就可以完美地工作。只有在部分视图上,它才无法正常工作。这表明我可以简单地停止使用分部视图,而只是将其内容包含在 Index.cshtml 上,如测试的那样。另一方面,我仍然不明白为什么对注册表单使用部分视图也不起作用。(有了这些新信息,我可能不得不以不同的形式重新提出这个问题,但现在没有时间......[/编辑 2]
编辑3:
看来我越来越接近理解问题的根本原因。因为现在我有了在索引视图上使用表单的验证......但是,一旦我将整个表单放入由 Knockout 属性绑定的 DIV 元素中,它就会停止工作 data-bind=“If: .....”因此,这似乎是问题的本质:客户端验证和 Knockout 绑定之间的交互。Knockout 绑定本身工作正常,但似乎阻止了验证的执行。虽然我仍然不明白为什么会这样。[/编辑 3]
那么,我错过了什么?任何建设性的建议,将在几个小时后回来查看。
答: 暂无答案
评论
Html.ValidationSummary(true, "", new { @class = "text-danger" })
EditorFor