Как редактировать несколько моделей в одном представлении Razor

Я новичок в MVC3, у меня есть несколько моделей, таких как BussinessDetails, ContactPerson, ServiceArea, Address и многие другие модели. У меня есть одна страница просмотра, где общие страницы просмотра, такие как Contacts, BusinessDetails, Address, ServiceArea и т.д. Все они находятся в виде вкладок. У них есть собственные модели.

Моя проблема заключается в том, как редактировать несколько моделей на одной странице редактирования. Перед отправкой этого сообщения я беру на себя помощь примера MVC3 "Music Store", но есть только одна модель ALBUM, и они дают операцию редактирования для одной модели, если есть одна или несколько моделей, как я буду редактировать на той же странице просмотра.

Я уже создал класс спецификации бизнес-класса. Это из 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);
}                                                                   

В HTTP POST существует только модель ALBUM, если есть больше моделей, как я выполняю операцию редактирования на нескольких моделях и просматриваю?

Ответ 1

Вам нужно включить другие ViewModels в основной CompositeModel, например так

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

Отправьте это на ваше мнение так

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

Измените свой вид, чтобы взять новый тип модели

@model CompositeModel

Чтобы ссылаться на свойства подмоделей, вы можете использовать синтаксис, подобный этому

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

или вы можете создать представление в папке EditorTemplates, в которой используется подмодель, например AlbumModel, и использовать EditorFor, как этот

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

Шаблон будет выглядеть примерно так:

@model AlbumModel

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

Теперь просто отправьте CompositeModel обратно на ваш контроллер, а затем сохраните все подмодели и теперь Боб вашего дяди!

[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
}

Ответ 2

Вам потребуется создать модель просмотра, содержащую оба типа, которые вам нужны. Что-то вроде этого (при условии, что вы редактируете как альбом, так и исполнителя):

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

Затем измените вид, чтобы использовать новую модель следующим образом:

@model MyModel

Затем измените метод Get на что-то вроде:

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);
}  

Затем измените метод Post, чтобы взять тип 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);
}      

Предполагая, что ваш вид имеет что-то вроде (завернутый в форму с кнопкой отправки, конечно):

@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)

Ответ 3

Один альтернативный способ - использовать С# Tuples
http://www.dotnetperls.com/tuple
В вашем представлении и контроллере определите кортеж, который представляет собой список ваших классов (моделей)