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

时间:2013-05-14 22:14:26

标签: iis url-rewriting url-routing global-asax

我有一个“顶级”网站www.ccesd.ac.uk,以及各种“低级”网站,例如www.ccesd.ac.uk/BritSocAt,这些网站是独立的网站,但却分享了很多网站码。这些较低级别的站点在IIS 7.5中指定为Web应用程序,并从www.ccesd.ac.uk继承了一个公共web.config文件,尽管它们位于自己的应用程序池中。

我已使用URL Rewrite模块配置IIS 7.5,以便较低级别的网站可以拥有自己的不同网址,例如www.BritSocAt.com,映射到www.ccesd.ac.uk/BritSocAt。

Web-site configuration in IIS 7.5

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

    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" } });
    }

我从Ruslan Yakushev的excellent tutorial了解到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文件)中都有相同的路由规则(“关于”)。我想我可以通过更改其中一个文件中的规则名称来解决这个问题;但这在一般情况下是不受欢迎的,特别是对于“家庭”。

我有什么遗漏或我能做些什么来修复它吗?

1 个答案:

答案 0 :(得分:2)

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

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

我的遗憾是一种轻微的失望:我认为IIS ARR / URL重写的这种限制应该明确并加以说明。 MSDN支持承认这是一个限制,但是没有解释它是合理的,因为它似乎是一个奇怪的事情 - 对他们来说,一个单独的域名意味着一个单独的网站,因此唯一合理的解决方案是容纳他们作为IIS中的单独站点,并使用虚拟目录进行共享文件和配置设置。从我们的角度来看,我们有一个主要网站有各种“皮肤”:每个都有自己的可自定义的样式,外观和功能,但它们都是从相同的代码库运行并使用相同的配置设置。因此,对我们来说更自然的设计是将它们作为IIS中的子目录运行;如果你不试图单独解决它们(即,使用单独的域),这确实很有效。由于这是一个商业考虑因素(我们的客户要求他们的网站可以通过他们选择的域名来解决)而不是设计考虑因素,看来我们的用户实际上是一个错过的可行用例。