有时候我们会碰到两个项目合在一起,那么必然会碰到两个同名的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 支持同名路由,不同命名空间的更多相关文章

  1. .NetCore MVC中的路由(1)路由配置基础

    .NetCore MVC中的路由(1)路由配置基础 0x00 路由在MVC中起到的作用 前段时间一直忙于别的事情,终于搞定了继续学习.NetCore.这次学习的主题是MVC中的路由.路由是所有MVC框 ...

  2. 【翻译】ASP.NET MVC 5属性路由(转)

    转载链接:http://www.cnblogs.com/thestartdream/p/4246533.html 原文链接:http://blogs.msdn.com/b/webdev/archive ...

  3. MVC的URL路由规则

    MVC的URL路由规则 Routing的作用:它首先是获取到View传过来的请求,并解析Url请求中Controller和Action以及数据,其次他将识别出来的数据传递给Controller的Act ...

  4. MVC中的路由

    authour: chenboyi updatetime: 2015-05-02 16:10:04 friendly link:   目录 1,思维导图 2,MVC处理机制简图(讲解路由解析) 3,默 ...

  5. 005. Asp.Net Routing与MVC 之三: 路由在MVC的使用

    上次讲到请求如何激活Controller和Action,这次讲下MVC中路由的使用.本次两个关注点: 遗留:ModelBinder.BindModel的过程 MVC中路由的使用 MVC 5中的Acti ...

  6. .NetCore MVC中的路由(2)在路由中使用约束

    p { margin-bottom: 0.25cm; direction: ltr; color: #000000; line-height: 120%; orphans: 2; widows: 2 ...

  7. 第2章 ASP.NET MVC(URL、路由及区域)

    * { font: 17px/1.5em "Microsoft YaHei" } ASPNET MVC URL.路由及区域 一.URL.路由及区域 一.      配置路由器 1. ...

  8. 为ASP.NET MVC应用添加自定义路由

    这里,我们将学习如何给asp.net mvc应用添加自定义路由.用自定义路由来修改默认路由表. 对一些简单的asp.net mvc应用,默认的路由表就已经足够了.但是,当你需要创建特殊的路由时,就需要 ...

  9. MVC+Bootstrap+Drapper使用PagedList.Mvc支持多查询条件分页

    前几天做一个小小小项目,使用了MVC+Bootstrap,以前做分页都是异步加载Mvc部分视图的方式,因为这个是小项目,就随便一点.一般的列表页面,少不了有查询条件,下面分享下Drapper+Page ...

随机推荐

  1. Laravel RuntimeException inEncrypter.php line 43: The only supported ciphers are AES-128-CBC and AES-256-CBC with the correct key lengths

    php artisan key:generate 运行上面代码即可解决

  2. 不在折腾---hive-0.13.1-bin

    Hive只在一个节点安装即可 上传tar包 解压 > tar zxvf hive-0.13.1-bin.tar.gz 配置mysql * 检查MySQL是否安装:rpm -qa | grep m ...

  3. 网站过滤器Filter

    实际上,Filter与Servlet及其相似,区别只是FIlter的doFilter()方法里多了一个FilterChain的参数,通过该参数可以控制是否放行用户的请求.网站有了过滤器十分的方便,可以 ...

  4. javascript 提取表单元素生成用于提交的对象(序列化 html 表单)

    function serialize(f) { var o = {}; var s = f.getElementsByTagName("select"); for (var i = ...

  5. Tomcat部署web应用程序

    对Tomcat部署web应用的方式总结,常见的有以下四种: 1.[替换ROOT目录] 最简单的一种方法,webapps目录下面ROOT文件夹的文件为你的文件,然后输入localhost:8080/首页 ...

  6. WinDbg 蓝屏dump分析教程

    一.WinDbg是什么?它能做什么? WinDbg是在windows平台下,强大的用户态和内核态调试工具.它能够通过dmp文件轻松的定位到问题根源,可用于分析蓝屏.程序崩溃(IE崩溃)原因,是我们日常 ...

  7. javascript实例备忘

    一,javascript动态显示: 如显示效果上图所示: 如图显示鼠标放在百度谷歌等字样上市动态显示其内容明细:代码如下:<head><title></title> ...

  8. jQuery刷新包含的<jsp:include>页面

    jQuery刷新包含页面 JQuery刷新包含页面,以下两种形式均可: <%@include file="../include/header.jsp" %>   < ...

  9. 面向对象cookie增删查

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  10. iOS开发:自定义控件实现手势解锁

    自定义控件 1.提供initWithFrame:及initWithCoder:方法来初始化: 2.解锁控件只负责展示.触摸.绘图等,存储轨迹.判断轨迹等操作不是解锁控件要做的.因此要定义一个代理,将轨 ...