Как создать модель сложного вида в ASP.NET MVC?

Создание и обновление модели сложного вида - это то, с чем я борюсь большую часть времени, когда я работаю над веб-проектом.

Например, я получил PageViewModel который принимает URL фонового изображения и заголовок страницы для передачи _Layout.cshtml, так

@model WebApplication.ViewModels.PageViewModel

<body background-image=@Model.BackgroundImageUrl>
   ...
</body

Что касается любой другой модели, у меня теперь есть 2 варианта:

  1. Вытекают из PageViewModel
  2. Создать недвижимость на PageViewModel хранить конкретную модель представления (композиция поверх наследования и т. д.)

По понятным причинам я более склонен к варианту 2. В любом случае, для GET действия, которые мне теперь нужно инициализировать все свойства из PageViewModel а также свойства модели представления, которые мне действительно нужны для конкретного действия, например

public PageViewModel
{
    public string BackgroundImageUrl { get; set; }
    public ContactViewModel Contact { get; set; }
}

создается как

public IActionResult Contact(int contactId)
{
   ...
   var viewmodel = new PageViewModel
   {
      BackgroundImageUrl = ...,
      ContactViewModel = new 
      {
         ...
      }
   }
}

что для меня является рецептом катастрофы.

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

public IActionResult Contact(ContactViewModel viewmodel)
{
   if (ModelState.IsValid)
   {
      ... (this is the easy case)
      return RedirectToAction(...)
   }

   ... (now we have a problem)
}

Если что-то пойдет не так в POST Действие Мне нужно перестроить весь граф модели представления, что не так уж плохо для приведенного выше примера, но в реальном приложении это очень запутанно и очень быстро (просто подумайте о заполнении выпадающих списков данными из магазина). Действия контроллера должны быть скудными, не так ли? Неправильно возлагать на модели представления ответственность за извлечение их собственных данных, поэтому, вероятно, мне следует придумать фабрику моделей представления. Это, в свою очередь, приведет к появлению множества фабрик, по одному для каждой модели представлений, что опять-таки станет беспорядочным.

Мне интересно, есть ли лучший подход.

1 ответ

Одной из возможностей для рассмотрения является использование child action ответственность за некоторую часть макета.

Например, у вас может быть следующее дочернее действие, которое будет отвечать за заполнение URL-адреса фонового изображения:

[ChildActionOnly]
public ActionResult BackgroundImage() 
{
    var model = new MyViewModel
    {
        BackgroundImageUrl = ...
    };
    return PartialView(model);
}

и затем иметь соответствующий частичный вид:

@model MyViewModel

<img src="@Model.BackgroundImageUrl" alt="" />

который может быть включен в ваш основной макет (который в этом случае не нуждается в модели представления, потому что различные ее части будут собраны из дочерних действий):

<body>
    @Html.Action("BackgroundImage", "SomeController")
    ...
</body>

При использовании этого подхода основное действие, которое отвечает за визуализацию представления, не должно знать и собирать сложную модель представления. Это будет сосредоточено только на его конкретной модели представления.

Другие вопросы по тегам