ASP.NET MVC Framework
✍ dations ◷ 2025-04-04 07:22:44 #微软开发工具,ASP.NET,MVC
ASP.NET MVC Framework是微软在ASP.NET中所添加的一组类别库,这组类别库可以使用Model-View-Controller的设计模式来开发ASP.NET的应用程序。它与现有的ASP.NET应用程序并没有冲突,所以两者是可以并发的。ASP.NET MVC Framework被包装在System.Web.Mvc.dll中,并利用ASP.NET Routing来支持动作流以及URL Rewriting的能力,让它可以更贴近Web的发展以及Web 2.0的特性。对于多数有ASP开发经验的开发人员来说看起来比较不陌生,但对于没有接触过像ASP、PHP、JSP、Perl这些Web开发工具的开发人员来说,相对的不容易入门。ASP.NET MVC 的第一个版本于2009年3月17日发布RTM版本,最新的ASP.NET MVC 5.2则是于2014年12月24日正式发行。
微软于 ASP.NET Core 中提出下一代的 MVC 框架,称为 ASP.NET Core MVC。
ASP.NET MVC是遵循软件模式的Model-View-Controller来发展,其中Model指的是数据或是业务逻辑组件,View是呈现给用户看的信息,而Controller则是接取来自用户的指令与数据,并将Model与View做集成的控制器,当服务器接到对ASP.NET MVC应用程序的要求时,服务器(IIS)会先使用UrlRoutingModule(ASP.NET Routing的 HTTP 模块),由它来解析是否有包含ASP.NET MVC应用程序的URL,若有,则会产生一个MvcRouteHandler对象,这个对象会装载运行的必要信息,并且会调用包含在URL中的Controller的Execute方法来运行工作。
Controller对象是基于IController
接口的规则所定义,提供针对HTTP要求做回应的一个运行工具,在ASP.NET MVC中已实现一个默认的类别 Controller,提供了必要的基础功能,另外也发展了一个 Controller 工厂,称为 Controller Factory,以IControllerFactory
接口定义,亦提供了DefaultControllerFactory,开发人员可以利用基本的类别以及利用它们来派生自己的 Controller 或 Controller Factory 来实现自己的控制器逻辑功能。
Model对象则是为ASP.NET MVC提供数据,不过它没有基类,而是使用.NET Framework一般性的数据结构或是现在的ADO.NET数据对象,像是List、Dictionary、DataTable、DataReader与DataSet等等,当然也可以是自己开发的商业对象,这些数据会透过ASP.NET MVC的ModelBinder工具类别来与Controller集成,ModelBinder本身是支持泛型(Generic)的,因为各种类型的数据它都可以使用。在ASP.NET MVC中提供了一个DefaultModelBinder对象,可支持大多数的.NET Framework数据类型,以及数组和已实现像是IList、IDictionary以及ICollection等接口的对象。
Model会在Controller运行动作时,作为一个ActionResult对象方式传回给MvcHandler对象,而这个对象即会指定要显示的View对象,像是下列代码所示:
1 using System.Linq; 2 using System.Web.Mvc; 3 using System.Web; 4 using System; 5 6 // GET: /Person/ 7 public ActionResult Index() 8 { 9 return View(people);10 }11 12 // GET: /Person/Details/513 public ActionResult Details(Person person)14 {15 return View(person);16 }17 18 // GET: /Person/Create19 public ActionResult Create()20 {21 return View();22 } 23 24 // POST: /Person/Create25 26 public ActionResult Create(Person person)27 {28 if (!ModelState.IsValid)29 {30 return View("Create", person);31 }32 33 people.Add(person);34 35 return RedirectToAction("Index");36 }
1 Public Class HomeController 2 Inherits System.Web.Mvc.Controller 3 4 'GET: /Person/ 5 Function Index() As ActionResult 6 Return View(people) 7 End Function 8 9 'GET: /Person/Details/510 Function Details(Person person) As ActionResult11 Return View(person)12 End Function13 14 'GET: /Person/Create15 Function Create() As ActionResult16 Return View()17 End Function18 19 'POST: /Person/Create20 <AcceptVerbs(HttpVerbs.Post)>21 Function Contact() As ActionResult22 If ModelState.IsValid Then23 Return View("Create", person)24 Else25 people.Add(person)26 Return RedirectToAction("Index")27 End If28 End Function29 30 End Class
View对象以IView
与IViewDataContainer
等接口为主,并且以ASP.NET的各式前端接口为主要输出工具,基于MVC的View弹性化设计考量,以往在ASP.NET Web Form的代码与HTML分离模式将不再存在,而是将代码与HTML混合的方式设计,让开发人员可以更精确的对View进行控制,而目前 ASP.NET MVC 支持的 View 有下列几种:
每个 View 对象都会内含一个泛型的参数,用来装载要呈现的数据(即Model),然后使用类似下面的方式来呈现数据:
1 <%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %> 2 3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 4 <html > 5 <head runat="server"> 6 <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title> 7 <link href="../../Content/Site.css" rel="stylesheet" type="text/css" /> 8 </head> 9 10 <body>11 <div class="page">12 13 <div id="header">14 <div id="title">15 <h1>My MVC Application</h1>16 </div>17 18 <div id="logindisplay">19 <% Html.RenderPartial("LogOnUserControl"); %>20 </div> 21 22 <div id="menucontainer">23 24 <ul id="menu"> 25 <li><%= Html.ActionLink("Home", "Index", "Home")%></li>26 <li><%= Html.ActionLink("About", "About", "Home")%></li>27 </ul>28 29 </div>30 </div>31 32 <div id="main">33 <asp:ContentPlaceHolder ID="MainContent" runat="server" />34 35 <div id="footer">36 </div>37 </div>38 </div>39 </body>40 </html>
技术
在ASP.NET MVC架构中,除了Controller、Model与View三个主要部分以外,还包含了许多技术以让这三层得以集成并交互运作。
Controller在ASP.NET MVC应用程序中是负责中控的角色,也是来自客户端HTTP要求的处理核心,因此有许多处理与转向HTTP要求的辅助技术在Controller层次都会使用到。
用来过滤客户端要求的URL,并借由定义好的路由表(route table)将要求导向至正确的MVC Controller,并调用Controller中的Execute方法运行,而Execute方法会将HTTP动作以及实际运行的指令交给正确的函数来运行。而通常一个MVC应用程序的URL都会是类似这样的URL格式:
http://127.0.0.1/ControllerName/ActionName/ActionParameters
而MvcRouteHandler会拆解URL,找出目标的Controller,并且将ActionName以及ActionParameters传给Controller中负责的函数(以ActionName来指定)。例如下列的URL会传递给BlogController的GetList方法:
http://127.0.0.1/Blog/GetList
动作与方法直接集成
ASP.NET MVC利用了中介数据的技术,直接将方法对应到指定的 HTTP 动词 (GET/POST/PUT/DELETE/HEAD等),MvcHandler会判断要求的类别,并将它交给URL中指定的方法来处理。目前MVC Framework可用下列的方式指定(均包含在 HttpVerbs 枚举类型中):
ViewPage
、ViewMasterPage
、ViewUserControl
等展示对象都支持泛型对象,可以直接装载Model数据传递至前端输出,可简化处理Model与View之间集成的动作,只要一个参数就可以将数据传给View:
public ActionResult GetList(){ return View(BlogDataModel);}
Function GetList() As ActionResult Return View(BlogDataModel) End Function
Model
在 ASP.NET MVC 中,Model 相对不设限,可以使用内置的数据结构以及自定义的数据类别,也可以是一个商业对象,因此 Model 的弹性相当大,除了前述的数据结构外,微软新发展的一些数据访问方式也可以应用在 Model 中,像是ADO.NET Entity Framework与LINQ to SQL等技术。
另外,MVC在服务端数据验证中,提供了ViewDataDictionary
类别,这个类别中有一个ModelState属性,内含了ModelStateDictionary
类别,开发人员可以利用这个类别来控制数据验证的结果,而View中输出验证消息的部分会和此类别有关系,例如下列的程序:
public ActionResult Create(Person person){ if (person.Name.Trim().Length == 0) { ModelState.AddModelError("Name", "Name is required."); } if (person.Age < 1 || person.Age > 200) { ModelState.AddModelError("Age", "Age must be within range 1 to 200."); } if ((person.Zipcode.Trim().Length > 0) && (!Regex.IsMatch(person.Zipcode, @"^\d{5}$|^\d{5}-\d{4}$"))) { ModelState.AddModelError("Zipcode", "Zipcode is invalid."); } if (!Regex.IsMatch(person.Phone, @"((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}")) { ModelState.AddModelError("Phone", "Phone number is invalid."); } if (!Regex.IsMatch(person.Email, @"^+@(+\.)+{2,4}$")) { ModelState.AddModelError("Email", "Email format is invalid."); } if (!ModelState.IsValid) { return View("Create", person); } people.Add(person); return RedirectToAction("Index");}
在 ASP.NET MVC 2.0 中,新增了一个可以直接让 MVC Framework 针对数据字段进行验证控制的模型,称为 Model Validation,它融合了在 .NET Framework 3.5 SP1 发表的 ASP.NET Dynamic Data Framework 中 Data Annotations (数据记号) 的特性,让开发人员可以只利用标记的方式来运行验证,或是利用自定义的代码来扩展数据记号的验证行为。
using System.ComponentModel.DataAnnotations; namespace MvcDA { public partial class Product { public class ProductMD { public object Name { get; set; } public object Color { get; set; } public object Weight { get; set; } // public object NoSuchProperty { get; set; } } }}
View
由于View是直接呈现给用户,因此与用户交互的部分都要由此层处理,包含数据的输出以及以客户端操作为主的回应(例如脚本)等。
HTML工具类别在View中是很重要的输出工具,它内置了辅助产生HTML标签的工具方法,多数的HTML语法都可以利用它来产生,包含像链接(<a>)、窗体(<form>)以及窗体控件等等。HTML工具是以HtmlHelper
类别为核心,并配合System.Web.Mvc.Html名字空间的方法,以延伸方法(Extension Method)的方式,让产生HTML的程序就有如调用方法般简单:
<h2>Index</h2><table> <tr> <th></th> <th> Id </th> <th> Name </th> </tr><% foreach (var person in Model) { %> <tr> <td> <%= Html.ActionLink("Details", "Details", person )%> </td> <td> <%= Html.Encode(person.Id) %> </td> <td> <%= Html.Encode(person.Name) %> </td> </tr><% } %></table><p> <%= Html.ActionLink("Create New", "Create") %></p>
数据验证
View的HTML工具可以配合Model处理数据验证的结果,在ASP.NET中常用的ValidationSummary在这里也支持,而且MVC的架构让验证信息的输出也更加弹性:
<h2>Create</h2><%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %><% using (Html.BeginForm()) {%> <fieldset> <legend>Fields</legend> <p> <label for="Name">Name:</label> <%= Html.TextBox("Name") %> Required <%= Html.ValidationMessage("Name", "*") %> </p> <p> <label for="Age">Age:</label> <%= Html.TextBox("Age") %> Required <%= Html.ValidationMessage("Age", "*") %> </p> <p> <label for="Street">Street:</label> <%= Html.TextBox("Street") %> <%= Html.ValidationMessage("Street", "*") %> </p> <p> <label for="City">City:</label> <%= Html.TextBox("City") %> <%= Html.ValidationMessage("City", "*") %> </p> <p> <label for="State">State:</label> <%= Html.TextBox("State") %> <%= Html.ValidationMessage("State", "*") %> </p> <p> <label for="Zipcode">Zipcode:</label> <%= Html.TextBox("Zipcode") %> <%= Html.ValidationMessage("Zipcode", "*") %> </p> <p> <label for="Phone">Phone:</label> <%= Html.TextBox("Phone") %> Required <%= Html.ValidationMessage("Phone", "*") %> </p> <p> <label for="Email">Email:</label> <%= Html.TextBox("Email") %> Required <%= Html.ValidationMessage("Email", "*") %> </p> <p> <input type="submit" value="Create" /> </p> </fieldset><% } %><div> <%=Html.ActionLink("Back to List", "Index") %></div>
不同类型的输出
每一个Controller中负责回应的方法,都会回传一个ActionResult对象的信息,ActionResult是一个运行结果对象的封装体,当MvcHandler运行完指令接到ActionResult时,就会依照它的内容来输出数据。目前MVC Framework支持的ActionResult有下列几种:
透过多类型的ActionResult,开发人员可以自由决定要回传的数据的类型与格式。
目前微软有一个Oxite项目,是使用ASP.NET MVC Framework所开发的博客引擎,而这个项目已经被微软的部分应用平台所采用,像是MIX Online、PDC 2009、MIX Video等官方网站都采用它来开发。另外,stackoverflow.com以及codeplex.com这两个网站也是采用ASP.NET MVC Framework。
ASP.NET MVC Framework虽然是ASP.NET的一部分,不过它的源代码是透过Microsoft Public License (MS-PL)的授权模式公开,因此在MS-PL授权的范围内,任何人是可以去查看与修改它的源代码的。
微软在2010年7月2日由Scott Guthrie发表新的MVC绘制引擎 (Render Engine):Razor Engine,它已内置于 ASP.NET MVC 3.0 中发布,它具有下列功能:
相关
- 发夹环茎环(英语:Stem-loop,或译主干-循环)指一种分子内碱基配对方式,与因此形成的结构,可发生于单股DNA,但在RNA分子中较为常见。当形成的循环较小时,也称为发夹(hairpin)或发夹环。此种结
- 麝鹿麝,俗称香獐,在有角下目是现存最原始的科,种类少,无角,雄性有发达獠牙。麝属中有七个种,包括原麝、林麝、黑麝、喜马拉雅麝、安徽麝(原被认为是林麝的亚种)。、白腹麝(也常被称为喜玛
- COBE宇宙背景探测者(COBE),也称为探险家66号 ,是建造来探索宇宙论的第一颗卫星。他的目的是调查宇宙间的宇宙微波背景辐射(CMB),而测量和提供的结果将可以协助提供我们了解宇宙的形状,这
- 木鼻白蚁科木鼻白蚁科(Stylotermitidae)是属于白蚁的一个科,被认为是介于木白蚁科和鼻白蚁科演化间的族群,而曾经被归于鼻白蚁科之下。本科之下共包含三个属,其中木鼻白蚁属是唯一现存的族
- 丹尼尔·奥尔特加何塞·丹尼尔·奥尔特加·萨阿韦德拉(西班牙语:Jose Daniel Ortega Saavedra;1945年11月11日-)生于拉利伯塔德。尼加拉瓜桑地诺民族解放阵线的领袖,现任尼加拉瓜总统。1979年,桑地
- 美国国家象征美国国家象征(英语:National Symbols of the United States)指的是那些常常被使用作为美利坚合众国象征的事物。本文中罗列了多种可用作美利坚合众国象征的事物,部分由《美国法
- 伊东贵之伊东贵之(1962年8月-)是一名日本东洋学者、中国思想史研究者。専攻是中国近世思想史、日中比较文学・思想。目前担任国际日本文化研究中心教授・综合研究大学院大学教授。东京都
- 千千千千,本名洪千淑(1991年4月30日生),嘉义市崇仁医护管理专科学校五专部护理科毕业,曾担任台大医院研究护理师,已离职。现为台湾一位以大食量著名的Youtuber,亦是目前台湾订阅数最高
- 沈云沛沈云沛(1854年-1919年),字雨人,又字雨辰,江苏省海州直隶州(今属江苏连云港市海州区)人。清末民初政治人物。光绪二十年(1894年)甲午恩科第二甲第八十六名进士出身。同年五月,改翰林院庶
- 奈落之花《奈落之花》(日语:奈落の花),是日本女歌手岛宫荣子的第二张单曲,于2007年8月22日由Frontier Works发行,商品番号为FCCM-0193。总销售量29,144张,在Oricon周公信榜最高排行第12位。