MVC 支持同名路由,不同命名空间
有时候我们会碰到两个项目合在一起,那么必然会碰到两个同名的controller,其实MVC在注册路由,添加Route的时候可以指定当前规则解析那个命名空间下的所有Controller。
注:Controller的调用是通过IControllerFactory,反射调用目标Controller,不指定目标命名空间,直接从BuildManager.GetReferencedAssemblies();如下。
private static List<Type> controllerTypes = new List<Type>();
/// <summary>
/// 静态构造函数
/// </summary>
static DefaultControllerFactory()
{
var assemblys = BuildManager.GetReferencedAssemblies();
foreach (Assembly assembly in assemblys)
{
var types = assembly.GetTypes().Where(a => typeof(IController).IsAssignableFrom(a));
foreach (Type type in types)
{
controllerTypes.Add(type);
}
}
} /// <summary>
/// 创建controller
/// </summary>
/// <param name="requestContext"></param>
/// <param name="controllerName"></param>
/// <returns></returns>
public IController CreateController(RequestContext requestContext, string controllerName)
{
string typeName = controllerName + "Controller";
Type controllerType = controllerTypes.FirstOrDefault(a => a.Name == typeName);
if (controllerType != null)
{
return (IController)Activator.CreateInstance(controllerType);
}
return null;
}
回归正题:如何支持多种命名空间
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index" }, namespaces: new string[] { "MvcExpose.Controllers" }
);
routes.MapRoute("Admin", "Admin/{controller}/{action}",
new { controller = "Home", action = "Index"}, new string[] { "MvcExpose.Admin.Controllers" });
}
切记:两种注册Url规则,要长度不一致,Default带有"{controller}/{action}/{id}"一直报错,以为在正则解析看来,无法区分两种路由规则的区别,因此当“http://localhost:4500/Admin/Home/Index”,系统先调用default的路由解析。
其实有一种更好的的方式:
就是建立所谓的区域,每一个区域就是一个独立的子系统,如下图:

其实最为重要的是用了AreaRegistration
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Admin";
}
} public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { controller="home",action = "Index", id = UrlParameter.Optional }
);
}
}
在Global中,我们有一句: AreaRegistration.RegisterAllAreas();调用这个方法的时候,当前Web应用所有直接或间接被引用的程序集会被加载,然后从这些程序集中解析出所有继承自AreaRegistration的类型并反射出对象,调用相应的RegisterArea。
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
原理:
MVC调用Controller是通过反射程序集中继承了IController的所有类(默认情况下),根据路由规则取出ControllerName,并实例化相对应的Controller实例,如果出现重名的Controller,会报错。

因此要指定好对应的命名空间,MVC将namespace存在RouteData的DateTokens中


十分直观的的看到,这样就给不同的路由规则,反射相应的命名空间下IController的实例!
MVC 支持同名路由,不同命名空间的更多相关文章
- .NetCore MVC中的路由(1)路由配置基础
.NetCore MVC中的路由(1)路由配置基础 0x00 路由在MVC中起到的作用 前段时间一直忙于别的事情,终于搞定了继续学习.NetCore.这次学习的主题是MVC中的路由.路由是所有MVC框 ...
- 【翻译】ASP.NET MVC 5属性路由(转)
转载链接:http://www.cnblogs.com/thestartdream/p/4246533.html 原文链接:http://blogs.msdn.com/b/webdev/archive ...
- MVC的URL路由规则
MVC的URL路由规则 Routing的作用:它首先是获取到View传过来的请求,并解析Url请求中Controller和Action以及数据,其次他将识别出来的数据传递给Controller的Act ...
- MVC中的路由
authour: chenboyi updatetime: 2015-05-02 16:10:04 friendly link: 目录 1,思维导图 2,MVC处理机制简图(讲解路由解析) 3,默 ...
- 005. Asp.Net Routing与MVC 之三: 路由在MVC的使用
上次讲到请求如何激活Controller和Action,这次讲下MVC中路由的使用.本次两个关注点: 遗留:ModelBinder.BindModel的过程 MVC中路由的使用 MVC 5中的Acti ...
- .NetCore MVC中的路由(2)在路由中使用约束
p { margin-bottom: 0.25cm; direction: ltr; color: #000000; line-height: 120%; orphans: 2; widows: 2 ...
- 第2章 ASP.NET MVC(URL、路由及区域)
* { font: 17px/1.5em "Microsoft YaHei" } ASPNET MVC URL.路由及区域 一.URL.路由及区域 一. 配置路由器 1. ...
- 为ASP.NET MVC应用添加自定义路由
这里,我们将学习如何给asp.net mvc应用添加自定义路由.用自定义路由来修改默认路由表. 对一些简单的asp.net mvc应用,默认的路由表就已经足够了.但是,当你需要创建特殊的路由时,就需要 ...
- MVC+Bootstrap+Drapper使用PagedList.Mvc支持多查询条件分页
前几天做一个小小小项目,使用了MVC+Bootstrap,以前做分页都是异步加载Mvc部分视图的方式,因为这个是小项目,就随便一点.一般的列表页面,少不了有查询条件,下面分享下Drapper+Page ...
随机推荐
- openssl evp 对称加密(AES_ecb,ccb)
openssl evp 对称加密(AES_ecb,ccb) evp.h 封装了openssl常用密码学工具,以下主要说对称加密的接口 1. 如下使用 aes_256_ecb 模式的加密解密测试代码 u ...
- MySQL 日期时间相关函数整理
-- 为日期增加一个时间间隔:date_add() SELECT NOW(); YEAR); MONTH); DAY); HOUR); MINUTE); SECOND); MICROSECOND); ...
- UIautomator Python测试
#!/usr/bin/env python # -*- coding: utf-8 -*- import unittest from mock import MagicMock, patch impo ...
- java web 之 SpringMVC4.x配置
合肥程序员群:49313181. 合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入) Q Q:408365330 E-Mail:egojit@qq.com 综述: 有 ...
- G:数字三角形
总时间限制: 1000ms 内存限制: 65536kB描述73 88 1 02 7 4 44 5 2 6 5 (图1) 图1给出了一个数字三角形.从三角形的顶部 ...
- phpMyAdmin - 错误 您应升级到 MySQL 5.5.0 或更高版本,解决办法。。。
折腾自己的个人网站,装了个数据库管理工具,遇到您应升级到 MySQL 5.5.0 或更高版本... 采用降级phpmyadmin版本的方法解决了: 查找phpmyadmin/libraries/com ...
- java动手动脑和课后实验型问题String类型
1.请运行以下示例代码StringPool.java,查看其输出结果.如何解释这样的输出结果?从中你能总结出什么? true true false 总结: 使用new关键字创建字符串对象时, 每次申请 ...
- 根据序列图像聚焦区域获取深度 Shape From Focus
最为超新新新新鸟...我也不知道第一篇文章应该写什么..所以,把自己最近正在研究的东西报一下吧, 研究的东西其实也不算深奥,就是对一个图像序列中的每张图像进行检测,发现每张图片的聚焦清晰区域,找到这个 ...
- python学习08——类
笨办法学python第42节,这节讲的是类,程序沿用上一节中一个游戏,不同的是这一节用了类的方法. 其中改动的代码主要如下 原来的最后几句用了这样的代码: ROOMS = { 'death':deat ...
- <![CDATA[]]>作用
<![CDATA[]]>的作用是让XML解析器将标签中的字符串当作普通文本对待,以防止某些字符串对XML格式造成破坏.