创建和更新复杂的视图模型是我在处理Web项目时大部分时间都在努力的方法。
例如,我有一个PageViewModel
,它会将背景图片网址和网页标题传递给_Layout.cshtml
,所以
@model WebApplication.ViewModels.PageViewModel
<body background-image=@Model.BackgroundImageUrl>
...
</body
至于其他所有视图模型,我现在有两个选项:
PageViewModel
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
动作中出现任何问题,我需要重建整个视图模型图,这对于上面的示例来说并不是太糟糕,但在现实世界的应用程序中,这会非常快速地混乱(只是想到使用来自商店的数据填充下拉列表)。控制器动作应该是精益的,不是吗?让视图模型负责检索自己的数据也是不对的,所以我应该想出一个视图模型工厂。反过来,这会产生大量的工厂,每个工厂都会看到一个工厂,这个工厂也会变得混乱。
我想知道是否有更好的方法。
答案 0 :(得分:2)
考虑的一种可能性是使用负责布局某些部分的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>
使用此方法,负责渲染视图的主要操作不需要知道和组装复杂的视图模型。它将只关注其特定的视图模型。