I'm creating an edit form for a Student model:
public class Student
{
[Key]
public virtual int ID { get; set; }
[Required]
public virtual StudentGuardian Guardian { get; set; }
}
This Student has a StudentGuardian instance inside, the StudentGuardian has validation attributes on Name, Sex ... etc
public class StudentGuardian
{
[Key]
public virtual int ID { get; set; }
[Required]
public virtual string Name { get; set; }
[Required]
public virtual string MobilePhone { get; set; }
[Required]
public virtual Sex Sex { get; set; }
}
But at Student edit form I'm only interested in GuardianId. The point is when creating an edit form and make something like that in the form:
@Html.DropDownListFor(x => x.Student.Guardian.ID, <GUARDIANS_LIST>)
and since the Guardian object is required at Student model, so the MVC validation is asking me to enter Guardian.Name and Guardian.MobilePhone and etc,
How can I just enforce the validation to be Guardian.Id only not the entire object?
The sole idea of keeping StudentGuardian
in Student
is to create a 1-to-1 relationship between Student
and StudentGuardian
classes and not for rendering data to the view
. By your approach you will be getting errors not only while editing the student entity but also while creating it. Trying using a view model as others have recommended. The following is just an attempt to help you understand better.
public class StudentViewModel
{
public int StudentId { get; set; }
public string Name { get; set; }
//..other member variables..
[Display(Name="Guardian"]
public int GuardianId { get; set; }
public virtual IEnumerable<StudentGuardian> Guardians { get; set; }
}
And then in your Edit
Action of your Controller
[HttpGet]
public ActionResult Edit(int id = 0)
{
Student student = db.Students.Find(id);
var model = new StudentViewModel();
model.Name = student.Name;
model.Guardians = db.Guardians.ToList();
//or if using repository then call the method that fetches
//.. you the list of objects
//..and bind it to the StudentViewModel instance created.
//Other Properties you need..fetch and assign them here..
//model.StudentId= student.Id; ... etc
if (student == null)
{
return HttpNotFound();
}
return View(model); // return the viewModel instance.
}
Bind your Edit View
with the StudentViewModel
as well.
@model MvcApplication.Models.ViewModels.StudentViewModel
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Student</legend>
@Html.HiddenFor(model => model.StudentId)
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.GuardianId)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.GuardianId)
@Html.DropDownListFor(model => model.GuardianId, new SelectList(Model.Guardians, "GuardianId", "GuardianName"),"Select")
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
Receive the data back on a reference of StudentViewModel
class
[HttpPost]
public ActionResult Edit(StudentViewModel model)
{
//..do whatever..Save to Database or something else..
}
Try googling for ViewModels, you will get numerous resources.