MVC - создание объекта и связанных объектов за один раз

Я хочу создать родительский объект с дочерними/связанными объектами в одном представлении. Примером может служить: создать одного Отца (с некоторым именем) вместе со всеми его сыновьями (с их именами). Я создал модель представления:

public class FatherViewModel {
  public Father father {get; set;} // has 1 property Name
  public List<Son> {get; set;} // has 1 property Name
}

Мой вопрос: как мне получить список Сынов назад из представления, когда сообщение выполняется? Я попытался использовать HiddenFor для каждого идентификатора Son, но, несмотря ни на что, список пуст, когда возвращается контроллеру.

UPDATE:

Я попробовал пример шаблона редактора Shyju, описанный ниже, но мой редактор никогда не вызывается. У меня есть 1 объект:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int? FatherId { get; set; }
    public virtual ICollection<Person> Children { get; set; }
}

Я сделал это:

  • Поднимите полный контроллер для лица с индексом, создайте, отредактируйте...
  • Создана папка EditorTemplates в Views- > Person
  • Создано Person.cshtml:

    @model TestEditorTemplate.Models.Person <div> <h4>Child</h4> @Html.TextBoxFor(s => s.Name) @Html.HiddenFor(s => s.Id) </div>

  • Добавлен @Html.EditorFor(m => m.Children) в Create.cshtml

Вопросы:

  • Как @Html.EditorFor(m => m.Children) возможно работать с шаблон редактора, когда m.Children представляет собой набор Person, а не один Person?
  • Я хочу создать (не редактировать) отца, включая детей в то же время. Это означает, что у меня нет идентификаторов для перехода к Create view для начала. Как это может работать? Из примера, сделанного Shyju, идентификаторы уже созданы заранее?? Или я просто неправильно понял пример?

Ответы

Ответ 1

Для этого вы можете использовать EditorTemplates. Вот рабочий образец.

Итак, у меня есть viewmodel для представления отношения отец-ребенок

public class PersonVM
{
    public int Id { set; get; }
    public string Name { set; get; }
    public int? ParentId { set; get; }
    public List<PersonVM> Childs { set; get; }
}

И в моем методе действий GET я создаю объект своей модели представления и загружаю в него данные Father -childs.

public ActionResult EditorTmp(int id = 1)
{
    //Hard coded for demo, you may replace with actual DB values
    var person = new PersonVM {Id = 1, Name = "Mike"};
    person.Childs = new List<PersonVM>
    {
        new PersonVM {Id = 2, Name = "Scott", ParentId = 11},
        new PersonVM {Id = 2, Name = "Gavin", ParentId = 12}
    };
    return View(person);
}

Теперь я создам EditorTemplate. Для этого перейдите в папку "Представления" и создайте каталог под названием EditorTemplates в каталоге, который имеет то же имя, что и контроллер, и добавьте представление с именем PersonVM.cshtml

enter image description here

Теперь перейдите к этому представлению и добавьте нижеприведенный код.

@model ReplaceWithYourNameSpaceNameHere.PersonVM
<div>
    <h4>Childs </h4>
    @Html.TextBoxFor(s => s.Name)
    @Html.HiddenFor(s => s.Id)
</div>

Теперь вернемся к нашему основному виду. Нам нужно сделать это представление строго типизированным для нашего оригинального PersonVM. Мы будем использовать метод EditorFor html helper в этом представлении, чтобы вызвать наш шаблон редактора

@model ReplaceWithYourNameSpaceNameHere.PersonVM
@using (Html.BeginForm())
{
    <div>
        @Html.TextBoxFor(s => s.Name)
        @Html.HiddenFor(s => s.Id)
    </div>
    @Html.EditorFor(s=>s.Childs)
   <input type="submit"/>
}

Теперь у нас есть метод HttpPost для управления отправкой формы

[HttpPost]
public ActionResult EditorTmp(PersonVM model)
{
    int fatherId = model.Id;
    foreach (var person in model.Childs)
    {
        var id=person.Id;
        var name = person.Name;
    }
    // to do  : Save ,then Redirect (PRG pattern)
    return View(model);
}

Теперь, если вы поместите точку останова в свой метод действия HttpPost, вы можете увидеть, что Id дочерних элементов передается этому методу действий.

enter image description here

Важно помнить, что имя представления шаблона вашего редактора должно быть таким же, как и тип, который вы привязываете к нему.