JQuery unobtrusive validation seems to work based on the model passed to the page - but what if I want to have more than one model in play?
Let's say "MyPage" has two forms, each posting back to a different Action, with a different model
Models
public class MyPageModel
{
public List<Student> Students { get; set; }
public List<Prof> Profs { get; set; }
[Required]
public string Student { get; set; } // wrong wrong wrong
[Required]
public string Prof { get; set; } // so wrong. this can't be the way
}
public class AddStudentModel
{
[Required]
public string Student { get; set; }
}
public class AddProfModel
{
[Required]
public string Prof { get; set; }
}
View
// MyPage!
// list students here
@using (Html.BeginForm("AddStudent", "Controller", new { }, FormMethod.Post))
{
@Html.TextBox("Student", null, new { })
@Html.ValidationMessageFor("Student")
<input type="submit" value="add student" />
}
// list professors here
@using (Html.BeginForm("AddProf", "Controller", new { }, FormMethod.Post))
{
@Html.TextBox("Prof", null, new { })
@Html.ValidationMessageFor("Prof")
<input type="submit" value="add prof" />
}
Controller
public ActionResult MyPage()
{
MyPageModel model = new MyPageModel();
// bind data here
return View(model);
}
public ActionResult AddStudent(AddStudentModel model)
{
// add student
return RedirectToAction("MyPage");
}
public ActionResult AddProf(AddProfModel model)
{
// add professor
return RedirectToAction("MyPage");
}
Up to now I've been adding empty Student
/ Prof
properties to MyPageModel
, but this feels very hacky. Is there a way to specify a model in the Html.BeginForm
that jquery validation will use?
You could use child actions for this, and remove your extra properties from your MyPageModel:
public ActionResult MyPage()
{
MyPageModel model = new MyPageModel();
// bind data here
return View(model);
}
[HttpGet]
public ActionResult AddStudent()
{
return PartialView(new AddStudentModel());
}
[HttpPost]
public ActionResult AddStudent(AddStudentModel model)
{
//add student
return RedirectToAction("MyPage");
}
Current MyPage:
//MyPage!
@Html.Action("AddStudent", "SomeController")
@Html.Action("AddProf", "SomeController")
New view returned by new child action.
//AddStudent.cshtml
@using (Html.BeginForm())
{
@Html.TextBoxFor(m => m.Student)
@Html.ValidationMessageFor(m => m.Student)
<input type="submit" value="add student" />
}
To make this a slick solution, it might be worth taking a look at Ajax.BeginForm as it'll allow you to update a form at a time on the page (and return a partial view as a reponse so a form submission doesn't need to refresh the whole page).