MVC 中的视图模型和对象操作
本文关键字:对象 操作 模型 视图 MVC | 更新日期: 2023-09-27 18:36:28
我想了解(并最终欣赏,因为现在只是痛苦......)MVC中更多的ViewModels和强类型视图。
我的视图模型
public class Combined
{
public IEnumerable<Domain> Domains { get; set; }
public IEnumerable<RegInfo> RegInfos { get; set; }
public Combined(IEnumerable<Domain> domains, IEnumerable<RegInfo> reginfos)
{
this.Domains = domains;
this.RegInfos = reginfos;
}
在控制器中,我将数据从存储库传递到组合类型的对象。
public ActionResult RegDetails(int id = 0)
{
var domain = from x in unitofwork.DomainRepository.Get(n => n.ID == id)
select x;
var reginfo = from y in unitofwork.ReginfoRepository.Get(n => n.ID == id)
select y;
var regdetails = new Combined(domain, reginfo);
return View(regdetails);
}
在视图(使用Razor)中,我@model project.namespace.Combined ,所以我传递了一个包含两个列表的对象。
1/为什么我无法访问这样的每个列表项@Model.Domain.Name(菜鸟问题,但请帮助我理解其背后的逻辑)?我可以使用join从视图"级别"中做到这一点,但这完全违背了MVC模式。我认为连接这两个表的唯一位置是在控制器中,但它将创建全新的对象,所以我需要为它创建一个模型吗?
2/获取一个 IEnumerable 对象的最佳方法是什么,该对象将保存来自 2 个或更多可用于填充视图(连接、自动映射器)的表的数据?
3/有没有一种方法可以让我创建一个模型,我可以使用它从一个表单发布到多个表?
提前谢谢。
控制器操作中获取实体的逻辑很好;这是控制器的工作。但是,您不需要视图模型上的自定义构造函数:只需使用对象初始化即可。
var regdetails = new Combined { Domains = domain, RegInfos = reginfo }
现在,就视图模型而言,Domains
和RegInfos
IEnumerable
,但您只为每个对象获取一个对象。如果您打算使用列表类型,则应修改 LINQ 以选择多个项,但如果您的意图实际上是每个项只有一个对象,则不应在视图模型中使用 IEnumerable
s。
public class Combined
{
public Domain Domain { get; set; }
public RegInfo RegInfo { get; set; }
}
如果这样做,则只需@Model.Domain.Name
即可访问Domain
实例上的Name
属性。但是,如果保留列表类型,则必须在视图中遍历它们(即使列表中只有一个项目):
@foreach (var domain in Model.Domains)
{
// Do something with domain.Name
}
您的视图中确实有一个模型属性,您可以像在 c# 中一样使用 Domains 和 RegInfos 属性。例如:
@{
var firstDomain = Model.Domains.FirstOrDefault();
// do some process with this variable
}
或:
@foreach(var regInfo in Model.RegInfos)
{
// do some other process
}
如果显示的数据来自各种数据源,则最好创建特定的视图模型。您需要避免在视图中进行计算或应用业务规则,在此之前应预先格式化数据。另一个好处是只将所需的数据传递给您的视图:您不想仅从数据库中获取 2 个显示属性的巨大对象(或集合)。
提交表单时也可以使用该视图模型。如果您的发布操作具有视图模型类型的参数,并且如果您在视图中正确生成输入(通过使用一些 HtmlHelper,如 Html.Editor(For) 等),则可以将其取回。
无论如何,关于强类型视图有很多话要说,并且可以在网络上找到许多资源/教程。