Передача в контроллер сложной модели

Рейтинг: 0Ответов: 1Опубликовано: 20.04.2015

Существует модель имеющая связи многие ко многим. Необходимо отобразить форму так, чтобы в контроллере получить уже заполненную модель с одним связанным и заполненным объектом.

Модель:

public class Phrase
{
    public int PhraseId { get; set; }
    public string Text { get; set; }      
    public int Lang { get; set; }
    public virtual ICollection<Phrase> translates { get; set; }
}

Ответы

▲ 2Принят

Насколько я вижу у вас дерево в модели. Модель содержит список таких же моделей. Для отображения такого рода модели я предлагаю использовать EditorTemplates.

  • Создадим папку EditorTemplates во Views\Shared
  • Создадим файл Phrase.cshtml в этой папке со следующим содержанием

    @model MVCReportViewer.Controllers.Phrase
    
    <li>
    @Html.HiddenFor(x => x.PhraseId)
    @Html.TextBoxFor(x => x.Text)
    @Html.TextBoxFor(x => x.Lang)
    
    @if (Model.Translates != null && Model.Translates.Any())
    {
        <ul>
            @Html.EditorFor(x => x.Translates)
        </ul>
    }
    </li>
    
  • Тестовый контроллер метод контроллера TestEditorTemplate:

    public ActionResult TestEditorTemplate()
    {
        ViewData.Model = new List<Phrase>
        {
            new Phrase
            {
                PhraseId = 1,
                Text = "prase 1",
                Lang = 0,
                Translates = new List<Phrase>
                {
                    new Phrase
                    {
                        PhraseId = 11,
                        Text = "prase 1.1",
                        Lang = 1
                    },
                    new Phrase
                    {
                        PhraseId = 12,
                        Text = "prase 1.2",
                        Lang = 1,
                        Translates = new List<Phrase>
                        {
                            new Phrase
                            {
                                PhraseId = 121,
                                Text = "prase 1.2.1",
                                Lang = 1
                            },
                            new Phrase
                            {
                                PhraseId = 12,
                                Text = "prase 1.2.2",
                                Lang = 1
                            }
                        }
                    }
                }
            },
            new Phrase
            {
                                PhraseId = 2,
                Text = "prase 2",
                Lang = 3,
            }
        };
        return View();
    }
    
    • Тестовое представление TestEditorTemplate.cshtml

      @model IEnumerable<MVCReportViewer.Controllers.Phrase>
      
      @{
          ViewBag.Title = "TestEditorTemplate";
      }
      
      
      <ul>
          @Html.EditorForModel()
      </ul>
      

Все, у нас все есть. Наш EditorTemplate сам сконструирует правильную разметку для того чтобы наша модель верно вернулось в контроллер, если мы заходим обернуть все это в форму. Я использовал хэлпер EditorForModel, но возможно использовать и EditorFor, если ваша модель является частью общей модели.

Более того - обратите внимание что нигде нет ни одного цикла. EditorTemplate применяется даже к коллекциям причем, расставляя верные name параметры в отрендереном html.

P.S. Обратите внимание, что я несколько изменил вашу ViewModel:

public class Phrase
{
    public int PhraseId { get; set; }
    public string Text { get; set; }
    public int Lang { get; set; }
    public virtual IEnumerable<Phrase> Translates { get; set; }
}

Не имеет смысл пользоваться коллекцией ICollection поскольку она имеет преимущество перед IEnumerable только в том случае если вы части изменяете значения в коллекции. А работа с MVC такова, что вы их только пишите внутрь, не изменяя. И принимаете из реквеста.