强烈的类型视图和共享视图

时间:2013-12-18 16:07:52

标签: c# asp.net-mvc

使用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>

3 个答案:

答案 0 :(得分:2)

我已经看到这种做法有多种不同的方式,这实际上取决于项目。

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

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

答案 1 :(得分:2)

因此,模型的包装正在创建视图模型,视图模型通常包含您的模型以及您可能需要的任何其他视图数据。创建视图模型基类是确保视图模型一致性的好方法。

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

总而言之 - 你的方法完全没问题,也许这个术语可能略有不同。

编辑:2013年12月19日0 RE:基于列表的观点

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

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

public class Book { ... }

视图模型(或调用它的PageModel)base

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

您将拥有这样的视图模型:

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

答案 2 :(得分:0)

只是不要输入ViewModel属性将作为object存在。您可以进行安全演员表并在布局上使用它来获取示例:

@{

  PageModel pageModel = this.Model as PageModel;

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

}

它也适用于部分视图。

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

Look this article.