子应用程序的Global.asax中的IIS 7.5 URL重写模块和URL路由

子应用程序的Global.asax中的IIS 7.5 URL重写模块和URL路由,iis,url-rewriting,url-routing,global-asax,Iis,Url Rewriting,Url Routing,Global Asax,我有一个“顶级”网站,还有各种“低级”网站,它们是独立的网站,但共享很多代码。这些较低级别的站点在IIS 7.5中被指定为web应用程序,并从中继承一个公共web.config文件,尽管它们位于自己的应用程序池中 我已将IIS 7.5配置为URL重写模块,以便较低级别的站点可以拥有自己的不同URL,例如www.BritSocAt.com,它映射到www.ccesd.ac.uk/BritSocAt 每个站点都有自己的Global.asax文件,其中包含为漂亮URL定义的URL路由规则。这些URL

我有一个“顶级”网站,还有各种“低级”网站,它们是独立的网站,但共享很多代码。这些较低级别的站点在IIS 7.5中被指定为web应用程序,并从中继承一个公共web.config文件,尽管它们位于自己的应用程序池中

我已将IIS 7.5配置为URL重写模块,以便较低级别的站点可以拥有自己的不同URL,例如www.BritSocAt.com,它映射到www.ccesd.ac.uk/BritSocAt

每个站点都有自己的Global.asax文件,其中包含为漂亮URL定义的URL路由规则。这些URL(/Home、/About、/Contact等)对于所有站点都是通用的,包括顶级(ccesd.ac.uk)站点

我从Ruslan Yakushev那里了解到,IIS URL重写模块是在Global.asax中的ASP.NET路由之前处理的。这是我需要的工作方式。但是,如果我键入www.britsocat.com/About,我发现正在使用www.ccesd.ac.uk的Global.asax文件!(我已经在测试中验证了这一点。)此外,这发生在IIS URL重写之前。换句话说,服务的结果页面是www.ccesd.ac.uk/Body.aspx?control=CCESDMissionStatement,而不是www.ccesd.ac.uk/BritSocAt/Body.aspx?control=CCESDMissionStatement

我怀疑这是因为我在两个站点(Global.asax文件)中有相同的路由规则(“About”)。我想我可以通过更改其中一个文件中规则的名称来解决这个问题;但总的来说,这是不可取的,尤其是对于“家”


有什么我遗漏了,或者我可以做些什么来修复它吗?

在与MSDN支持团队进行了一次长时间的会议之后,似乎无法做到这一点:官方的回应是,IIS ARR和URL重写并不是设计用来以上述方式将单独的域名映射到子应用程序的。这与这样一个事实有关,即不能将单独的域名绑定到IIS中的子应用程序,而只能绑定到根级别的网站。官方推荐的方法是在IIS中为每个不同的域名设置单独的网站(即一个用于britsocat.com,一个用于ccesd.ac.uk等)

对于那些感兴趣的人来说,发生的事情是ARR不知道/BritSocAt是ccesd.ac.uk的子应用程序;一旦发生重定向(或者更确切地说,重写),就将/BritSocAt视为标准虚拟目录。因此,一旦在根级别的Global.asax文件中找到了友好URL的匹配规则,就不再进行进一步搜索,而忽略了更具体的/BritSocAt Global.asax文件。(这与没有ARR的情况相反,在ARR中优先使用子级别的Global.asax文件。)我试图通过将路由规则从各种Global.asax文件移动到相应HttpModules的Init()方法来避免这种情况,然后让根级别的web.config文件指定根级别模块,然后/BritSocAt web.config文件指定其自己的模块(首先删除了根级别模块)。然而,结果完全相同;使用ARR时,子级别web.config被忽略。(我通过在其中放入一个不存在的模块名进行了测试——没有错误!)我甚至尝试对根级模块进行黑客攻击,使其忽略对/BritSocAt address的所有请求;然而,由于IIS7,使用“集成模式”会导致请求信息不再可用于模块的Init()方法(通过设计)。最后,我尝试将所有路由规则移动到IIS中(从Global.asax);这让我更接近了,但我的网站仍然在做一些非常奇怪(和无法解释的)的事情,到目前为止,已经是银行假日周末前的一个周五晚上7点了,所以我放弃了


我剩下的感觉是一种轻微的失望:我认为IIS ARR/URL重写的局限性应该明确并加以解释。MSDN支持部门承认这是一个限制,但认为没有解释这一点是有道理的,因为这似乎是一件奇怪的事情——对他们来说,一个单独的域名意味着一个单独的网站,因此,唯一合理的解决方案是将它们作为单独的站点放在IIS中,并使用虚拟目录来共享文件和配置设置。从我们的角度来看,我们有一个拥有各种“皮肤”的主要站点:每个站点都有自己的可定制样式、外观和功能,但它们都从相同的代码库运行,并使用相同的配置设置。因此,对我们来说,更自然的设计是在IIS中将它们作为子目录运行;事实上,如果您不尝试单独处理它们(即,使用单独的域),那么这种方法非常有效。由于这是一个商业考虑因素(我们的客户要求他们的网站可以通过他们选择的域名寻址),而不是设计考虑因素,因此我们的网站实际上是一个被忽略的可行用例。

只是一个简单的想法,在使用@cheesemacfly-非常好的建议之前,您能否确保没有调用重写模块,谢谢。我以前没用过这个工具。只是想感谢你的提问和后续行动。我们的项目也面临着类似的问题,我们花了很多时间寻找问题和解决方案。只有在找到解决方案后,我们才发现了这个堆栈溢出帖子,但是解释非常有用。比他们可能意识到的更多的开发人员分享了您对MS的轻微失望。非常欢迎您。我很高兴它帮助了一些人,尤其是经过这么长时间!
    void Application_Start(object sender, EventArgs e)
    {
      // Code that runs on application startup
      RegisterRoutes(System.Web.Routing.RouteTable.Routes);
    }

    // ** URL ROUTING **
    private static void RegisterRoutes(System.Web.Routing.RouteCollection routes)
    {
      routes.Ignore("{resource}.axd/{*pathInfo}");
      // HOME
      routes.MapPageRoute("Home", "Home", "~/Body.aspx", false, new System.Web.Routing.RouteValueDictionary
 { { "control", "HomePage" } });
      // CONTACT US
      routes.MapPageRoute("ContactUs", "Contact", "~/Body.aspx", false, new System.Web.Routing.RouteValueDictionary
 { { "control", "CCESDContactUs" } });
      // ABOUT US
      routes.MapPageRoute("AboutUs", "About", "~/Body.aspx", false, new System.Web.Routing.RouteValueDictionary
 { { "control", "CCESDMissionStatement" } });
    }