[翻译:ASP.NET MVC 教程]理解模型、视图和控制器
本篇教程为你提供了ASP.NET MVC的模型、视图和控制器的高级概述。换句话说,即本文向你解释了在ASP.NET MVC中“M”、“V”和“C”具体内容。
阅读本教程后,你应当能够理解ASP.NET MVC应用程序的不同部分是怎样一同工作的。同时,你也能明白ASP.NET MVC应用程序架构与ASP.NET Web Forms应用程序或Active Server Pages应用程序是不同的。
简易的ASP.NET MVC应用程序
创建ASP.NET MVC Web应用程序的默认Visual Studio模板包含了一个被用来了解ASP.NET MVC应用程序不同组成部分的极为简易的示例程序。
启动Visual Studio 2008,用MVC模板新建一个ASP.NET MVC应用程序,然后选择菜单选项File, New Project(见图1)。在新建项目对话框中,在Project Types栏下选择你所使用的编程语言(Visual Basic或C#),然后在Templates栏下选择ASP.NET MVC Web Application。点击OK按钮。
图1:新建项目对话框
当你创建ASP.NET MVC应用程序时,Create Unit Test Project对话框会出现(见图2)。该对话框能让你在你的解决方案中创建一个独立的项目来测试你的ASP.NET MVC应用程序。选择选项No, do not create a unit test project,然后点击OK按钮。
图2:创建单元测试对话框
在新ASP.NET MVC应用程序创建后,你会在解决方案浏览窗口中看见一些文件夹和文件。个别的说,你将看见三个名为Models、Views和Controllers的文件夹。正如你从文件夹名猜到的那样,三个文件夹包含了实现模型、视图和控制器的文件。
如果你展开Controllers文件夹,你应当能看见名为AccountController.cs的文件和名为HomeController.cs的文件。如果你展开Views文件夹,你应当能看见名为Account、Home和Shared的三个子文件夹。如果你展开Home文件夹,你应当能看见名为About.aspx 和Index.aspx的两个附加文件(见图3)。这些文件组成了包含在默认ASP.NET MVC内的简易应用程序。
图3:解决方案浏览窗口
你可以运行该简易程序通过选择菜单选项Debug, Start Debugging或者按下F5键。
当你首次运行ASP.NET应用程序时,图4中的对话框会出现并推荐你开启调试模式。点击OK按钮,运行程序。
图4:调试未启用对话框
当你运行ASP.NET MVC应用程序时,Visual Studio在你的浏览器中启动该程序。该简易程序仅有两个页面:Index页面和About页面组成。当应用程序首次运行时,Index页面会出现(见图5)。你可以通过点击应用程序右上角的菜单链接导航至About页面。
图5:Index页面
注意到你浏览器地址栏中的URLs的变化。例如,当你点击About菜单链接时,浏览器地址栏中的URL将转变为/Home/About。
如果你关闭浏览器窗口并返回至Visual Studio,你将不能找到带有路径Home/About的文件。该文件不存在。这怎么可能呢?
一个URL不等于一个页面
当你构建一个传统的ASP.NET Web Forms应用程序或一个Active Server Pages应用程序时,在URL和页面之间具有一对一对等的关系。如果你从服务器请求一个名为SomePage.aspx的页面,那么服务器上就应当有一个名为SomePage.aspx的页面。如果SomePage.aspx文件不存在,你将会得到一个难看的404 – Page Not Found错误。
当构建一个ASP.NET MVC应用程序时,相反的,你输入浏览器地址栏的URL和在你应用程序中的文件并没有对等关系。在ASP.NET MVC应用程序中,一个URL对等于一个控制器动作而不是位于磁盘上的页面。
在传统的ASP.NET或ASP应用程序中,浏览器请求被映射到页面。在ASP.NET MVC应用程序中,相反的,浏览器请求被映射到控制器动作。一个ASP.NET Web Forms应用程序是以内容为中心的。一个ASP.NET MVC应用程序,相反的,是以业务逻辑为中心的。
理解ASP.NET路由
浏览器请求通过一个被称为ASP.NET Routing(ASP.NET路由)的ASP.NET框架特性被映射到一个控制器动作中。ASP.NET MVC framework 使用ASP.NET路由来将进来的请求路由至控制器动作。
ASP.NET路由使用路由表来处理进来的请求。该路由表创建于Web应用程序首次启动时。该路由表安排在Global.asax文件中。默认的MVC Global.asax文件包含在清单1中。
清单1——Global.asax
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace MvcApplication1
{
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
}
当一个ASP.NET 应用程序首次启动时,Application_Start()方法即被调用。在清单1中,该方法调用RegisterRoutes()方法,然后RegisterRoutes()方法创建了默认路由表。
默认路由表由一个路由组成。该默认路由将所有进来的请求分解为三个部分(一个URL部分是由 “/”之间的内容组成的。)第一部分被映射到控制器名称,第二部分被映射到动作名称,最后一部分被映射到被传送至动作的名为Id的参数。
例如,考虑如下的URL:
/Product/Details/3
该URL像这样被解析为三部分:
Controller = Product
Action = Details
Id = 3
在Global.asax定义的默认路由为这三个参数设定了默认值。默认控制器为Home、默认动作为Index以及默认Id为一个空字符串。记住这些默认值,考虑下列URL是怎样被解析的:
/Employee
该URL像这样被解析为三个参数:
Controller = Employee
Action = Index
Id = ??
最后,如果你打开一个不提供任何URL的ASP.NET MVC应用程序(例如,http://localhost/),那么该URL将会像这样被解析为:
Controller = Home
Action = Index
Id = ??
该请求被路由至HomeController类中的Index()动作。
理解控制器
控制器负责控制用户与MVC应用程序交互的方法。一个控制器包含了对于ASP.NET MVC应用程序的控制逻辑流。当一个用户发出浏览器请求时,控制器决定向该用户发送回何种回应。
一个控制器就是一个类(例如,一个Visual Basic或C# 类)。ASP.NET MVC例程在Controllers文件夹下包含了一个名为HomeController.cs的控制器。HomeController.cs文件的内容如清单2所示。
清单2——HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Title"] = "Home Page";
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult About()
{
ViewData["Title"] = "About Page";
return View();
}
}
}
注意到HomeController有两个名为Index()和About()的方法。这两个方法对等于控制器中的两个动作。URL /Home/Index请求调用HomeController.Index()方法,URL /Home/About请求调用HomeController.About()方法。
任何在控制器中的公用方法都被作为一个控制器动作。你需要对此谨慎。这意味着包含在控制器中的任何公用方法都能被通过在浏览器中输入正确URL的连接到Internet的任意一人请求调用。
理解视图
位列于HomeController类中的两个控制器行为——Index()和About(),都返回一个视图。视图包含了HTML标签以及被发送至浏览器的内容。一个视图等价于一个正在ASP.NET MVC应用程序中工作的一个页面。
你必须将视图创建在正确的位置。HomeController.Index()动作返回了位于下列路径的一个视图:
\Views\Home\Index.aspx
HomeController.About()动作返回了位于下列路径的一个视图:
\Views\Home\About.aspx
一般而言,如果你想针对一个控制器动作返回一个视图,那么你需要在Views文件夹下创建一个与你的控制器名称相同的子文件夹。在该子文件夹中,你必须创建一个与你的控制器动作名称相同的.aspx文件。
清单3中的文件包含了About.aspx视图的内容。
清单3——About.aspx
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="aboutContent" ContentPlaceHolderID="MainContent" runat="server">
<h2>About</h2>
<p>
Put content here.
</p>
</asp:Content>
如果忽略掉清单3中的首行,你会发现视图中的剩余部分的大多数都是由标准的HTML组成的。你可以通过键入任何你想要的HTML代码来修改该视图的内容。
一个视图与位于Active Server Pages或ASP.NET Web Forms中的一个页面是十分类似的。视图能包含HTML内容及脚本代码。你可用你最擅长的编程语言(例如,C#或Visual Basic)来编写脚本代码。你用这些脚本来显示动态内容,诸如数据库数据等。
理解模型
我们之前已讨论了控制器及视图。最后一个需要讨论话题便是模型。一个MVC模型是什么呢?
一个MVC模型包含了所有你应用程序中不包含在视图及控制器中的业务逻辑。该模型应当包含你应用程序的所有商业逻辑、验证逻辑以及数据库连接逻辑。例如,如果你使用Microsoft Entity Framework来连接到你的数据库,那么你就在Models文件夹下创建了你的Entity Framework类(.edmx文件)。
视图应当只能包含有关生成用户界面的业务逻辑。控制器应当只包含被要求返回至正确的视图或让用户重新导向至另一个动作(控制流)的最精简的业务逻辑。
一般来说,你应当力争做到“胖模型”和“瘦控制器”。你的控制器方法应当只包含少量代码。如果控制器动作代码数量巨大,那么你应当考虑将该业务逻辑移出至Models文件夹下的一个新类中。
小结
本篇教程为你提供了ASP.NET MVC Web应用程序不同部分的高级概述。你了解了ASP.NET Routing是怎样将进来的浏览器请求映射至指定的控制器动作中的,了解到控制器是怎样精心安排传回浏览器的视图的。最后,你了解到模型是怎样包含应用程序的商业逻辑、验证逻辑和数据库连接逻辑的。
文章出处:Kinglee’s Blog (http://www.cnblogs.com/Kinglee/)
版权声明:本文的版权归作者与博客园共有。转载时须注明本文的详细链接,否则作者将保留追究其法律责任。