Как вручную включить проверку JQuery с помощью ASP.NET MVC

Я пытаюсь понять некоторые основы проверки jQuery, связанные с ASP.NET MVC.

Краткая версия этого вопроса: Какую магию я пропускаю, чтобы код, созданный @Html.EditorFor(), выполнял проверку jQuery, но не работает. Я пытаюсь подключить мою собственную проверку jQuery с использованием того же самого HTML?

Как учебное упражнение (и потому, что оно имитирует то, что я действительно хочу делать на моем сайте), я создал новое приложение MVC 4 в Visual Studio 2012. Я добавил модель представления:

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();
        }
    }
}

Когда я запускаю проект, веб-страница отображает текстовое поле и волшебным образом подтверждает, что пользователь должен ввести значение. Пока что так хорошо...

Теперь мое фактическое приложение - онлайн-опрос. Он отображает вопросы и запрашивает ответы на основе script. Моя реальная модель просмотра содержит свойства, которые сопоставляются с текстом вопроса, значением, предоставленным пользователем, и т.д. Модель viewmodel также содержит свойство Boolean Required, которое указывает, должен ли пользователь указывать значение (то есть, включать или нет "требуемая" проверка в представлении), поэтому это означает, что мне нужно удалить атрибут [Required] в свойстве MyStringValue в моей модели просмотра и предоставить свою собственную мануальную проверку, основанную на обязательном свойстве в модели просмотра.

Вот где я заблудился. В 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>

Но я не вижу ни одного HTML-кода на странице, который явно ссылается на библиотеку jQuery-validation, и я не вижу код JavaScript, который позволяет проверять, поэтому я не понимаю, почему это работает вообще.

Кроме того, если я удаляю атрибут [Required] и жестко кодирую представление, чтобы испускать вышеуказанный HTML (без вызовов magic @html.xxx()), то проверка не происходит вообще.

Что мне не хватает?

Ответы

Ответ 1

Да, я упустил что-то действительно фундаментальное.

Шаблон страницы (_Layout.cshtml), созданный для нового проекта MVC 4, содержит этот код в конце страницы:

        @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")
}

Итак, короткий ответ на мой вопрос заключается в том, чтобы добавить указанный выше код в конец моего файла Views\Home\Index.cshtml. Это позволяет проверять jQuery, происходит магия, а атрибуты data-xxx больше не игнорируются. Жизнь хороша.

Ответ 2

Нет никакой магии, которой вам не хватает. "Ненавязчивая валидация" Microsoft script может использоваться на любом веб-сайте, который использует проверку jquery и jquery. Он не привязан к ASP.NET - пока HTML - это формат, который ожидает ненавязчивый script, тогда будет работать script. В этой скрипте показан ненавязчивый script, примененный к форме, не созданной ASP.NET.

У ненавязчивого script есть две основные задачи:

  • Инициализировать плагин jquery.validate.js
  • Прочитайте атрибуты data-val * в разметке и переведите это в Правила проверки jquery

Как вы, возможно, читали, атрибуты разметки, которые ненавязчивые script читают, выглядят следующим образом

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

Мое личное мнение о ненавязчивом script заключается в том, что оно относится к категории того, что Стив Сандерсон называет "demoware" в своей книге MVC. Он делает некоторые приятные вещи из коробки, но он кодирует jquery validate, который намного проще использовать сам по себе. Я стараюсь удалить его, когда я начинаю новый проект.