Well, after some research, I could not understand the "viewmodel".
I have not found articles that explain to me what steps should be taken with ViewModels compared to just passing Entity as a model for the view. Using pure Entity is pretty straight forward:
When creating a new record, just show the view. If there is a message, confirm, add (x) and voilá! When editing, populate the object and send it to the view. When publishing, checking, changing state and saving. This is no secret.
But I can not create and edit ViewModels. Can someone help me with this?
To be short, I have these POCOs:
public class Vessel { public int Id { get; set; } [Required] public string Name { get; set; } public int ShipownerId { get; set; } public virtual Shipowner Shipowner { get; set; } } public class Shipowner { public int Id { get; set; } public string Name { get; set; } public virtual ICollection<Vessel> Vessels { get; set; } }
And this view:
@model INTREPWEB.Models.VesselCreateViewModel @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset> <legend>Vessel</legend> <div class="editor-label"> @Html.LabelFor(model => model.Vessel.Name) </div> <div class="editor-field"> @Html.EditorFor(model => model.Vessel.Name) @Html.ValidationMessageFor(model => model.Vessel.Name) </div> <div class="editor-field"> @Html.DropDownListFor(model => model.Vessel.ShipownerId, Model.Shipowners, String.Empty) @Html.ValidationMessageFor(model => model.Vessel.Name) </div> <p> <input type="submit" value="Create" /> </p> </fieldset> }
I created this ViewModel:
public class VesselCreateViewModel { public Vessel Vessel { get; set; } public SelectList Shipowners { get; set; } public VesselCreateViewModel() { using (INTREPDB db = new INTREPDB()) { var list = db.Shipowners.ToList() .Select(x => new SelectListItem { Text = x.Name, Value = x.Id.ToString() }); Shipowners = new SelectList(list, "Value", "Text"); } } public VesselCreateViewModel(int id) { using (INTREPDB db = new INTREPDB()) { Vessel = db.Vessels.Find(id); var list = db.Shipowners.ToList() .Select(x => new SelectListItem { Text = x.Name, Value = x.Id.ToString() }); Shipowners = new SelectList(list, "Value", "Text"); } } }
As you can see, it automatically fills the collection for the view to display the DropDown menu. I was able to create new vessels, doing the same as for the models. But I can’t understand what I’m doing wrong when I edit this thing.
This is the wrong POST Edit method:
[HttpPost] public ActionResult Edit(VesselCreateViewModel vm) { if (ModelState.IsValid) { db.Entry(vm.Vessel).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } return View(vm); }
What should I do to save this little monster?