【问题标题】:ASP.NET MVC - prevent submit of invalid form using jQuery unobtrusive validationASP.NET MVC - 使用 jQuery 不显眼验证防止提交无效表单
【发布时间】:2017-02-16 13:15:00
【问题描述】:

我有一个 ASP.NET 项目,它使用 jQuery.Validate 和 ASP.NET 构建的 unobtrusive wrapper 自动连接客户端验证。

a) 我肯定有合适的库:jquery.js, jquery.validate.js, & jquery.validate.unobtrusive.js

b) 并且 MVC 渲染引擎肯定是开启的(ClientValidationEnabled & UnobtrusiveJavaScriptEnabled 在 web.config 的 appSettings 部分)

这是一个简单的例子:

型号

public class Person
{
    [Required]
    public string Name { get; set; }
}

控制器

public ActionResult Edit()
{
    Person p = new Person();
    return View(p);
}

查看

@model validation.Models.Person

@using (Html.BeginForm()) {
    @Html.ValidationSummary(false)

    @Html.LabelFor(model => model.Name)
    @Html.EditorFor(model => model.Name)
}

这会生成以下客户端标记:

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.15.1/jquery.validate.js"></script>
<script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.js"></script>
    
<form action="/Person" method="post">
  <div class="validation-summary-valid" data-valmsg-summary="true">
    <ul><li style="display:none"></li></ul>
  </div>
  <label for="Name">Name</label>
  <input data-val="true" data-val-required="The Name field is required." id="Name" name="Name" type="text" value="" />
  <input type="submit" value="Save" />
</form>

运行时它会执行客户端验证,注意到某些表单元素是无效的,但随后回传到服务器。

为什么它不能阻止状态无效的表单的回发?

【问题讨论】:

    标签: asp.net asp.net-mvc jquery-validate unobtrusive-validation


    【解决方案1】:

    问题

    事实证明,当您没有为给定的表单元素包含 @Html.ValidationMessageFor 占位符时,就会发生这种情况。

    以下是对问题发生位置的深入探讨:

    当表单提交时,jquery.validate.js 会调用以下方法:

    validate: function( options ) {
      form: function() {
        showErrors: function(errors) {
          defaultShowErrors: function() {
            showLabel: function(element, message) {
              this.settings.errorPlacement(label, $(element) )
    

    errorPlacement 将在jquery.validate.unobtrusive.js 中调用此方法:

    function onError(error, inputElement) { 
       var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
           replace = $.parseJSON(container.attr("data-valmsg-replace")) !== false;
    

    当我们不为验证消息添加占位符时,$(this).find(...) 将找不到任何东西。

    意思是container.attr("data-valmsg-replace") 将返回undefined

    当我们尝试在未定义的值上调用$.parseJSON 时,这会带来一个问题。如果一个错误被抛出(并且没有被捕获),JavaScript 将停止在它的轨道上并且永远不会到达阻止表单提交的原始方法 (return false) 中的最后一行代码。

    解决方案

    升级 jQuery Validate Unobtrusive

    Newer versions of jQuery Validate 更好地处理这个问题并在将它们传递给$.parseJSON 之前检查空值

    function onError(error, inputElement) {  // 'this' is the form element
        var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
            replaceAttrValue = container.attr("data-valmsg-replace"),
            replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;
    

    添加 ValidationMessageFor

    为了解决核心问题,对于表单上的每个输入,请确保包括:

    @Html.ValidationMessageFor(model => model.Name)
    

    这将呈现以下客户端标记

    <span class="field-validation-valid" data-valmsg-for="Name" data-valmsg-replace="true"></span>
    

    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.15.1/jquery.validate.js"></script>
    <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.js"></script>
        
    <form action="/Person" method="post">
      <div class="validation-summary-valid" data-valmsg-summary="true">
        <ul><li style="display:none"></li></ul>
      </div>
      <label for="Name">Name</label>
      <input data-val="true" data-val-required="The Name field is required." id="Name" name="Name" type="text" value="" />
      <span class="field-validation-valid" data-valmsg-for="Name" data-valmsg-replace="true"></span>
      <input type="submit" value="Save" />
    </form>

    【讨论】:

      猜你喜欢
      • 2011-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-20
      • 2018-09-29
      • 1970-01-01
      • 2011-12-22
      • 1970-01-01
      相关资源
      最近更新 更多