15.1 ASP.NET MVC概述
ASP.NET MVC是一种构建Web应用程序的框架,它将最流行的MVC框架应用于ASP.NET框架。下面从MVC的工作模式开始介绍,逐步过渡到ASP.NET MVC 4。
15.1.1 MVC工作模式
抛开具体的开发语言来讲,MVC是一种软件开发的架构模式,也算是一种思想。在MVC模式中将软件系统分为:模型、视图和控制器三个基本部分。
它们各负其职,相互独立,又具有联系,如图15-1所示是MVC这三部分的示意图。
图15-1 MVC示意图
(1)模型:负责对整个软件项目数据和业务的封装和管理。
(2)视图:负责给用户传递信息,收集用户提交的信息。
(3)控制器:负责控制视图的展示逻辑。
1.视图
视图是用户看到并与之交互的界面。对老式的Web应用程序来说,视图就是由HTML元素组成的界面,在新式的Web应用程序中,HTML依旧在视图中扮演着重要的角色。但一些新的技术已层出不穷,包括Flash、XHTML、XML/XSL、WML等一些标识语言和Web Services。
如何处理应用程序的界面变得越来越有挑战性。MVC一个很大的好处是它能为应用程序处理很多不同的视图。在视图中其实没有真正的处理发生,不管这些数据是联机存储的还是一个雇员列表,作为视图来讲,它只是作为一种输出数据并允许用户操纵的方式。
2.模型
模型表示企业数据和业务规则。在MVC的三个部分中,模型拥有最多的处理任务。例如,它可能用EJB这样的组件对象来处理数据库。被模型返回的数据是中立的,就是说模型与数据格式无关,这样一个模型能为多个视图提供数据。由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的重复性。
3.控制器
控制器接收用户的输入并调用模型和视图去完成用户的需求。所以,当单击Web页面中的超链接和发送HTML表单时,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型组件去处理请求,然后确定用哪个视图来显示模型处理返回的数据。
15.1.2 MVC优缺点
在使用ASP或者PHP开发Web应用时,初始的开发模板就是混合层的数据编程。例如,直接向数据库发送请求并用HTML显示,开发速度往往比较快。但由于数据页面的分离不是很直接,因而很难体现出业务模型的样子或者模型的重用性,很难满足用户的变化性需求。
MVC要求对应用分层,虽然要花费额外的工作,但产品的结构清晰,产品的应用通过模型可以得到更好的体现。
(1)首先,最重要的是应该有多个视图对应一个模型的能力。在目前用户需求的快速变化下,可能有多种方式访问应用的要求。
例如,订单模型可能有本系统的订单,也有网上订单,或者其他系统的订单,但对于订单的处理都是一样,也就是说订单的处理是一致的。按MVC设计模式,一个订单模型以及多个视图即可解决问题。这样减少了代码的复制,即减少了代码的维护量,一旦模型发生改变,也易于维护。
(2)其次,由于模型返回的数据不带任何显示格式,因而这些模型也可直接应用于接口的使用。
(3)再次,由于一个应用被分离为三层,因此有时改变其中的一层就能满足应用的改变。一个应用的业务流程或者业务规则的改变只需改动MVC的模型层。
(4)控制层的概念也很有效,由于它把不同的模型和不同的视图组合在一起完成不同的请求,因此,控制层可以说是包含用户请求权限的概念。
(5)最后,它还有利于软件工程化管理。由于不同的层各司其职,每一层不同的应用具有某些相同的特征,有利于通过工程化、工具化产生管理程序代码。
凡事都不是绝对的,MVC也是如此。MVC也不是最先进、最优秀或者最好的选择,其缺点主要体现在以下几个方面:
(1)增加了系统结构和实现的复杂性。
对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率。
(2)视图与控制器间过于紧密的连接。
视图与控制器是相互分离的,但是又紧密联系的部分,如果视图没有控制器的存在,那它的应用是很有限的。反之亦然,这样就妨碍了它们的独立重用。
(3)视图对于模型数据的低效率访问。
依据模型操作接口的不同,视图可能需要多次调用才能获得足够的显示数据。对未变化数据的不必要的频繁访问,也将损害操作性能。
目前,一般高级的界面工具或者构造器不支持MVC架构。改造这些工具以适应MVC需要和建立分离部分的代价是很高的,从而造成使用MVC的困难。
15.1.3 ASP.NET MVC 4新特性
ASP.NET MVC是微软官方推出的基于ASP.NET的MVC模式网站应用程序开发框架,官方网站http://www.asp.net/mvc。
ASP.NET MVC的第一个版本是于2009年3月17日发布的RTM版本。在经历了漫长的Preview之后,终于2010年3月11日发布了ASP.NET MVC 2.0。之后又发布了ASP.NET MVC 3.0。目前最新版本为MVC 4.0,也是本书所采用的开发版本。
ASP.NET MVC 4包含大量的新特性和功能,主要新特性如下:
(1)Razor增强功能
ASP.NET MVC 4提供了新的视图引擎Razor V2。Razor V2包含丰富的增强功能,可以让视图模板更简洁,并为解析URL引用和有选择地呈现HTML属性提供了更好的支持。
(2)捆绑和缩小
ASP.NET MVC 4包括ASP.NET 4.5中的新捆绑和缩小支持特性。这些特性使用户在构建Web应用程序时能最小化网页所做的HTTP请求数量和大小,实现更快的加载速度和响应用户请求。
(3)数据库迁移
ASP.NET MVC 4内置的实体框架为最新的4.3,包含很多新功能,其中最受期待的功能之一是支持迁移数据库。这让用户方便地使用代码集中迁移的方法来改进数据库架构,这样做的同时也保留了数据库内的数据。
(4)Web API
ASP.NET MVC 4包括一些出色的新特性支持来创建Web API。这使用户能够轻松地创建HTTP服务和应用程序,并且这些服务和应用程序能够以编程方式从大范围的客户端调用(包括使用JavaScript从浏览器中调用,到任何移动/客户端平台上的本机应用程序)。新的Web API还支持提供一个理想的平台来建设RESTFUL服务。
(5)移动Web
ASP.NET MVC 4支持用于构建移动Web应用程序和移动Web站点,并使其更容易构建针对手机和平板的优化体验。
(6)异步支持和WebSockets
在将ASP. NET MVC 4与.NET 4.5和VS 2012一起使用时,用户将能够充分利用额外的语言和运行时功能,异步支持是其中最大的一个。ASP.NET MVC运行时支持新的C#异步语言增强功能,这将让用户编写出令人难以置信的可伸缩的应用程序。同时还可以利用内置于.NET 4.5的新WebSocket支持来构建更丰富的浏览/服务器通信应用程序。
15.1.4 Razor视图引擎
在ASP.NET MVC 1和ASP.NET MVC 2中默认使用的视图引擎被称为Web Forms视图引擎。因为它与Web Forms使用了相同的文件(例如,aspx、ascx和master)和语法。
如下所示为一个Web Forms视图引擎下的文件内容。
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcApplication1.Models.LogOnModel>" %> <asp:Content ID="loginTitle" ContentPlaceHolderID="TitleContent" runat="server"> 登录 </asp:Content> <asp:Content ID="loginContent" ContentPlaceHolderID="MainContent" runat="server"> <h2>登录</h2> <p>请输入用户名和密码。 <%: Html.ActionLink("注册", "Register") %> 如果您没有账户。</p> <script src="<%: Url.Content("~/Scripts/jquery.validate.min.js") %>" type="text/javascript"></script> <% using (Html.BeginForm()) { %> <%: Html.ValidationSummary(true, "登录不成功。请更正错误并重试。") %> <div> <fieldset> <legend>账户信息</legend> <div class="editor-label"> <%: Html.LabelFor(m => m.UserName) %> </div> <div class="editor-field"> <%: Html.TextBoxFor(m => m.UserName) %> <%: Html.ValidationMessageFor(m => m.UserName) %> </div> <div class="editor-label"> <%: Html.LabelFor(m => m.Password) %> </div> <div class="editor-field"> <%: Html.PasswordFor(m => m.Password) %> <%: Html.ValidationMessageFor(m => m.Password) %> </div> <div class="editor-label"> <%: Html.CheckBoxFor(m => m.RememberMe) %> <%: Html.LabelFor(m => m.RememberMe) %> </div> <p><input type="submit" value="登录" /> </p> </fieldset> </div> <% } %> </asp:Content>
从ASP.NET MVC 2之后新增了Razor视图引擎,它不像Web Forms视图引擎那样具有类似XML的复杂语法规则。Razor的语法更加易于输入、阅读和维护,且结构更简洁。如下所示是使用Razor生成相同标记的内容。
@model MvcApplication2.Models.LogOnModel @{ ViewBag.Title = "登录"; } <h2>登录</h2> <p>请输入用户名和密码。如果您没有账户,请 @Html.ActionLink("注册", "Register")。 </p> <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> @Html.ValidationSummary(true, "登录不成功。请更正错误并重试。") @using (Html.BeginForm()) { <div> <fieldset> <legend>账户信息</legend> <div class="editor-label"> @Html.LabelFor(m => m.UserName) </div> <div class="editor-field"> @Html.TextBoxFor(m => m.UserName) @Html.ValidationMessageFor(m => m.UserName) </div> <div class="editor-label"> @Html.LabelFor(m => m.Password) </div> <div class="editor-field"> @Html.PasswordFor(m => m.Password) @Html.ValidationMessageFor(m => m.Password) </div> <div class="editor-label"> @Html.CheckBoxFor(m => m.RememberMe) @Html.LabelFor(m => m.RememberMe) </div> <p> <input type="submit" value="登录" /> </p> </fieldset> </div> }
Razor视图引擎允许用户编写更复杂的逻辑代码,而且可以在代码和标签之间轻易转换。虽然Razor语法与其他的标记语法不同(ASP.NET Web Form),但是它们的目标都是相同的,即渲染HTML。
如下是foreach循环在Web Form中的语法。
<ul> <% foreach(var a in actions) {%> <li><a href="<%:a.href%>" > <%: a.title%></a> </li> <%}%> </ul>
如下所示为Razor语法的代码。
<ul> @foreach(var a in actions){ <li><a href="@a.href">@a.title</a></li> } </ul>
在Razor中要定义一个代码块需要以“@{”开始,以“}”结束。这里的代码块与代码段不同,代码块要求使用C#常规代码,即必须符合C#语法,每行以分号结束。如下是一个代码块的例子。
@{ LayoutPage="~/Views/Shared/_Layout.cshtml"; View.Title="Action:"+Model.Title; }
如上所示,代码块中不能渲染任何东西,并且编写的代码不可以有返回值。
综上所述,Razor的主要特点如下。
(1)不是新语言。Razor语法非常直观,且支持现在的.NET编码方法和技术。只需简单地输入“@”符号即可进入Razor视图状态。
(2)容易学习。由于Razor不是一门新的编程语言,因此学习Razor非常容易。如果熟悉HTML和.NET语言,那么编写将会更加容易上手Razor。
(3)支持所有文本编辑器。由于Razor是轻量级并注重于HTML的语言,因此可以自由地选择编辑器。虽然VS 2012提供了Razor的智能语法提示,但是Razor足够简单,可以使用任何文本编辑器进行编辑。
(4)单元测试。Razor视图引擎的核心编译与System.Web或ASP.NET没有任何依赖关系,它能执行单元测试,甚至可以从命令行执行。