【问题标题】:Strongly typed-views and shared views强类型视图和共享视图
【发布时间】:2013-12-18 16:07:51
【问题描述】:

使用 Visual Studio 设置的默认 MVC 项目,我有一个 _ViewStart.cshtml 文件,它设置了一个共享的“主”视图。

我目前正在处理以下断言;只要有可能,您应该使用强类型视图,因为这样感觉更干净。 (如有错误请指正)

我正在考虑让我的共享“主”视图接受 PageModel,其中可能包含 PageTitleUserLocality 等内容。

我的所有数据模型是否都应该从PageModel 继承,以便“主”视图和不同的页面视图可以处理不同类型的模型?我只是想了解 MVC 最佳实践。

模型

public class PageModel {
    public string Title { get; set; }
}

public class DataModel : PageModel {
    public int ID { get; set; }
    public DateTime Timestamp { get; set; }
}

_Layout.cshtml

@model Namespace.Models.PageModel

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>@Model.Title - Website Name</title>
        <!-- etc etc -->

Index.cshtml

@model Namespace.Models.DataModel

编辑

假设上述方法是合理的,当“主”视图仍期待单个模型时,您将如何处理应该接受项目列表的视图?

_Layout.cshtml

@model Namespace.Models.PageModel

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>@Model.Title - Website Name</title>
        <!-- etc etc -->

Index.cshtml

@model IEnumerable<Namespace.Models.DataModel>

<table>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.ID)
        </th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.ID)
        </td>
    </tr>
}
</table>

【问题讨论】:

  • 您的模型是否来自数据库?
  • 我读过一些关于包装数据库模型而不是直接使用它们的文章

标签: c# asp.net-mvc


【解决方案1】:

因此,模型的包装实际上是创建一个视图模型,该视图模型通常包含您的模型和您可能需要的任何其他视图数据。创建视图模型基类是确保视图模型一致性的好方法。

然后您可以完全按照您的描述使用您的视图模型库(即在您的 _Layout 类中设置 @model)。

总而言之-您的方法完全没问题,只是术语可能略有不同。

编辑:19/12/2013 0 RE:基于列表的视图

处理此问题的最简单方法是将项目列表作为视图模型的属性公开 - 即不要使用 @model IEnumerable 而是创建公开 IEnumerable 的视图模型,例如:

如果你有一个 Book 类型的模型:

public class Book { ... }

还有一个视图模型(或您称之为 PageModel)的基础

public abstract class ViewModelBase { 
    public string Title { get; set; }
}

你会有这样的视图模型:

public class BooksViewModel : ViewModelBase {
    public IEnumerable<Namespace.Models.DataModel> Books { get; set;}
}

【讨论】:

  • 对不起,这是一个相关的后续,您应该如何使用这种方法处理列表视图? (见问题编辑)
【解决方案2】:

我已经看到了很多不同的方法,这真的取决于项目。

一种方法是将视图配置中的&lt;pages pageBaseType="CustomWebViewPage"&gt; 设置为继承System.Web.Mvc.WebViewPage 的类,并使用User 模型或其他特定于域的全局属性扩展自定义类。

我更喜欢从ViewBag 覆盖页面标题,因为它在简单页面上提供了更大的灵活性。

【讨论】:

  • 我发现自己同情那些不鼓励使用 ViewBag 的人,主要是因为无法控制其中可以放置什么
【解决方案3】:

只是不要输入您的ViewModel 属性将作为object 出现。您可以进行安全投射并在布局上使用它作为示例:

@{

  PageModel pageModel = this.Model as PageModel;

  if (pageModel != null)
  {
     <div>obj.Title</div>
  }  

}

对局部视图也有效。

现在,如果您确定所有控制器的每个操作都可以返回使用 Layout 页面的 View,那么只需转换并使用 Model。

Look this article.

【讨论】:

  • 那篇文章暗示他在提倡我概述的方法? “只要你遵循基本的继承规则,在主/布局页面上强烈键入模型是完全安全的”
猜你喜欢
  • 2017-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多