ASP.NET MVC Framework

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物件是基于codice_1介面的规则所定义，提供针对HTTP要求做回应的一个执行工具，在ASP.NET MVC中已实作一个预设的类别 Controller，提供了必要的基础功能，另外也发展了一个 Controller 工厂，称为 Controller Factory，以codice_2介面定义，亦提供了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物件，像是下列程式码所示：
using System.Linq;
using System.Web.Mvc;
using System.Web;
using System;
 // GET: /Person/
 public ActionResult Index()
 return View(people);
 // GET: /Person/Details/5
 public ActionResult Details(Person person)
 return View(person);
 // GET: /Person/Create
 public ActionResult Create()
 return View();
 // POST: /Person/Create
 [AcceptVerbs(HttpVerbs.Post)]
 public ActionResult Create(Person person)
 if (!ModelState.IsValid)
 return View("Create", person);
 people.Add(person);
 return RedirectToAction("Index");
Public Class HomeController
 Inherits System.Web.Mvc.Controller
 'GET: /Person/
 Function Index() As ActionResult
 Return View(people)
 End Function
 'GET: /Person/Details/5
 Function Details(Person person) As ActionResult
 Return View(person)
 End Function
 'GET: /Person/Create
 Function Create() As ActionResult
 Return View()
 End Function
 'POST: /Person/Create
 &lt;AcceptVerbs(HttpVerbs.Post)&gt;
 Function Contact() As ActionResult
 If ModelState.IsValid Then
 Return View("Create", person)
 Else
 people.Add(person)
 Return RedirectToAction("Index")
 End If
 End Function
End Class
View物件以codice_3与codice_4等介面为主，并且以ASP.NET的各式前端介面为主要输出工具，基于MVC的View弹性化设计考量，以往在ASP.NET Web Form的程式码与HTML分离模式将不再存在，而是将程式码与HTML混合的方式设计，让开发人员可以更精确的对View进行控制，而目前 ASP.NET MVC 支援的 View 有下列几种：
每个 View 物件都会内含一个泛型的参数，用来装载要呈现的资料(即Model)，然后使用类似下面的方式来呈现资料：
&lt;%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html &gt;
&lt;head runat="server"&gt;
 &lt;title&gt;&lt;asp:ContentPlaceHolder ID="TitleContent" runat="server" /&gt;&lt;/title&gt;
 &lt;link href="../../Content/Site.css" rel="stylesheet" type="text/css" /&gt;
&lt;/head&gt;
&lt;body&gt;
 &lt;div class="page"&gt;
 &lt;div id="header"&gt;
 &lt;div id="title"&gt;
 &lt;h1&gt;My MVC Application&lt;/h1&gt;
 &lt;/div&gt;
 &lt;div id="logindisplay"&gt;
 &lt;% Html.RenderPartial("LogOnUserControl"); %&gt;
 &lt;/div&gt; 
 &lt;div id="menucontainer"&gt;
 &lt;ul id="menu"&gt; 
 &lt;li&gt;&lt;%= Html.ActionLink("Home", "Index", "Home")%&gt;&lt;/li&gt;
 &lt;li&gt;&lt;%= Html.ActionLink("About", "About", "Home")%&gt;&lt;/li&gt;
 &lt;/ul&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;div id="main"&gt;
 &lt;asp:ContentPlaceHolder ID="MainContent" runat="server" /&gt;
 &lt;div id="footer"&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
技术.
在ASP.NET MVC架构中，除了Controller、Model与View三个主要部份以外，还包含了许多技术以让这三层得以整合并交互运作。
Controller.
Controller在ASP.NET MVC应用程式中是负责中控的角色，也是来自用户端HTTP要求的处理核心，因此有许多处理与转向HTTP要求的辅助技术在Controller层次都会使用到。
ASP.NET 路由技术.
用来过滤用户端要求的URL，并借由定义好的路由表(route table)将要求导向至正确的MVC Controller，并呼叫Controller中的Execute方法执行，而Execute方法会将HTTP动作以及实际执行的指令交给正确的函式来执行。而通常一个MVC应用程式的URL都会是类似这样的URL格式：
而MvcRouteHandler会拆解URL，找出目标的Controller，并且将ActionName以及ActionParameters传给Controller中负责的函式（以ActionName来指定）。例如下列的URL会传递给BlogController的GetList方法：
动作与方法直接整合.
ASP.NET MVC利用了中介资料的技术，直接将方法对应到指定的 HTTP 动词 (GET/POST/PUT/DELETE/HEAD等)，MvcHandler会判断要求的类别，并将它交给URL中指定的方法来处理。目前MVC Framework可用下列的方式指定（均包含在 HttpVerbs 列举型别中）：
将资料模型与展示层直接包装.
codice_10、codice_11、codice_12等展示物件都支援泛型物件，可以直接装载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在伺服端资料验证中，提供了codice_13类别，这个类别中有一个ModelState属性，内含了codice_14类别，开发人员可以利用这个类别来控制资料验证的结果，而View中输出验证讯息的部份会和此类别有关联，例如下列的程式：
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Person person)
 if (person.Name.Trim().Length == 0)
 ModelState.AddModelError("Name", "Name is required.");
 if (person.Age &lt; 1 || person.Age &gt; 200)
 ModelState.AddModelError("Age", "Age must be within range 1 to 200.");
 if ((person.Zipcode.Trim().Length &gt; 0) &amp;&amp; (!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, @"^[\w-\.]+@([\w-]+\.)+[\w-]{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 {
 [MetadataType(typeof(ProductMD))]
 public partial class Product {
 public class ProductMD {
 [StringLength(50),Required]
 [StringLength(15)]
 [Range(0, 9999)]
View.
由于View是直接呈现给使用者，因此与使用者互动的部份都要由此层处理，包含资料的输出以及以用户端操作为主的回应（例如指令码）等。
HTML 工具类别.
HTML工具类别在View中是很重要的输出工具，它内建了辅助产生HTML标签的工具方法，多数的HTML语法都可以利用它来产生，包含像连结()、表单(&lt;form&gt;)以及表单控制项等等。HTML工具是以codice_15类别为核心，并配合System.Web.Mvc.Html命名空间的方法，以延伸方法(Extension Method)的方式，让产生HTML的程式就有如呼叫方法般简单：
&lt;h2&gt;Index&lt;/h2&gt;
&lt;table&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;
 Id
 &lt;/th&gt;
 &lt;th&gt;
 Name
 &lt;/th&gt;
 &lt;/tr&gt;
&lt;% foreach (var person in Model) { %&gt;
 &lt;tr&gt;
 &lt;td&gt;
 &lt;%= Html.ActionLink("Details", "Details", person )%&gt;
 &lt;/td&gt;
 &lt;td&gt;
 &lt;%= Html.Encode(person.Id) %&gt;
 &lt;/td&gt;
 &lt;td&gt;
 &lt;%= Html.Encode(person.Name) %&gt;
 &lt;/td&gt;
 &lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;
 &lt;%= Html.ActionLink("Create New", "Create") %&gt;
&lt;/p&gt;
资料验证.
View的HTML工具可以配合Model处理资料验证的结果，在ASP.NET中常用的ValidationSummary在这里也支援，而且MVC的架构让验证资讯的输出也更加弹性：
&lt;h2&gt;Create&lt;/h2&gt;
&lt;%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %&gt;
&lt;% using (Html.BeginForm()) {%&gt;
 &lt;fieldset&gt;
 &lt;legend&gt;Fields&lt;/legend&gt;
 &lt;p&gt;
 &lt;label for="Name"&gt;Name:&lt;/label&gt;
 &lt;%= Html.TextBox("Name") %&gt; Required
 &lt;%= Html.ValidationMessage("Name", "*") %&gt;
 &lt;/p&gt;
 &lt;p&gt;
 &lt;label for="Age"&gt;Age:&lt;/label&gt;
 &lt;%= Html.TextBox("Age") %&gt; Required
 &lt;%= Html.ValidationMessage("Age", "*") %&gt;
 &lt;/p&gt;
 &lt;p&gt;
 &lt;label for="Street"&gt;Street:&lt;/label&gt;
 &lt;%= Html.TextBox("Street") %&gt;
 &lt;%= Html.ValidationMessage("Street", "*") %&gt;
 &lt;/p&gt;
 &lt;p&gt;
 &lt;label for="City"&gt;City:&lt;/label&gt;
 &lt;%= Html.TextBox("City") %&gt;
 &lt;%= Html.ValidationMessage("City", "*") %&gt;
 &lt;/p&gt;
 &lt;p&gt;
 &lt;label for="State"&gt;State:&lt;/label&gt;
 &lt;%= Html.TextBox("State") %&gt;
 &lt;%= Html.ValidationMessage("State", "*") %&gt;
 &lt;/p&gt;
 &lt;p&gt;
 &lt;label for="Zipcode"&gt;Zipcode:&lt;/label&gt;
 &lt;%= Html.TextBox("Zipcode") %&gt;
 &lt;%= Html.ValidationMessage("Zipcode", "*") %&gt;
 &lt;/p&gt;
 &lt;p&gt;
 &lt;label for="Phone"&gt;Phone:&lt;/label&gt;
 &lt;%= Html.TextBox("Phone") %&gt; Required
 &lt;%= Html.ValidationMessage("Phone", "*") %&gt;
 &lt;/p&gt;
 &lt;p&gt;
 &lt;label for="Email"&gt;Email:&lt;/label&gt;
 &lt;%= Html.TextBox("Email") %&gt; Required
 &lt;%= Html.ValidationMessage("Email", "*") %&gt;
 &lt;/p&gt;
 &lt;p&gt;
 &lt;input type="submit" value="Create" /&gt;
 &lt;/p&gt;
 &lt;/fieldset&gt;
&lt;div&gt;
 &lt;%=Html.ActionLink("Back to List", "Index") %&gt;
&lt;/div&gt;
不同类型的输出.
每一个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授权的范围内，任何人是可以去检视与修改它的原始码的。
ASP.NET MVC Razor Engine.
微软在2010年7月2日由Scott Guthrie发表新的MVC绘制引擎 (Render Engine)：Razor Engine，它已内建于 ASP.NET MVC 3.0 中发布，它具有下列功能：