随着对Web应用程序功能需求的日益增长,与特定Web应用程序相关联的文件的数量有可能会急剧增长。在Web窗体应用程序中,网页通常分为若干个子文件夹,每个子文件夹代表这些网页集合中的一个逻辑分组。另一方面,Web表单项目模板有可能使用任意的文件夹结构来进行文件组织。
ASP.NET MVC按照既定惯例进行管理。因此,对应的文件夹结构比较严格,你甚至可以照搬照抄使用,所有网页都被划分为根文件夹Views下的一些子文件夹,每一个子文件夹与Controllers文件夹中的每个控制器名称相匹配。例如,“Organizations”控制器就在“Views”文件夹下有一个对应的“Organizations”文件夹,所有ASPX网页描述了对应于Organizations控制器的视图。图1给出了一个这样的可能的示例文件夹结构:
图1—示例MVC工程结构
虽然上述过程可以允许稍微的定制,但是由于约定惯例文件夹结构还是保持比较严格的组织方式。最新版本的MVC 2.0中在上述约定中添加了一个区段(Area)的新概念。这样一来,在严格的ASP.NET MVC框架和逻辑组件分离之间就出现了一种平衡机制。理解这一点最简单的方式就是观察一下一个示例工程的文件夹结构。下面给出的是与前面的图1同一样的项目,但是经过使用内联区段技术进行了重新布局。
图2—使用内联式区段
内联项目区段允许ASP.NET MVC项目在维持控制器、模型和视图文件夹结构的同时,还对逻辑组件进行相互的分离,但是核心项目实施与Organizations区段是分离开来的。应用程序的区段可以允许出现重复的控制器类命名、模型类名字、视图命名等,但各个区段还可以共享“Shared”文件夹下的资源。
你可能看到,在上面图1和图2中给出的两个文件夹架构例子中,文件夹架构略微改变了一下。图1中只有一个organization控制器,现在有了一个organization区段,在连接中出现了另一个级别的层次结构。现在,针对/Organizations/Index的请求被路由到/Organizations/Management/Index之下。
一、路由
ASP.NET MVC中视图之间使用的默认的路由机制都是按照惯例执行的。例如,在图1中,到Manage行为的链接将会产生下列的行为链接声明,这样会生成一个重定向到主项目中的Organizations控制器的超链接。
清单1—将目标锁定在Organizations控制器中的Manage视图上
new { controller = "Organizations", key = 1 })
第一个参数指定链接文本,而最后三个参数依次指定要调用的行为方法、行为方法所在的控制器和路由参数,这些参数就像查询字符串一样进行传递(除非在路由中指定参数)。
区段概念的引入对上述情形进行了一些改变,因为我们需要能够区分希望路由到的区段。要实现这一点是很简单的,我们只需要把一个额外的区段对应的键/值对添加到路由参数列表中。为了路由到如清单2所示的新的内联段中,我们可以使用下面的语法:
清单2—将目标锁定在Organizations区段上的Management控制器中的Manage视图上
new { area = "Organizations" key = 1 })
一个区段目标指定了要导航到的正确区段。不使用这种办法,链接将导航到主项目中的ManagementController控制器,但这个控制器是不存在的。在上面的代码中,我们新增加了area = "Organizations",从而实现把所有请求正确路由到区段范围内的控制器上。
但是,要实现这一目标还需要几个步骤—需要使用一个称为AreaRegistration的新的对象。我们需要针对区段使用一个定制的注册过程,如清单3所示。
清单3—注册一个区段的代码举例
{
public override string AreaName
{
get
{
return "Organizations";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Organizations_default",
"Organizations/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
这里,RegisterArea是实现注册的关键组件,通过把另一个路由添加到区段路由集合中实现。请注意,这里的区段名Organizations是以硬编码方式添加到URL中;因此,所有使用此区段名称作为前缀的请求都被进行特别路由处理。
你可能感到疑惑:为什么我们不能在主应用程序的路由定义中指定Organizations部分?实际上,如果我们将它加入到标准的路由表中,而不通过区段上下文,那么,我们还是把所有文件驻留到同一个项目中,从而失去了首先分离项目区段的好处(即区段失败了作用)。
二、多项目区段
尽管不直接为ASP.NET MVC 2所支持,但是在测试版本的ASP.NET MVC中,仍然支持多项目区段,即通过区段把一个大项目分成多个子项目。一个单独的ASP.NET MVC项目可以被看作是一个区段,其工作方式就像一个嵌入式区段一样。这种方法非常类似于嵌入式工程区段,当然还要在MVC项目中进行一些额外的设置工作。
上述额外的设置功能需要使用一种技术,即复制项目内容并在主项目中布署它们,主要是把外部项目区与主ASP.NET MVC项目进行合并。借助于ASP.NET MVC未来程序集的一部分,框架会自动地通过一个MSBuild任务为你完成这项工作。有一个称为Microsoft.Web.Mvc.Build.dll的程序集负责执行此过程。
注意:上述功能不被微软官方所支持。但是,如果你想尝试利用此安装程序的话,下面的资源将有助于你实现定制的项目构建任务:
• http://msdn.microsoft.com/en-us/library/ee307987%28VS.100%aspx
• http://dotnetslackers.com/articles/aspnet/a-first-look-at-asp-net-mvc-2.aspx
至于微软方面,到目前为止仅支持单个项目区段。
三、我的看法
“区段”概念的引入有助于实现内容的分离,但因为各种各样的原因,我的建议是不要过度使用这一概念。首先,“区段”的引入的确增加了项目范围内的文件的数量。保持尽可能小的项目文件数目将有助于保持应用程序的可维护性。当然我不是反对使用区段技术,只是推荐在项目规模和实现内容逻辑分离之间要保持一个适度的平衡为最好。
使用区段带来的一个很好的特性是,你可以为视图设置具有类似命名的控制器,从而使得整个网站感觉是一致的。例如,区段accounts,store和catalog可以使用一致的URL,通过给予每一个区段类似命名的控制器和行为来实现。例如,你的网站可以使用如下的组织方式:
/Store/Search/Index
/Catalog/Search/Index
虽然一致性不是必需的,但是它可以帮助用户更容易地在你的网站中导航—通过使用类似的设置(假定每个视图都提供类似的功能)。
四、结论
“区段”概念的引入有助于实现内容的分离,并能够改变路由过程工作的方式。区段有自己的文件夹结构并能够实现把他们自己的控制器要求路由到对应的视图。路由需要使用一个新的区段路由参数,以便路由到正确的区段上。
转自: http://tech.it168.com/a2010/0901/1098/000001098030_1.shtml