如何使用ASP.NET MVC手动启用jQuery验证

时间:2021-01-07 04:12:19

I'm struggling to understand some of the basics of jQuery validation as wired up with ASP.NET MVC.

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

The short version of this question is: What magic am I missing that allows the code produced by @Html.EditorFor() to perform jQuery validation, but doesn't work I try to wire up my own jQuery validation using the exact same HTML?

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

As a learning exercise (and because it mimics what I really want to do in my website) I created a new MVC 4 app in Visual Studio 2012. I added a view model:

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

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

and I modified Views\Home\Index.cshtml to create a form based on my view model like this:

我修改了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" />
}

Finally, I modified the Home controller to supply the view model to the form and to handle the associated POST, like this:

最后,我修改了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();
        }
    }
}

When I run the project, the web page displays a text box and magically validates that the user must enter a value. So far so good...

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

Now, my actual app is an online survey. It displays questions and solicits answers based on a script. My actual viewmodel contains properties that map to the text of the question, the value supplied by the user, etc. The viewmodel also contains a Boolean Required property that specifies whether or not the user must supply a value (i.e., whether or not to enable "required" validation in the View) - so this means that I need to remove the [Required] attribute on the MyStringValue property in my viewmodel and supply my own validation magic based on the Required property in the viewmodel.

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

This is where I get lost. In IE, I can see that the @html.xxx calls in the sample app (outlined above) produces this HTML for the form:

这是我迷路的地方。在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>

But I don't see any HTML elsewhere on the page that obviously references the jQuery-validation library, nor do I see the JavaScript code that enables validation, so I don't understand why this works at all.

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

Furthermore, if I remove the [Required] attribute, and hard-code the View to emit the above HTML (without the magic @html.xxx() calls) then no validation happens at all.

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

What am I missing?

我错过了什么?

2 个解决方案

#1


12  

Yes, I was missing something really fundamental.

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

The page template (_Layout.cshtml) created for a new MVC 4 project contains this code at the end of the page:

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

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

That code pulls in the jQuery library (after all of the HTML on the page has been seen by the browser) and then renders an optional "section" that can be supplied by the view. That code does not pull in the jQuery validation library.

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

ASP.NET MVC validation works without jQuery validation, but all of the validation is done in the server. The careful observer will note that, once warned that a missing string value must be supplied, client-side validation makes the warning go away by simply entering a single character in the offended text box. But without jQuery validation enabled, typing into the text box doesn't dynamically remove the warning.

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

In order to "turn on" jQuery validation for a single view, this code needs to reside somewhere in the view's cshtml file (stylistically, it wants to be at the end of the file since it will show up at the end of the HTML):

为了“打开”单个视图的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.

所以,我的问题的简短回答是在Views \ Home \ Index.cshtml文件的末尾添加上面的代码。这使得jQuery验证,魔术发生,并且不再忽略data-xxx属性。生活很好。

#2


10  

There is no magic that you are missing. The Microsoft 'unobtrusive validation' script can be used in any website that uses jquery and jquery validate. It is not tied to ASP.NET - as long as the HTML is the format that the unobtrusive script expects, then the script will work. This fiddle shows the unobtrusive script applied to a form not produced by ASP.NET.

没有你想要的魔法。 Microsoft“不显眼的验证”脚本可以在任何使用jquery和jquery验证的网站中使用。它与ASP.NET无关 - 只要HTML是不显眼的脚本所期望的格式,那么脚本就可以工作。这个小提琴显示了应用于非ASP.NET生成的表单的不显眼的脚本。

The unobtrusive script has two main tasks:

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

  1. Initialize the jquery.validate.js plugin
  2. 初始化jquery.validate.js插件
  3. Read the data-val* attributes in the markup and translate this into jquery validate rules
  4. 读取标记中的data-val *属性并将其转换为jquery验证规则

As you may have read, the markup attributes that the unobtrusive script reads are as follows

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

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

so a input field might look like this

所以输入字段可能如下所示

  <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="" />

My personal opinion of the unobtrusive script is that it falls into the category of what Steve Sanderson calls 'demoware' in his MVC book. It does some nice stuff out of the box but it hobbles jquery validate which is much easier to use on its own. I tend to delete it when I start a new project.

我对这个不引人注目的剧本的个人看法是,它属于史蒂夫桑德森在他的MVC书中称之为'demoware'的范畴。它开箱即可做出一些不错的东西,但它会让jquery验证变得更容易,而且它本身更容易使用。当我开始一个新项目时,我倾向于删除它。

#1


12  

Yes, I was missing something really fundamental.

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

The page template (_Layout.cshtml) created for a new MVC 4 project contains this code at the end of the page:

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

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

That code pulls in the jQuery library (after all of the HTML on the page has been seen by the browser) and then renders an optional "section" that can be supplied by the view. That code does not pull in the jQuery validation library.

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

ASP.NET MVC validation works without jQuery validation, but all of the validation is done in the server. The careful observer will note that, once warned that a missing string value must be supplied, client-side validation makes the warning go away by simply entering a single character in the offended text box. But without jQuery validation enabled, typing into the text box doesn't dynamically remove the warning.

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

In order to "turn on" jQuery validation for a single view, this code needs to reside somewhere in the view's cshtml file (stylistically, it wants to be at the end of the file since it will show up at the end of the HTML):

为了“打开”单个视图的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.

所以,我的问题的简短回答是在Views \ Home \ Index.cshtml文件的末尾添加上面的代码。这使得jQuery验证,魔术发生,并且不再忽略data-xxx属性。生活很好。

#2


10  

There is no magic that you are missing. The Microsoft 'unobtrusive validation' script can be used in any website that uses jquery and jquery validate. It is not tied to ASP.NET - as long as the HTML is the format that the unobtrusive script expects, then the script will work. This fiddle shows the unobtrusive script applied to a form not produced by ASP.NET.

没有你想要的魔法。 Microsoft“不显眼的验证”脚本可以在任何使用jquery和jquery验证的网站中使用。它与ASP.NET无关 - 只要HTML是不显眼的脚本所期望的格式,那么脚本就可以工作。这个小提琴显示了应用于非ASP.NET生成的表单的不显眼的脚本。

The unobtrusive script has two main tasks:

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

  1. Initialize the jquery.validate.js plugin
  2. 初始化jquery.validate.js插件
  3. Read the data-val* attributes in the markup and translate this into jquery validate rules
  4. 读取标记中的data-val *属性并将其转换为jquery验证规则

As you may have read, the markup attributes that the unobtrusive script reads are as follows

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

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

so a input field might look like this

所以输入字段可能如下所示

  <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="" />

My personal opinion of the unobtrusive script is that it falls into the category of what Steve Sanderson calls 'demoware' in his MVC book. It does some nice stuff out of the box but it hobbles jquery validate which is much easier to use on its own. I tend to delete it when I start a new project.

我对这个不引人注目的剧本的个人看法是,它属于史蒂夫桑德森在他的MVC书中称之为'demoware'的范畴。它开箱即可做出一些不错的东西,但它会让jquery验证变得更容易,而且它本身更容易使用。当我开始一个新项目时,我倾向于删除它。