首先介绍一下问题产生的背景。web项目很多都需要权限系统,因此我将权限系统分离开成一个独立的项目,暂且称为Auth系统,以后有哪个项目需要权限系统,只需要引用Auth系统的dll即可。每新建一个mvc项目,都会有默认的路由,参数有name、url、defaults,默认的路由设置是在项目根目录的App_Start文件夹下的RouteConfig.cs中。这里不再细说,但它还有一个参数namespace,类型是string[]。新建项目的默认的路由,里面是没有显示这个参数的,默认值是当前项目Controller的命名空间名称。好了不再多说别的,下面直奔问题。
暂定一下有两个系统,Auth系统,是一个mvc权限系统;B系统,也是一个mvc系统,且要引用Auth系统。
假如,Auth系统使用的是默认路由,且Auth系统的Controller是建立在mvc项目的根Controller文件夹下,没有建立在域Areas下面的Conttrller文件夹下。而且将要引用Auth系统dll的系统B,也使用的是默认路由,且准备把Auh系统引用在根目录下面的Contrller,而不是域Areas之类的下面。这样的话,把Auth的dll引用到B系统中,接下来,把Auth系统的View文件夹下面的视图和Content和Srcipt静态文件都复制到系统B中,这样就可以在B系统中打开Auth的页面了。
问题来了,假如Auth系统使用的是默认路由。但B系统,想把Auth系统分离在域Areas下面怎么办呢?如果还按照上面的相似方式,把Auth系统的View和静态文件复制到系统B的域Areas下面中,运行起来之后,假定域名称叫Admin,那么http://localhost:***/Admin/权限系统Controller/权限系统Action,结果是找不到相关资源。如果去掉域的名称Admin,像这样:http://localhost:***/权限系统Controller/权限系统Action,结果是提示找不到~/View/系统权限/系统权限.cshtml。说明应该是命名空间不一样,所以产生了这样的现象。
解决这个问题的办法是:在Auth系统的路由中设置一个自己的namespace名称,在B系统的根目录下面的路由中设置一个自己的namespace名称。关键来了,在B系统的域Areas中的路由设置namespace,也要加一个自己的namespace名称,但同时将Auth系统的路由命名空间也加入进去。namespace的参数类型是string[],所以可以加多个。像下面这样的。
routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, namespaces: new string[] { "B.Web.Controllers", //B系统的路由命名空间 "Auth.Web.Controllers" //Auth系统的路由命名空间名称 } );