Reputation: 512
I am trying to understand partial views in MVC... What I am trying to accomplish is to have a master View which renders, say, two partial views. Each partial view contains a different ViewModel (with DataAnnotations). When I submit the form of one of those partial views, in case there is a server-side validation error, I would like to have the master View show up again with the validation messages on that partial.
Any tips in the right way would be deeply appreciated.
Upvotes: 1
Views: 5855
Reputation: 17182
Here you go with the sample solution -
Let create a complex model in following way -
public class Person
{
public Contact contact { get; set; }
public Vehicle vehicle { get; set; }
}
public class Contact
{
[Required]
public string Email { get; set; }
}
public class Vehicle
{
[Required]
public string Name { get; set; }
}
Then lets create a Main controller with an Index action in following way, this action is going to create a simple dummy model and bind it to the Index view -
public class MainController : Controller
{
public ActionResult Index()
{
Person p = new Person();
p.contact = new Contact();
p.vehicle = new Vehicle();
return View(p);
}
}
And Index view is going to be -
@model MVC.Controllers.Person
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@using (Html.BeginForm("Submit","Main",FormMethod.Post))
{
@Html.EditorFor(x => x.contact, "~/Views/Main/EditorTemplates/Contact.cshtml")
@Html.EditorFor(x => x.vehicle, "~/Views/Main/EditorTemplates/Vehicle.cshtml")
<input type="submit" value="click"/>
}
Here in the above view, instead of using Partial Views, I used Editor Views. Reason is that Partial views gives very hard experience in Model binding the Complex models.
So I created EditorTemplated folder in Main View folder and placed following files in there.
Contact.cshtml -
@model MVC.Controllers.Contact
@Html.LabelFor(model => model.Email, new { @class = "control-label col-md-2" })
@Html.EditorFor(model => model.Email)
@Html.ValidationMessageFor(model => model.Email)
Vehicle.cshtml -
@model MVC.Controllers.Vehicle
@Html.LabelFor(model => model.Name, new { @class = "control-label col-md-2" })
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
With the above setup, we can go and run the application and following screen should show up -
And this form is going to POSTed to Submit Action of Main controller, so this is going to be my submit action -
public ActionResult Submit(Person p)
{
if (!ModelState.IsValid)
return View("Index", p);
else
{
// do something
return View();
}
}
When we click button without entering any value, then validation will trigger and we should see error messages as below -
And in normal valid situations, you can submit the form and then run your business logic.
Upvotes: 2