I'm struggling to understand some of the basics of jQuery validation as wired up with ASP.NET MVC.
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?
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:
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:
@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:
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.
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:
<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.
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.
What am I missing?