ASP.NET MVC:理解模型、视图和控制器

时间:2023-02-03 22:27:01

ASP.NET MVC应用程序示例

用Visual Studio默认模板创建ASP.NET MVC Web应用程序时,会附带创建一个非常简单的实例程序,可以用来帮助理解ASP.NET MVC程序中的各个组成部分,本文我们就用这个示例进行讲解。

在Visual Studio 2008中点击“文件” > “新建项目”,选择“ASP.NET MVC”模板创建一个ASP.NET MVC应用程序,如图1所示,在新建项目对话框中,在项目类型下选择你熟悉的编程语言,如Visual Basic 或 C#,然后在模板下选择“ASP.NET MVC Web Application”模板,点击确定按钮。

 
1 新建项目对话框

你在创建一个新的ASP.NET MVC应用程序时,会显示一个创建新的单元测试项目对话框,如图2所示,这个对话框让你可以单独为你的方案创建一个项目测试你的ASP.NET MVC应用程序,这里选择选项“不,不创建测试项目”,然后点击确定按钮。

 
2 创建单元测试对话框

创建好ASP.NET MVC应用程序后,在方案浏览窗口你会看到有几个文件夹和文件,特别地,你会看到模型(Models)、视图(Views)和控制器(Controllers)三个文件夹,正如你从这些文件夹的名字猜测到的,这些文件夹包括了模型、视图和控制器的实现文件。

如果你展开控制器文件夹,应该会看到一个名叫HomeController.vb的文件,如果你展开视图文件夹,应该会看到两个子文件夹,一个是Home,一个Shared,如果你展开Hom文件夹,你应该会看到两个文件:about.aspx和Home.aspx(如图3所示)。这些文件就组成了使用ASP.NET MVC默认模板创建的应用程序。

 
3 方案浏览窗口

通过选择菜单项“调试” > “开始调试”,可以运行这个示例程序,同样,按F5键也一样。

当你第一次运行ASP.NET MVC应用程序时,会显示图4所示的对话框,建议你开启调试模式,点击确定按钮后程序开始运行。

 

当你运行ASP.NET MVC应用程序时,Visual Studio会在你的浏览器中启动应用程序,示例应用程序由两个页面组成:Index页面和About页面。当应用程序第一次启动时显示Index页面(如图5所示),你可以点击程序右上角链接切换到About页面。

 
4 调试没有开启对话框

注意浏览器地址栏中的URL,当你点击Home链接时,浏览器地址栏中的URL改变为/Home,当你点击About链接时,URL改成/About。

如果你关掉浏览器返回Visual Studio窗口,你看不到有Home和About文件存在,怎么可能呢?

一个URL不等于一个页面

当你构建一个传统的ASP.NET Web窗体应用程序或ASP应用程序时,一个URL就对应一个页面,它们是一对一的关系,如果你向服务器请求一个名叫SomePage.aspx的页面,那么在硬盘上都有一个文件的名字叫做SomePage.aspx,如果不存在这个文件,就会返回一个404 - Page Not Found的错误。

相反,在构建ASP.NET MVC应用程序时,URL和页面就不是一一对应关系了,在ASP.NET MVC应用程序中,一个URL对应一个控制器行为,而不是硬盘上的一个页面文件。

在传统ASP.NET和ASP应用程序中,浏览器请求被映射到页面,在ASP.NET MVC应用程序中,浏览器请求映射到控制器行为,ASP.NET应用程序是以内容为中心,相反,ASP.NET MVC应用程序是以应用逻辑为中心。

理解URL路由

浏览器请求通过ASP.NET MVC的一个叫做URL路由的特性映射到控制器行为,URL路由路由入站请求给控制器行为。

URL路由使用路由表处理入站请求,当你的应用程序第一次启动时创建这个路由表,路由表配置在Global.asax文件中,默认的MVC Global.asax文件内容如清单1所示。

清单1 Global.asax

Public Class GlobalApplication 
Inherits System.Web.HttpApplication

Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
routes.IgnoreRoute("{resource}.axd/{*pathInfo}")
’ MapRoute takes the following parameters, in order:
’ (1) Route name
’ (2) URL with parameters
’ (3) Parameter defaults
routes.MapRoute( _
"Default", _
"{controller}/{action}/{id}", _
New With {.controller = "Home", .action = "Index", .id = ""} _
)
End Sub

Sub Application_Start()
RegisterRoutes(RouteTable.Routes)
End Sub
End Class

当一个ASP.NET应用程序第一次启动时,会调用Application_Start()方法,在清单1中,这个方法叫做RegisterRoutes()方法,RegisterRoutes()方法创建默认路由表。

默认路由表只有一条路由记录,它将所有入站请求分成三段,第一段映射到控制器名字,第二段映射到行为名字,最后一段映射到传递给行为的参数Id。

如下面的URL:

/Product/Details/3

这个URL被解析成下面三部分:

Controller = ProductController

Action = Details

Id = 3

注意后缀Controller跟在Controller参数的结尾,这仅仅是MVC的一个怪癖。

默认路由包括了这三段的默认值,默认控制器是HomeController,默认行为是Index,默认Id是空字符串,使用默认值时,思考一下下面的URL该如何解析:

/Employee

这个URL被解析成下面三段:

Controller = HomeController

Action = Index

Id = “”

请求被路由到HomeController类的Index()行为。

理解控制器

控制器控制用户与ASP.NET MVC应用程序交互的方式,由控制器决定向发送了请求的用户返回什么内容。

控制器就是一个类,ASP.NET MVC示例应用程序在控制器文件夹下只包括了一个名叫HomeController.vb的控制器,HomeController.vb的内容如清单2所示。

清单2 HomeController.vb

Public Class HomeController 
Inherits System.Web.Mvc.Controller

Function Index()
ViewData("Title") = "Home Page"
ViewData("Message") = "Welcome to ASP.NET MVC!"
Return View()
End Function

Function About()
ViewData("Title") = "About Page"
Return View()
End Function
End Class

注意HomeController有两个方法(函数):Index()和About(),这两个方法对应控制器暴露的两个行为,URL /Home/Index调用HomeController.Index()方法,URL /Home/About调用
HomeController.About()方法。

控制器中所有公共方法都是以控制器行为方式暴露的,这意味着任何在浏览器地址栏敲入对应的URL都可以调用这些方法,这一点需要注意。

理解视图

HomeController类暴露了两个控制器行为:Index()和About(),它们返回的都是一个视图。视图包括HTML标记和发送给浏览器的内容,在ASP.NET MVC应用程序中,一个视图就相当于一个页面。

你必须在正确的位置创建你的视图,HomeController.Index()行为返回位于下列路径的视图:

/Views/Home/Index.aspx

HomeController.About()行为返回位于下列路径的视图:

/Views/Home/About.aspx

通常,如果你想为控制器行为返回一个视图,你必须在视图文件夹下创建一个与控制器名字相同的子文件夹,在这个子文件夹中,还必须创建一个与控制器行为同名的.aspx文件。

清单3中显示了About视图文件的内容。

清单3 About.aspx

<%@ Page Language="VB" MasterPageFile="~/Views/Shared/
Site.Master" AutoEventWireup="false" CodeBehind="About.aspx.vb" Inherits="MvcA
pplication1.About" %> <asp:Content ID="aboutContent" ContentPlaceHolderID="MainC
ontent" runat="server"> <h2>About Us</h2>
<p>
TODO: Put <em>about</em> content here.
</p>
</asp:Content>

如果你忽略清单3中的第一行,视图剩下的部分呢内容都是标准的HTML,你可以在里面添加任何需要的HTML内容。

视图和ASP页面或ASP.NET Web窗体非常类似,视图可以包括HTML内容和脚本,你可以用你熟悉的.NET编程语言(如c#或VB .NET)编写脚本,使用脚本来显示动态内容,如数据库数据。

理解模型

我们已经讨论了控制器和视图,我们要讨论的最后一个主题是模型,什么是MVC模型呢?

MVC模型包括应用程序的所有逻辑,这些逻辑在视图和控制器都是没有的,模型应该包括应用程序所有的业务逻辑和数据库访问逻辑,例如,如果你使用LINQ到SQL访问你的数据库,那么你就应该在模型(Models)文件夹下创建LINQ到SQL的类(dbml文件)。

视图应该只包括与用户接口有关的逻辑,控制器应该只包括暴露给请求返回正确视图的最小逻辑或将用户重定向到另一个控制器行为的逻辑,除此之外其它任何逻辑都应该包括在模型中。
通常,你应该为控制器减肥,为模型增肥,控制器方法应该只包括很少的代码,如果控制器行为太臃肿了,你应该思考如何将其中隐含的逻辑迁移到模型中去。

小结

本文向你介绍了ASP.NET MVC各个不同部件之间的差异,并且学习了URL路由如何将入站请求路由到合适的控制器行为的,还学习了视图是如何返回给浏览器的,最后还介绍了模型应该包括哪些业务逻辑和数据库访问逻辑。