(转)ASP.NET Mvc 2.0 - 1. Areas的创建与执行
转自:http://www.cnblogs.com/terrysun/archive/2010/04/13/1711218.html
ASP.NET Mvc 2.0 - 1. Areas的创建与执行
Areas是ASP.NET Mvc 2.0版本中引入的众多新特性之一,它可以帮你把一个较大型的Web项目分成若干组成部分,即Area。实现Area的功能可以有两个组织形式:
- 在1个ASP.NET Mvc 2.0 Project中创建Areas。
- 创建多个ASP.NET Mvc 2.0 Project,每个Project就是一个Area。
第2种结构比较复杂,但第1种结构同样可以做到每个Area之间的并行开发,互不影响,所以不推荐第2种方法。
以ASP.NET Mvc 2.0的默认模板为例:
1. 首先要新建一个ASP.NET Mvc 2.0的Project,在Project上点击鼠标右键选择Add->Area,在打开的窗口中输入Area的名子(例如:Profile),点击Add按钮,然后将看到下面的结构。![]()
名子叫做Profile的Area的结构与根目录下的Controllers,Models和Views的结构是一样的,唯一区别是Profile下面多了一个ProfileAreaRegistration.cs文件。它继承自AreaRegistration类,ProfileAreaRegistration 必须实现AreaRegistration类中的AreaName属性和RegisterArea(AreaRegistrationContext context)方法
using System.Web.Mvc; namespace ASP.NET_Mvc_2_Test.Areas.Profile
{
public class ProfileAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Profile";
}
} public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Profile_default",
"Profile/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
}
AreaName属性用来定义Area的名子, RegisterArea(AreaRegistrationContext context) 方法中可以看出在浏览器的地址栏中URL的样式为Profile/{controller}/{action}/{id},是4级构结,只要将context.MapRoute(…)改为
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Profile_default",
"Profile/{action}/{id}",
new { controller = "要访问的controller名子", action = "Index", id = UrlParameter.Optional }
);
}
URL的样式会再变为三级结构 Profile/{action}/{id}。
2. 修改根目录下Views/shared/Site.Master文件,并添加一个名为o”Your Profile”的菜单项并指定area的名子, 示例中Area的名子为Profile。
<ul id="menu">
<li><%= Html.ActionLink("Home", "Index", "Home", new { area = ""}, null)%></li>
<li><%= Html.ActionLink("Your Profile", "ViewProfile", "Profile", new { area = "Profile" }, null)%></li>
<li><%= Html.ActionLink("About", "About", "Home", new { area = ""}, null)%></li>
</ul>
注意:Home和About不属于任何Area,但是也要通过匿名对象的方式声明area,如果没有声明Area,当进入到Profile的某个view时, Home和About的会的URL会变为Profile/Home, Profile/About,点击Home或About时会有异常抛出,所以当页面上的某个链接不属于任何一个Area并且有可能被多个Area可享的话,一定要加上new { area = ""}
3. 只有匹配正确的Route才能显示Area中的View,Area中的Route已经配置好,但它是如何被加入到RouteTable中的?
3.1 首先在Global.asax.cs的Application_Start()方法中调用了AreaRegistration.RegisterAllAreas()方法,这个方法的目地主是找出所有继承了AreaRegistration的类,并执行RegisterArea(…)方法来完成注册
public static void RegisterAllAreas() {
RegisterAllAreas(null);
}
public static void RegisterAllAreas(object state) {
RegisterAllAreas(RouteTable.Routes, new BuildManagerWrapper(), state);
}
internal static void RegisterAllAreas(RouteCollection routes, IBuildManager buildManager, object state) {
List<Type> areaRegistrationTypes = TypeCacheUtil.GetFilteredTypesFromAssemblies(_typeCacheName, IsAreaRegistrationType, buildManager);
foreach (Type areaRegistrationType in areaRegistrationTypes) {
AreaRegistration registration = (AreaRegistration)Activator.CreateInstance(areaRegistrationType);
registration.CreateContextAndRegister(routes, state);
}
}
3.1.1 TypeCacheUtil.GetFilteredTypesFromAssemblies(…)方法用来找出所有继承了AreaRegistration类的Type对象:
public static List<Type> GetFilteredTypesFromAssemblies(string cacheName, Predicate<Type> predicate, IBuildManager buildManager) {
TypeCacheSerializer serializer = new TypeCacheSerializer();
// first, try reading from the cache on disk
List<Type> matchingTypes = ReadTypesFromCache(cacheName, predicate, buildManager, serializer);
if (matchingTypes != null) {
return matchingTypes;
}
// if reading from the cache failed, enumerate over every assembly looking for a matching type
matchingTypes = FilterTypesInAssemblies(buildManager, predicate).ToList();
// finally, save the cache back to disk
SaveTypesToCache(cacheName, matchingTypes, buildManager, serializer);
return matchingTypes;
}
在GetFilteredTypesFromAssemblies(…)方法中,先从缓存中读取匹配的类型(缓存用于.Net Framework 4.0中,示例程序用VS2008在.NET 3.5环境下,暂不讨论缓存的应用)。缓存没有数据返回,调用FilterTypesInAssemblies(…)方法返回List<Type>对象, 这时返回的List<Type>才是继承了AreaRegistration类的Type对象, 下面的代码是FilterTypesInAssemblies方法的源码:
private static IEnumerable<Type> FilterTypesInAssemblies(IBuildManager buildManager, Predicate<Type> predicate) {
// Go through all assemblies referenced by the application and search for types matching a predicate
IEnumerable<Type> typesSoFar = Type.EmptyTypes;
ICollection assemblies = buildManager.GetReferencedAssemblies();
foreach (Assembly assembly in assemblies) {
Type[] typesInAsm;
try {
typesInAsm = assembly.GetTypes();
}
catch (ReflectionTypeLoadException ex) {
typesInAsm = ex.Types;
}
typesSoFar = typesSoFar.Concat(typesInAsm);
}
return typesSoFar.Where(type => TypeIsPublicClass(type) && predicate(type));
}
与寻找controll的方法相似,找出所有assembly中的所有Type并通过TypeIsPublicClass和predicate的过滤出继承了AreaRegistration类的Type对象
3.1.2 在GetFilteredTypesFromAssemblies(…)方法中如果.Net Framework的版本不是4.0, 最后的SaveTypesToCache(…)方法也不会执行
以后会对.Net Framework 4.0下的ReadTypesFromCache(…)和SaveTypesToCache(…)进行补充
3.2 遍历返回的List<Type>对象,反射出AreaRegistration 对象并调用它的CreateContextAndRegister(…)方法
internal void CreateContextAndRegister(RouteCollection routes, object state) {
AreaRegistrationContext context = new AreaRegistrationContext(AreaName, routes, state);
string thisNamespace = GetType().Namespace;
if (thisNamespace != null) {
context.Namespaces.Add(thisNamespace + ".*");
}
RegisterArea(context);
}
在CreateContextAndRegister(…)方法中创建一个AreaRegistrationContext 对象并做为RegisterArea(…)方法的参数,RegisterArea刚好是AreaRegistration 的继承类中重写方法,在RegisterArea方法只要调用AreaRegistrationContext 类的MapRoute(…)方法就可能完成一个新的Route的注册。
【示例代码 下载】
首先第一点,绝对不可以修改源码 :)
固定是可以的,首先不需要创建继承于AreaRegistration的类,将每个area的route注册写到Global.asax.cs中, 如下
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public static void RegisterRoutes(RouteCollection routes){ routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); // Register Arearoutes.MapRoute( "Profile_default", "Profile/{action}/{id}", new { controller = "Profile", action = "index", id = UrlParameter.Optional } ); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults );} |
Sorry,是我没有说明白,一定要声明AreaName并保存到Route.DatattTokens中,否则不能定位到相应的area目录,下面的代码是两个area,先注册Profile再注册Blog
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); #region Register Areas // Profile ares. Route areaProfile = routes.MapRoute( "Profile_default", "Profile/{action}/{id}", new { controller = "Profile", action = "View", id = UrlParameter.Optional} ); areaProfile.DataTokens["area"] = "Profile"; areaProfile.DataTokens["UseNamespaceFallback"] = true; // Blog ares. Route areaBlog = routes.MapRoute( "Blog_default", "Blog/{action}/{id}", new { controller = "Blog", action = "View", id = UrlParameter.Optional} ); areaBlog.DataTokens["area"] = "Blog"; areaBlog.DataTokens["UseNamespaceFallback"] = true; #endregion routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults ); }
|
(转)ASP.NET Mvc 2.0 - 1. Areas的创建与执行的更多相关文章
- 2.第一个ASP.NET MVC 5.0应用程序
大家好,上一篇对ASP.NET MVC 有了一个基本的认识之后,这一篇,我们来看下怎么从头到尾创建一个ASP.NET MVC 应用程序吧.[PS:返回上一篇文章:1.开始学习ASP.NET MVC] ...
- 返璞归真 asp.net mvc (6) - asp.net mvc 2.0 新特性
原文:返璞归真 asp.net mvc (6) - asp.net mvc 2.0 新特性 [索引页][源码下载] 返璞归真 asp.net mvc (6) - asp.net mvc 2.0 新特性 ...
- ASP.NET MVC 4.0中选择Windows 验证默认出错拒绝访问的原因和解决方案
在VS 2012或者2013 中,根据模板创建一个ASP.NET MVC 4.0的应用程序,选择下面的模板 然后选择Intranet Application 不对源代码做任何修改,直接按下F5调试,会 ...
- 安装了VS2010 sp1 后再安装ASP.NET MVC 3.0的问题
安装了VS2010 sp1 后再安装ASP.NET MVC 3.0的问题(Final Result: Installation failed with error code: (0x80070643) ...
- 返璞归真 asp.net mvc (13) - asp.net mvc 5.0 新特性
[索引页][源码下载] 返璞归真 asp.net mvc (13) - asp.net mvc 5.0 新特性 作者:webabcd 介绍asp.net mvc 之 asp.net mvc 5.0 新 ...
- ASP.NET MVC 3.0 Controller基础
ASP.NET MVC 3.0 Controller基础 1.Controller类与方法 Controller(控制器)是ASP.NET MVC的核心,负责处理浏览器请求,并作出响应.Cotro ...
- 从零开始学习ASP.NET MVC 1.0
转自:http://www.cnblogs.com/zhangziqiu/archive/2009/02/27/ASPNET-MVC-1.html <从零开始学习ASP.NET MVC 1.0& ...
- ASP.NET MVC 4.0的Action Filter
有时候你想在调用action方法之前或者action方法之后处理一些逻辑,为了支持这个,ASP.NET MVC允许你自定义创建action过滤器.Action过滤器是自定义的Attributes,用来 ...
- 安装了VS2010 sp1 后再安装ASP.NET MVC 3.0的问题(Final Result: Installation failed with error code: (0x80070643), "安装时发生严重错误 " (Ela)
原文:安装了VS2010 sp1 后再安装ASP.NET MVC 3.0的问题(Final Result: Installation failed with error code: (0x800706 ...
随机推荐
- VC中GBK与UTF8转化
void ConvertGBKToUtf8(CString& strGBK) { int len=MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strG ...
- 八、MPxToolCommand, tool command
1. Tool Property Sheets: 是用来更改context属性的编辑框,类似于attribute editor.(property和attribute本质上是一个意思)作用于activ ...
- COSBench性能测试配置--一张图说明一切
COSBench性能测试配置--一张图说明一切: 测试配置,并发数,运行时间设置
- PreparedStatement解决sql注入问题
总结 PreparedStatement解决sql注入问题 :sql中使用?做占位符 2.得到PreparedStatement对象 PreparedStatement pst=conn.prepar ...
- ios base64图片上传失败问题
今天做图片上传,后台用的是base64解密图片二进制文件,以前都是用表单上传来解决图片上传的,现在后台没有人改,所以研究下base64上传. 需要将图片base64加密,但是调用 [data base ...
- Address already in use的解决方法
当客户端保持着与服务器端的连接,这时服务器端断开,再开启服务器时会出现: Address already in usr. 可以用netstat -anp | more 可以看到客户端还保持着与服务器的 ...
- Java第一天学习笔记整理
一.关键字 java的关键字对java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等,关键字不能用作变量名.方法名.类名.包名. 常见的关键字: 用于定义数据类型的关键字 cla ...
- COleChangeSourceDialog不能Change Source的解决方法
在微软给的例子OClient中,有选中一个OLE对象然后Change Source的功能,但是会报错.分析了一下是这样的: void CMainView::OnOleChangeSource() ...
- RHEL 7.0 本地配置yum源
RHEL 7.0 本地配置yum源 yum简介 yum = Yellow dog Updater, Modified 主要功能是更方便的添加/删除/更新RPM包. 它能自动解决包的倚赖性问题. 它 ...
- CommandArgument传多个参数
CommandArgument='<%#Eval("id")+","+Eval("interName") %>'