View主要用於呈現數據。由於Controller和相關的Service已經處理完業務邏輯並將結果打包成model實體,View只需要怎么去獲得model並將其轉為Html
1選擇需要渲染的視圖
在上一篇中GuestbookController:
public ActionResult Create() { return View(); }
默認渲染的是Views/Guestbook/Create.cshtml. 當以無參形式調用View()時, Framework推斷要渲染的視圖的名稱應該和Action的名稱一致。然后在MVC管線中,ControllerActionInvoker執行ViewResult並且告知要渲染的View,同時Framework請求ViewEngineCollection去定位要渲染的View(默認情況下,先尋找Views/<Controller Name>目錄,然后是Views/Shared 目錄)
2View重寫
指定視圖名稱來返回視圖
public ActionResult TestJson() { return View(); } public ActionResult TestJsonContent() { return View("TestJson"); }
甚至還可以指定視圖的路徑
return View("~/Views/SomeOtherDirectory/New.cshtml");
3傳遞數據給View
在MVC中,Model對象是指包含了數據的模型. Controller將Model傳遞給View以后, View對象中不應該做任何的業務邏輯處理, 僅僅根據Model對象做一些顯示邏輯的處理.
傳遞Model對象時, 我們有兩種選擇:
1.傳遞一個弱類型的集合, 即成員為object類型的集合, 在View中需要將每個成員轉換成我們需要的類型,比如int, string,自定義類型等.
2.傳遞強類型對象, 這些類型是我們自定義的. 在View中直接使用我們傳遞的強類型對象, 不需要再轉換類型.
傳遞弱類型:
ASP.NET MVC框架定義了ViewContext類, 直譯后是"View上下文", 其中保存和View有關的所有數據, 其中Model對象也封裝在了此類型中.
ViewData集合和TempData集合都是用來保存Model對象的.在一個Controller的Action中, 我們可以用如下方式為這兩個集合賦值:
public ActionResult Create()
{
ViewData["hasPermission"] = true;
TempData["hasPermission"] = true;
return View();
}
在頁面中, 使用如下方式使用這兩個集合:@{bool hasPermission=(bool)ViewData["hasPermission"]} @{bool hasPermission=(bool)TempData["hasPermission"]}
自MVC 3開始有一個新的ViewBag 動態特性,它主要是為了從Controller到view進行傳值用的,類似有所使用的ViewData[] 字典類。它定義為Dynamic,意味着你能動態的set/get 值,增加任何數量的的額外字段而不需要強類型的檢測。
public ActionResult Create() { ViewBag.hasPermission = true; return View(); }
在頁面中, 使用如下方式@{bool hasPermission=(bool)ViewBag.hasPermission}
強類型
當使用基於Razor的視圖時,視圖默認繼承兩個類型:System.Web.Mvc.WebViewPage或者 System.Web.Mvc.WebViewPage<T>。泛型WebViewPage<T>繼承自 WebViewPage,但是提供了一些非泛型WebViewPage類里沒有的獨特的補充。
下面展示了WebViewPage<T>的主干成員定義:
public class WebViewPage<TModel> : WebViewPage { public new AjaxHelper<TModel> Ajax { get; set; } public new HtmlHelper<TModel> Html { get; set; } public new TModel Model { get; } public new ViewDataDictionary<TModel> ViewData { get; set; } }
要使用強類型視圖,首先你必須確保控制器動作正確設置了ViewData.Model。在清單3.4里,我們獲取所有的留言記錄,顯示在列表頁面,並傳遞個人檔案的整個集合到View方法,此方法封裝了對ViewData.Model屬性的設置。
public ActionResult Index() { var mostRecentEntries = (from entry in _db.Entries orderby entry.DateAdded descending select entry).Take(20); var model = mostRecentEntries.ToList(); return View(model); }
在與這個動作相應的Index視圖里,即使松散類型的WebViewPage類也能使用ViewData.Model屬性。但是這個屬性只是一個object類型,我們需要對它進行轉換以便有效地使用它。作為替代方案,我們能用@model關鍵詞指定模型的類型。
@using Guestbook.Models
@model List<GuestbookEntry>
ASP.NET MVC 3 Beta版中添加新@model指令以提供一個更干凈簡潔的方式來指明你想要在視圖文件中引用強類型模型類。你現在只需在你的Razor視圖文件的頂端寫 上@model StrongModelType就行了, 再無需有一個@inherits或指定一個視圖基類
例如:
@model MvcApplication5.Models.GuestbookEntry
@model IEnumerable<MvcApplication5.Models.GuestbookEntry>
轉換為強類型后,要顯示響應的數據是那么的簡單,如:@Model.Message
4視圖模板的選擇
MVC提供了兩種視圖:Aspx, Razor:
使用.ASPX“代碼碎塊”的方式編寫
我們需要在HTML標簽中使用”<%= %>”來標記“代碼碎塊”:
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<DemoRC.Models.DTO.TransferModelController.StrongTypedDemoDTO>" %> ... <body> <fieldset> <legend>Fields</legend> <p> UserName: <%= Html.Encode(Model.UserName) %> </p> <p> UserPassword: <%= Html.Encode(Model.UserPassword) %> </p> </fieldset> <p> <%=Html.ActionLink("Edit", "Edit", new { /* id=Model.PrimaryKey */ }) %> | <%=Html.ActionLink("Back to List", "Index") %> </p> </body>
仔細觀察就可以發現上例中每一個代碼碎塊都需要5個字符(”<%= %>”)來標明代碼的開始和結束位置。
使用Razor的語法編寫
在Razor中,你只需要用一個”@”字符就可以標識代碼塊的開始,與”<% %>”代碼碎塊不一樣,Razor不需要你顯式指明代碼塊的結束位置:
<ol> <li> @Html.LabelFor(m => m.UserName) @Html.TextBoxFor(m => m.UserName) </li> <li> @Html.LabelFor(m => m.Password) @Html.PasswordFor(m => m.Password) </li> <li> @Html.CheckBoxFor(m => m.RememberMe) @Html.LabelFor(m => m.RememberMe, new { @class = "checkbox" }) </li> </ol>