Cómo editar varios modelos en una sola Vista Razor

Soy nuevo en MVC3, tengo múltiples modelos como BussinessDetails , ContactPerson , ServiceArea , Address y muchos más modelos. Tengo una sola página de vista donde las páginas de vista compartida como Contacts , Detalles de BusinessDetails , Address , Áreas de servicio, etc. están todas en tabs. Ellos tienen sus propios modelos.

Mi problema es cómo editar varios modelos en una misma página de vista de edición. Antes de enviar esta publicación, tomo la ayuda del ejemplo MVC3 “Tienda de música”, pero solo hay un modelo ALBUM y dan operación de edición para un modelo si hay uno o más modelos que debo editar en la misma página de vista.

Ya he hecho una clase de especificación de negocio para padres. Esto es de MVC “Music Store”

 public ActionResult Edit(int id) { Album album = db.Albums.Find(id); ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name", album.GenreId); ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name", album.ArtistId); return View(album); } [HttpPost] public ActionResult Edit(Album album) { if (ModelState.IsValid) { db.Entry(album).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name", album.GenreId); ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name", album.ArtistId); return View(album); } 

En HTTP POST solo hay en el modelo ALBUM si hay más modelos de cómo estoy realizando la operación de edición en varios modelos y vista?

Necesita incluir los otros Modelos de Vista en un Modelo CompositeModel principal como tal

 public class CompositeModel { public Album AlbumModel { get; set; } public Another AnotherModel { get; set; } public Other EvenMore { get; set; } } 

Envía eso a tu vista como tal

 public ActionResult Index() { var compositeModel = new CompositeModel(); compositeModel.Album = new AlbumModel(); compositeModel.OtherModel = new AnotherModel(); compositeModel.EvenMore = new Other(); return View(compositeModel) } 

Modifique su vista para tomar el nuevo tipo de modelo

 @model CompositeModel 

Para referirse a las propiedades de los submodelos, puede usar una syntax como esta

 @Html.TextBoxFor(model => model.Album.ArtistName) 

o puede crear una vista en la carpeta EditorTemplates que tome un submodelo como AlbumModel y use EditorFor como este

 @Html.EditorFor(model => model.Album) 

La plantilla se vería algo como esto

 @model AlbumModel @Html.TextBoxFor(model => model.AlbumName) @Html.TextBoxFor(model => model.YearReleased) @Html.TextBoxFor(model => model.ArtistName) 

Ahora solo devuelve CompositeModel a tu controlador y luego guarda todos los submodelos y ahora Bob es tu tío.

 [HttpPost] public ActionResult Index(CompositModel model) { // save all models // model.Album has all the AlbumModel properties // model.Another has the AnotherModel properties // model.EvenMore has the properties of Other } 

Tendrá que crear un modelo de vista que contenga los dos tipos que necesita. Algo así (suponiendo que está editando un álbum y un artista):

 public class MyModel { public Album Album { get; set; } public Artist Artist { get; set; } public SelectList Genres { get; set; } public SelectList Artists{ get; set; } } 

Luego cambie su vista para usar el nuevo modelo de esta manera:

 @model MyModel 

Luego cambie su método Get para que sea algo así como:

 public ActionResult Edit(int id) { var model = new MyModel(); model.Album = db.Albums.Find(id); model.Artist = yourArtist; //whatever you want it to be model.Genres = new SelectList(db.Genres, "GenreId", "Name", model.Album.GenreId); model.Artists = new SelectList(db.Artists, "ArtistId", "Name", model.Album.ArtistId); return View(model); } 

A continuación, cambie su método de publicación para tomar el tipo de MyModel :

 [HttpPost] public ActionResult Edit(MyModel model) { if (ModelState.IsValid) { //save your items here db.SaveChanges(); return RedirectToAction("Index"); } model.Genres = new SelectList(db.Genres, "GenreId", "Name", model.Album.GenreId); model.Artists = new SelectList(db.Artists, "ArtistId", "Name", model.Album.ArtistId); return View(album); } 

Suponiendo que su vista tiene algo así como (envuelto en un formulario con un botón de enviar por supuesto):

 @Html.EditorFor(m => m.Artist.Name) //do this for all Artist Fields @Html.EditorFor(m =? m.Album.Name) //do this for all Album Fields //the following two show you how to wire up your dropdowns: @Html.DropDownListFor(m => m.Album.ArtistId, Model.Artists) @Html.DropDownListFor(m => m.Album.GenreId, Model.Genres) 

Una forma alternativa es usar C # Tuples
http://www.dotnetperls.com/tuple
En su vista y controlador, defina una tupla que sea una lista de sus clases (modelos)