Reputation: 555
I have these models and a view model. When form posting to create the entries, the selected value for WardID
and DoctorID
becomes zero in the controllers POST method.
View code
@model NewClient.HospitalMgt.ViewModel.PatientAdmissionViewModel
....
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<div class="editor-label">
@Html.LabelFor(model => model.Admission.WardID, "Ward")
</div>
<div class="editor-field">
@Html.DropDownList("WardID", String.Empty)
@Html.ValidationMessageFor(model => model.Admission.WardID)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Admission.DoctorID, "Doctor")
</div>
<div class="editor-field">
@Html.DropDownList("DoctorID", String.Empty)
@Html.ValidationMessageFor(model => model.Admission.DoctorID)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Patient.PatientName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Patient.PatientName)
@Html.ValidationMessageFor(model => model.Patient.PatientName)
</div>
.... //more controls for properties of Patient
<div class="editor-label">
@Html.LabelFor(model => model.Admission.AdmissionNumber)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Admission.AdmissionNumber)
@Html.ValidationMessageFor(model => model.Admission.AdmissionNumber)
</div>
.... //more controls for properties of Admission
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
Controller code
public ActionResult Create()
{
ViewBag.WardID = new SelectList(db.Wards, "WardID", "WardNumber");
ViewBag.DoctorID = new SelectList(db.Doctors, "DoctorID", "DoctorName");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(PatientAdmissionViewModel Id)
{
if (ModelState.IsValid)
{
var c = new Patient()
{
Address = Id.Patient.Address,
ContactNumber = Id.Patient.ContactNumber,
EmergencyContact = Id.Patient.EmergencyContact,
PatientName = Id.Patient.PatientName,
};
var a = new Admission()
{
AdmissionNumber = Id.Admission.AdmissionNumber,
AdmissionDate = Id.Admission.AdmissionDate,
**WardID = Id.Admission.WardID, //becomes zero
DoctorID = Id.Admission.DoctorID //becomes zero**
};
db.Patients.Add(c);
db.Admissions.Add(a);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.WardID = new SelectList(db.Wards, "WardID", "WardNumber", Id.Admission.WardID);
ViewBag.DoctorID = new SelectList(db.Doctors, "DoctorID", "DoctorName", Id.Admission.DoctorID);
return View(Id);
}
Models and View models
//[NotMapped]
public class PatientAdmissionViewModel
{
public Patient Patient { get; set; }
public Admission Admission { get; set; }
}
public class Patient
{
public int PatientID { get; set; }
[Required(ErrorMessage = "A Patient Name is required")]
public string PatientName { get; set; }
public string Address { get; set; }
[Required(ErrorMessage = "A Contact Number is required")]
public string ContactNumber { get; set; }
public string EmergencyContact { get; set; }
public virtual Ward Ward { get; set; }
}
public class Admission
{
public int AdmissionID { get; set; }
public string AdmissionNumber { get; set; }
public Nullable<int> PatientID { get; set; }
public int WardID { get; set; }
public int DoctorID { get; set; }
public System.DateTime AdmissionDate { get; set; }
public virtual Ward Ward { get; set; }
public virtual ICollection<PatientPayment> PatientPayments { get; set; }
}
Upvotes: 4
Views: 15673
Reputation: 823
instead of this
@Html.DropDownList("WardID", String.Empty)
@Html.DropDownList("DoctorID", String.Empty)
use this on view
@Html.DropDownListFor(model => model.Admission.WardID, (SelectList)ViewBag.WardID, "--Select One--")
@Html.DropDownListFor(model => model.Admission.DoctorID, (SelectList)ViewBag.DoctorID, "--Select One--")
use this on controller
WardID = Id.Admission.WardID,
DoctorID = Id.Admission.DoctorID
Upvotes: 0
Reputation:
You use of @Html.DropDownList("WardID", String.Empty)
and @Html.DropDownList("DoctorID", String.Empty)
are generating inputs with name="WardID"
and name="DoctorID"
respectively, but you model does not contain properties with those names (it does however contain a property named Admission
which contains those properties).
You 'view model' is not really a view model (a view model should not contain properties which are data models when editing). Your view model should also contain properties for the SelectList
's so that you can strongly bind to your model. Your view model needs to be
public class PatientAdmissionViewModel
{
[Display(Name = "Ward"]
[Required(ErrorMessage = "Please select a ward")]
public int? SelectedWard { get; set; }
[Display(Name = "Doctor"]
[Required(ErrorMessage = "Please select a doctor")]
public IEnumerable<SelectListItem> WardList { get; set; }
public int? SelectedDoctor { get; set; }
public IEnumerable<SelectListItem> DoctorList { get; set; }
public string PatientName { get; set; }
... // other properties of Patient that you need in the view
public string AdmissionNumber{ get; set; }
... // other properties of Admission that you need in the view
}
and in the GET method, initialize an instance of the view model, set its properties and return it to the view
public ActionResult Create()
{
var model = new PatientAdmissionViewModel()
{
WardList = new SelectList(db.Wards, "WardID", "WardNumber"),
DoctorList = new SelectList(db.Doctors, "DoctorID")
};
return View(model);
}
and in the view
@Html.DropDownListFor(m => m.SelectedWard, Model.WardList, "-Please select-")
....
@Html.DropDownListFor(m => m.SelectedDoctor, Model.DoctorList, "-Please select-")
and finally, in the POST method, you initialize new instances of your data models, set their properties based on the values in the view models and save the data models.
I also recommend you read the answers to What is ViewModel in MVC?.
Upvotes: 2