更改MVC注册Areas的顺序,掌控Areas的运作
一、前言
首先,有人要问,为什么要更改Areas的注册顺序呢?
使用Areas的时候一般会在前面加标识符,比如:admin/{controller}/{action}/{id}
而且Areas的注册早于默认的网站 (就是不放在Areas文件夹中的那个网站)
但是,我想,能不能干脆就不用外部的那个默认网站,而是把所有部分都放Areas中呢?
然后,把其中一个的标识符去掉,变成默认的网站
这时候,项目根目录就少了2个文件夹,Controller和View
是不是很整洁?的确…但问题也随之而来
二、把所有网站都放在Areas里的一个大问题
简单的来说,这个问题就是你无法指定不同Area的注册顺序,那会出现什么问题呢?
如果我有2个Area:
一个是带标识符的,叫admin,地址是 admin/{controller}/{action}/{id}
一个是默认的,叫web,地址是 {controller}/{action}/{id}
这时候,如果web注册比admin早,就会出现问题了,就算我输入 admin.aspx,按照次序,会先被web捕捉,被认为是web中的一个controller
所以我们需要想办法更改areas的注册顺序
至于为什么默认的时候不能确定顺序?看一下MVC源代码就知道了,它是利用反射来获得Areas的,放到一个集合后用foreach注册
三、设定注册顺序的2种方法
1)第一种方法是昨天看到以为博友写了篇关于Areas的文章,我在下面问他后他告诉我的
传送门,看下面留言即可知道了:www.cnblogs.com/terrysun/archive/2010/04/13/1711218.html
他的方法是把Areas的注册移出来,放在同一个地方,这样就可以随意地更改顺序了
2)第二种方法是我昨天刚试验成功的,虽然看似麻烦,但是看起来更清楚一点,我个人推荐
首先,我重写了一个 AreaRegistration 类,这个类是用来注册Areas的

/// <summary>
/// 根据顺序注册Areas
/// </summary>
abstract public class AreaRegistrationOrder : AreaRegistration
{
/// <summary>
/// 存放AreaContent
/// </summary>
protected static List<AreaRegistrationContext> areaContent = new List<AreaRegistrationContext>();
/// <summary>
/// 存放AreaRegistration
/// </summary>
protected static List<AreaRegistrationOrder> areaRegistration = new List<AreaRegistrationOrder>();
/// <summary>
/// 劫持
/// </summary>
/// <param name="context"></param>
public override void RegisterArea(AreaRegistrationContext context)
{
areaContent.Add(context);
areaRegistration.Add(this);
}
/// <summary>
/// 注册
/// </summary>
/// <param name="context"></param>
public abstract void RegisterAreaOrder(AreaRegistrationContext context);
/// <summary>
/// 顺序
/// </summary>
public abstract int Order { get; }
/// <summary>
/// 按照顺序注册Areas
/// </summary>
public static void RegisterAllAreasOrder()
{
RegisterAllAreas();
Register();
}
/// <summary>
/// 注册
/// </summary>
private static void Register()
{
List<int[]> order = new List<int[]>();
for(int k=0;k<areaRegistration.Count;k++)
{
order.Add(new int[] { areaRegistration[k].Order, k });
}
order = order.OrderBy(o => o[0]).ToList();
foreach (var o in order)
{
areaRegistration[o[1]].RegisterAreaOrder(areaContent[o[1]]);
}
}
}
}
那接下来怎么使用这个抽象类呢?
你只需要改2个地方
1)首先,你需要把Global.asax中原来那个注册全部Areas的函数换掉,并且把RegisterRoutes函数中的代码删掉
(上图注释中有一个错别字,应该是”代码也删除“,不是”代码页删除“)
2)接下来,你就可以新建一个Areas了,对于新建的Areas,你需要做如下修改:
总结一下你总共要做那些事:
. 把原来继承的类换掉,换乘上面那个类,并实现抽象函数
.. 把RegisterArea删掉,换成RegisterAreaOrder,原来的操作写在RegisterAreaOrder中
... Order中,指定它的顺序,越小越就早执行,可以是负数
四、Ending
源代码下载:https://files.cnblogs.com/dozer/MVC-AREAS.zip
感谢大家的阅读,如果收获,请点支持~谢谢~
本作品采用知识共享署名-非商业性使用 3.0 Unported许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架