MVC有关的核心命名空间主要有以下几个
1) System.Web.Routing
URL路由在该命名空间下提供了使用URL路由功能的类,它可以将一个URL路由映射对应到Controller上,而不是映射到一个物理文件。
2) System.Web.Extensions
这是ASP.NET Ajax的命名空间,在MVC中使用Ajax功能时需要引用。
3) System.Web.Mvc
这是ASP.NET MVC最主要的命名空间。该命名空间包含一些类和接口,它们支持用于创建Web应用程序的ASP.NET MVC框架。该命名空间包含表示控制器、控制器工厂、操作结果、视图、分部视图以及模型编译等的类。
4) System.Web.Abstractions
该命名空间包含一些相关的基类,例如HttpContextBase和HttpRequestBase等。
5) System.Web.DynamicData
该命名空间包含为 ASP.NET 动态数据提供核心功能的类。另外,它还提供允许自定义动态数据行为的扩展性功能。
创建ASP.NET MVC Web应用程序项目时,MVC组件会按项目文件夹自动分开,如图1-4所示。
![]() |
图1-4 |
默认情况下,MVC应用程序目录结构包括以下文件夹。
引用
App_Data
Content
Controllers
Models
Scripts
Views
默认情况下,当ASP.NET MVC框架加载视图时,它将在"Views\控制器名称"文件夹中寻找具有请求的视图名称的ViewPage (.aspx)文件。默认情况下,Views文件夹中也有一个名为Shared的子文件夹,但该文件夹不与任何控制器对应。
Shared文件夹用于存储在多个控制器之间共享的视图。例如,我们可以将Web应用程序的母版页放在Shared文件夹中。
除了使用前面列出的文件夹之外,ASP.NET MVC Web应用程序还使用Global.asax文件中的代码来设置全局URL路由默认值,并且使用Web.config文件来配置应用程序。
路由在Global.asax文件的Application_Start方法中初始化
默认的路由表中包含一个路由,该默认路由将所有进入的请求拆分为3个单元(URL 单元是正斜杠之间的所有内容)。第一个单元映射到控制器名称,第二个单元映射到操作名称,最后一个单元映射到传递给操作名称 ID 的参数。
例如,考虑下面的URL:
- /Product/Details/3
此URL被解析为如下3个部分:
- Controller
= ProductController - Action
= Details - Id
= 3
前缀控制器将被附加到控制器参数的末端,这只是MVC的一个特殊之处。
默认路由包括所有3个单元的默认值。默认控制器是HomeController,默认操作是Index,而默认ID是一个空字符串。观察这些默认值,考虑如何解析下面的 URL:
- /Employee
此URL被解析为如下3个参数:
- Controller
= EmployeeController - Action
= Index - Id
= “”
最后,如果打开ASP.NET MVC应用程序而不提供任何URL(例如http://localhost/),那么URL将被解析为:
- Controller
= HomeController - Action
= Index - Id
= “”
在构建传统的ASP.NET WebForm应用程序时,URL和页面是一一对应的。如果从服务器上请求名称为Index.aspx的页面,则硬盘上最好有名称为Index.aspx的页面。如果Index.aspx文件不存在,则将出现404 - Page Not Found错误。
相反,在构建ASP.NET MVC应用程序时,在浏览器地址栏中键入的URL和应用程序中的文件不存在对应关系。在ASP.NET MVC应用程序中,URL对应的是控制器操作,而不是硬盘上的页面。
还有,在传统的ASP.NET应用程序中,浏览器请求是映射到页面上的。在ASP.NET MVC应用程序中,浏览器请求是映射到控制器操作。ASP.NET WebForm应用程序关注的是内容,而ASP.NET MVC应用程序关注的则是应用程序逻辑。
视图
由HomeController类中公开的两个控制器方法Index()和About()都返回一个视图。视图包括发送到浏览器的HTML标记和内容。在使用ASP.NET MVC应用程序时,视图等于页面。
因此,必须在正确的位置创建视图。HomeController.Index()操作返回位于以下路径的视图:
- \Views\Home\Index.aspx
HomeController.About()操作返回位于以下路径的视图:
- \Views\Home\About.aspx
总之,如果要为控制器操作返回视图,则需要在Views文件夹中使用与控制器相同的名称创建子文件夹。在子文件夹中,必须创建与控制器操作名称相同的.aspx文件。
视图非常类似于ASP.NET WebForm的页面,视图包括HTML内容和脚本,可以使用我们熟悉的.NET编程语言(如C#或Visual Basic .NET)来编写脚本。可以使用脚本显示动态内容,例如数据库中的数据。
模型
MVC模型包含所有视图或控制器不包含的应用程序逻辑。模型应该包含所有应用程序业务逻辑和数据库访问逻辑。例如,如果正在使用 LINQ to SQL 访问数据库,那么将在Models文件夹中创建LINQ to SQL类(dbml文件)。
视图应该只包含与生成用户界面相关的逻辑。控制器应该只包含要求返回正确视图或者将用户重定向到另一操作所需的最小逻辑,其他所有内容都应包含在模型中。总之,应该努力实现高效模型和简化控制器。控制器方法应该只包含几行代码。如果控制器操作过长,则应该考虑将逻辑移动到Models文件夹下的一个新类中。
ASP.NET MVC与WebForm相比,最大的优势就是当应用程序日益复杂时,可以通过分离模型、视图和控制器来进行单元测试。从而使开发者更容易、及时地发现问题。
- protocol
:// hostname[:port] [/path] [?parameters][#fragment]
URL各部分的说明如下。
protocol
hostname
port
path
parameters
fragment
自定义URLRouting规则。
首先,先预计我的博客需要有以下几种URL格式。
Blog.mvc/2010-11-07
Photo/life.private
Photo/2010/work
Article/Show/aspnet
Home/Index/32
了解过了需求,下面着手编写路由代码。为了节省篇幅,这里直接贴出所有配置代码,如下所示:
- //
Blog.mvc/2010-11-07 - routes.MapRoute(
-
"BlogRoute", -
"Blog.mvc/{date}", -
new { controller = "Blog", action = "List" }, -
new { date = @"^\d{4}-\d{2}-\d{2}" }); -
- //
Photo/life.private - routes.MapRoute(
-
"PhotoRoute", -
"Photo/{make}.{model}", -
new { controller = "Picture", action = "Show" }, -
new { model = @"(private|public)" }); -
- //
Photo/2010/work - routes.MapRoute(
-
"PhotoRoute2", -
"Photo/{*values}", -
new { controller = "Photo", action = "Index" }, -
null); -
- //
Article/Show/aspnet - routes.MapRoute(
-
"ArticleRoute", -
"Article/Show/{key}", -
new { controller = "Article", action = "List" }, -
new { httpMethod = "POST" }); -
- //
Article/Show/aspnet - routes.MapRoute(
-
"ArticleRoute2", -
"Article/Show/{key}", -
new { controller = "Article", action = "List" }, -
new { }); -
- //
Home/Index/32 - routes.MapRoute(
-
"Default", -
"{controller}/{action}/{id}", -
new { controller = "Home", action = "Index", id = "0" }, -
new { controller = @"^\w+", action = @"^\w+", id = @"^\d+" }); - 需要注意的是路由规则中的名称参数不可以重复。