View(視圖),大家並不是很陌生!視圖是負責向用戶提供用戶界面(UI),他是一個承載有模型(顯示控制器需要的信息),該模型需要轉換格式呈現給用戶。在ASP.NET MVC中,視圖通過狀態寄存器的模型對象傳遞給它的控制器和改造的內容到HTML。
OK,我們下來看一個例子,建立一個視圖叫(Sample.cshtml),具體代碼如下:
@{ this.Layout = null; } <!DOCTYPE html> <html> <head><title>Sample View</title></head> <body> <h1>@ViewBag.Message</h1> <p> This is a sample view. It's not much to look at, but it gets the job done. </p> </body> </html>
這是一個非常簡單的示例顯示一條消息,由控制器到視圖一種通過@ ViewBag.Message動態表達。基於Web框架ASP.NET Web Forms和PHP等不同的地方在於:他不能直接訪問(你不可能直接在瀏覽器中看到該頁面)。因為視圖始終呈現由控制器提供的數據視圖將呈現出來。所以我們需要在控制器(Controller)里添加一下代碼:
// GET: /Sample public ActionResult Sample() { this.ViewBag.Message = "Hellw World.Welcome to ASP.NET MVC4!"; return this.View("Sample"); }
控制器里設置ViewBag.Message屬性為一個字符串,然后返回一個視圖名為Sample的頁面。這里就不在運行了!
指定視圖
在每一個控制器文件夾中,有一個視圖文件,命名為每個操作方法一樣的的操作方法。這提供了基礎視圖相關的操作方法。操作方法可以返回一個ViewResult通過查看方法,例如下面的代碼:
public class HomeController : Controller { public ActionResult Index() { this.ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application"; return this.View(); } }
這個方法(Action)是HomeController默認方法。他會自動索引到Views/Home/Index.cshtml文件。但是在ASP.NET MVC中你可以覆蓋這一默認的機制,你可以指定該方法(Action)呈現到不同的視圖上。比如這樣:
public class HomeController : Controller { public ActionResult Index() { this.ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application"; return this.View("NotIndex"); } }
這種情況,他會自動索引到Views/Home文件夾下找NotIndex.cshtml文件.當然你還可以這樣,讓他去索引不同目錄下面的頁面,這是你可以這樣:
public class HomeController : Controller { public ActionResult Index() { this.ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application"; return this.View("~/Views/Example/Index.cshtml"); } }
ViewData 和 ViewBag
從技術上講,數據通過控制器通過一個稱為ViewData的ViewDataDictionary(一個字典類型)。在ViewPage中查詢數據時需要轉換合適的類型,例如下面代碼:
ViewData["CurrentTime"] = DateTime.Now;
雖然這仍然是可用的,ASP.NET MVC 3利用C#4動態關鍵字允許更簡單的語法。屆時,你可以這樣:
ViewBag.CurrentTime = DateTime.Now;
由此可以看出,ViewBag.CurrentTime是相當於ViewData的[“currentTime”].可以看到ViewBag在ViewPage中查詢數據時候不需要轉換合適的類型,具有更好的可讀性!
強類型的視圖(STRONGLY TYPED VIEWS)
假如你需要寫一個視圖顯示的列表專輯實例,一個可行的方式是對其列表進行迭代顯示到視圖,可以想下面所示:
public ActionResult List() { var albums = new List<Album>(); for(int i = 0; i < 10; i++) { albums.Add(new Album {Title = "Product " + i}); } ViewBag.Albums = albums; return View(); }
在視圖頁面,你就可以這樣搞:
<ul> @foreach (Album a in (ViewBag.Albums as IEnumerable<Album>)) { <li>@a.Title</li> } </ul>
OK!我們在方法里返回的ViewBage.Albums是個動態的(運行時編譯)IEnumerable<Album>枚舉類型。其實為了代碼更好的可讀性,我們可以將上面視圖頁面代碼這么搞:
<ul> @foreach (dynamic p in ViewBag.Albums) { <li>@p.Title</li> } </ul>
在我們的Controller(控制器)里通過方法(Action)來加載模型,傳遞模型實例.例如可以這樣:
public ActionResult List() { var albums = new List<Album>(); for (int i = 0; i < 10; i++) { albums.Add(new Album {Title = "Album " + i}); } return View(albums); }
接下來在View(視圖),(幕后是這ViewData.Model屬性的值設置的值傳遞到該視圖的方法),可以這么搞(需要引用一哈模型):
@model IEnumerable<MvcApplication1.Models.Album> <ul> @foreach (Album p in Model) { <li>@p.Title</li> } </ul>
還有一個更好的方法,將我經常用的命名空間寫在web.config中,如下:
@using MvcApplication1.Models <system.web.webPages.razor> … <pages pageBaseType="System.Web.Mvc.WebViewPage"> <namespaces> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" />
<add namespace="MvcApplication1.Models" /> </namespaces> </pages> </system.web.webPages.razor>
視圖模型
通常一個視圖需要顯示各種數據但是不直接映射到域模型。比如在一個商品的詳情頁面,可能會附加這個商品相關的商品及其他的一些東西。有個很簡單的辦法的顯示這些額外數據而不牽扯到你的視圖模型,用ViewBag來完成這些顯示數據。當然這個不適用與任何人,大家在搞項目會碰到的很多種情況,所以要看情況選擇對應的辦法處理!當然你也可以寫一個視圖模型類,你能想到的一個視圖模型,它的存在就只是為了提供信息視圖。可以去參考下("MVVM")理解。例如,我現在想要展示一個購物車,它包含商品信息,商品價格和一些用戶的信息,那么我可以寫下面一個模型類:
public class ShoppingCartViewModel { public IEnumerable<Product> Products { get; set; } public decimal CartTotal { get; set; } public string Message { get; set; } }
現在在視圖上就可以直接用我們編寫的視圖模型,只需要我們引用下,如下:
@model ShoppingCartViewModel
關於創建視圖這里就不做過多的羅嗦了!
了解下Razor
Razor視圖引擎引是ASP.NET MVC 3默認的視圖引擎。Razor是一個ASP.NET MVC 提供一個干凈的,輕量級的,簡單的視圖引擎。Razor的好處是:提供了簡化的語法表達的意見,最大限度地減少語法和多余的字符。Razor會使視圖想要表達的邏輯更加明確(更容易看懂),列入下面的例子:
@{ // this is a block of code. For demonstration purposes, // we'll create a "model" inline. var items = new string[] {"one", "two", "three"}; } <html> <head><title>Sample View</title></head> <body> <h1>Listing @items.Length items.</h1> <ul> @foreach (var item in items) { <li>The item name is @item.</li> } </ul> </body> </html>
Razor的一些語法:
- 隱式的代碼表達
代碼表達式的值如何響應到到視圖,如何顯示出值:
Razor | <span>@model.Message</span> |
Web Forms | <span><%: model.Message %></span> |
上面是在Razor表達式的HTML編碼和Web Forms語法編碼的一個對比,是不是感覺Razor要好用很多!
- 顯式代碼表達
RAZOR | <span>ISBN@(isbn)</span> |
Web Forms | <span>ISBN<%: isbn %></span> |
- 未編碼的代碼表達式
在某些情況下,你需要明確地呈現一些值不應該HTML編碼。您可以使用Html.Raw方法,以確保該值的編碼不,如下:
Razor | <span>@Html.Raw(model.Message)</span> |
Web Forms | <span><%: Html.Raw(model.Message) %></span> or <span><%= model.Message %></span> |
- 代碼快
Razor | @{ int x = 123; string y = ˝because.˝; } |
Web Forms | <% int x = 123; string y = "because."; %> |
- 結合文字和標記
Razor | @foreach (var item in items) { <span>Item @item.Name.</span> } |
Web Forms | <% foreach (var item in items) { %> <span>Item <%: item.Name %>.</span> <% } %> |
- 混合代碼和純文本
Razor | @if (showMessage) { <text>This is plain text</text> } or @if (showMessage) { @:This is plain text. } |
Web Forms | <% if (showMessage) { %> This is plain text. <% } %> |
- 分離代碼分隔符號
Razor | My Twitter Handle is @haacked or My Twitter Handle is @@haacked |
Web Forms | <% expression %> marks a code nugget. |
- 服務器端注釋
Razor | @* This is a multiline server side comment. @if (showMessage) { <h1>@ViewBag.Message</h1> } All of this is commented out. *@ |
Web Forms | <%--This is a multiline server side comment. <% if (showMessage) { %> <h1><%: ViewBag.Message %></h1> <% } %> All of this is commented out. --%> |
- 調用泛型方法
Razor | @(Html.SomeMethod<AType>()) |
Web Forms | <%: Html.SomeMethod<AType>() %> |
指定局部視圖
OK,最后聊下局部視圖,mvc通常出了action(方法)返回一個視圖外,當然他也可以返回一個局部試圖PartialView()可以搞定某些情況下你的困惑。下面看一個簡單的例子:
public ActionResult HuiTai() { this.ViewBag.Message = "This is a View(My -> ActionResult)"; return this.View(); } public PartialViewResult Huitai() { this.ViewBag.Message = "This is a PartialView(My -> PartialViewResult)"; return this.PartialView(); }
上面兩種寫法都是OK的,只不過一個是具體的表達方式!這個這里就不做過多的詮釋,前面都啰嗦過了!先分享這些吧,有點雜,但是有點幫助就行了!主要說了:視圖引擎有一個非常具體的,有明確目的。它們的存在數據傳遞給他們控制器和相應的方法執行后輸出,通常為HTML。還有就是了簡單的解了Razor語法。本片文章就先分享這些,有那些不對的地方還請各位前輩,朋友多多指導,大家共同進步學習!