MVC4-View(视图)
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语法。本片文章就先分享这些,有那些不对的地方还请各位前辈,朋友多多指导,大家共同进步学习!