18

我正在努力理解与 ASP.NET MVC 连接的 jQuery 验证的一些基础知识。

这个问题的简短版本是:我错过了什么魔法,允许生成的代码@Html.EditorFor()执行 jQuery 验证,但不起作用我尝试使用完全相同的 HTML 连接我自己的 jQuery 验证?

作为学习练习(并且因为它模仿了我在网站中真正想做的事情),我在 Visual Studio 2012 中创建了一个新的 MVC 4 应用程序。我添加了一个视图模型:

using System.ComponentModel.DataAnnotations;
namespace ValidationTest.Models
{
    public class MyViewModel
    {
        [Required]
        public string MyStringValue { get; set; }
    }
}

我修改了 Views\Home\Index.cshtml 以根据我的视图模型创建一个表单,如下所示:

@model ValidationTest.Models.MyViewModel
@using (Html.BeginForm(new { id = "MyForm" })) {
    @Html.LabelFor(m => m.MyStringValue)
    @Html.EditorFor(m => m.MyStringValue)
    @Html.ValidationMessageFor(m => m.MyStringValue)

    <br />
    <input type="submit" value="Submit" />
}

最后,我修改了 Home 控制器以将视图模型提供给表单并处理相关的 POST,如下所示:

using System.Web;
using System.Web.Mvc;
using ValidationTest.Models;

namespace ValidationTest.Controllers
{
    public class HomeController : Controller
    {
        [HttpGet]
        public ActionResult Index()
        {
            var viewModel = new MyViewModel();
            return View(viewModel);
        }

        [HttpPost]
        public ActionResult Index(MyViewModel viewModel)
        {
            if (!ModelState.IsValid) return View(viewModel);

            return RedirectToAction("About");
        }

        public ActionResult About()
        {
            ViewBag.Message = "Your app description page.";
            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";
            return View();
        }
    }
}

当我运行项目时,网页会显示一个文本框并神奇地验证用户必须输入一个值。到现在为止还挺好...

现在,我的实际应用是在线调查。它根据脚本显示问题并征求答案。我的实际视图模型包含映射到问题文本的属性、用户提供的值等。视图模型还包含一个布尔必需属性,它指定用户是否必须提供一个值(即是否启用视图中的“必需”验证) - 所以这意味着我需要删除[Required]视图模型中 MyStringValue 属性上的属性,并根据视图模型中的 Required 属性提供我自己的验证魔法。

这就是我迷路的地方。在 IE 中,我可以看到示例应用程序中的 @html.xxx 调用(如上所述)为表单生成了以下 HTML:

<label for="MyStringValue">MyStringValue</label>
<input  class="text-box single-line" 
        data-val="true" 
        data-val-required="The MyStringValue field is required." 
        id="MyStringValue" 
        name="MyStringValue" 
        type="text" 
        value="" />
<span data-valmsg-for="MyStringValue" data-valmsg-replace="true"></span>

但是我在页面上的其他地方看不到任何明显引用 jQuery-validation 库的 HTML,也没有看到启用验证的 JavaScript 代码,所以我根本不明白为什么会这样。

此外,如果我删除该[Required]属性,并对 View 进行硬编码以发出上述 HTML(没有神奇的 @html.xxx() 调用),则根本不会发生验证。

我错过了什么?

4

2 回答 2

14

是的,我错过了一些非常基本的东西。

为新的 MVC 4 项目创建的页面模板 (_Layout.cshtml) 在页面末尾包含以下代码:

        @Scripts.Render("~/bundles/jquery")
        @RenderSection("scripts", required: false)
    </body>
</html>

该代码拉入 jQuery 库(在浏览器看到页面上的所有 HTML 之后),然后呈现可由视图提供的可选“部分”。该代码不会入 jQuery 验证库。

ASP.NET MVC 验证无需 jQuery 验证即可工作,但所有验证都在服务器中完成。细心的观察者会注意到,一旦警告必须提供缺失的字符串值,客户端验证只需在被冒犯的文本框中输入单个字符即可使警告消失。但是如果没有启用 jQuery 验证,在文本框中输入内容不会动态删除警告。

为了“打开”单个视图的 jQuery 验证,此代码需要驻留在视图的 cshtml 文件中的某个位置(从风格上讲,它希望位于文件的末尾,因为它将显示在 HTML 的末尾) :

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

So, the short answer to my question is to add the above code at the end of my Views\Home\Index.cshtml file. This enables jQuery validation, magic happens, and the data-xxx attributes are no longer ignored. Life is good.

于 2013-03-04T02:01:39.557 回答
11

没有你缺少的魔法。Microsoft 'unobtrusive validation' 脚本可用于任何使用 jquery 和 jquery validate 的网站。它不依赖于 ASP.NET - 只要 HTML 是不显眼的脚本所期望的格式,那么脚本就可以工作。 这个小提琴显示了应用于不是由 ASP.NET 生成的表单的不显眼的脚本

不显眼的脚本有两个主要任务:

  1. 初始化 jquery.validate.js 插件
  2. 读取标记中的 data-val* 属性并将其转换为 jquery 验证规则

您可能已经阅读过,不显眼的脚本读取的标记属性如下

data-val="true"
data-val-rulename="message"
data-val-rulename-paramname1="paramvalue"
data-val-rulename-paramname2="paramvalue"

所以输入字段可能看起来像这样

  <input
     data-val="true" 
     data-val-required="This field is required..." 
     data-val-number="Please enter a number..."
     data-val-range="Must be between 50 and 100...",
     data-val-range-min="50"
     data-val-range-max="100"
     id="mynumber" 
     name="mynumber" 
     type="text" value="" />

我个人对不显眼的脚本的看法是,它属于 Steve Sanderson 在他的 MVC 书中所说的“demoware”类别。它做了一些开箱即用的好东西,但它阻碍了 jquery validate本身更容易使用。当我开始一个新项目时,我倾向于删除它。

于 2013-02-24T17:10:52.593 回答