【问题标题】:IIS 7.5 URL rewrite module and URL routing in Global.asax for sub-applicationsGlobal.asax 中用于子应用程序的 IIS 7.5 URL 重写模块和 URL 路由
【发布时间】:2013-05-09 08:33:30
【问题描述】:

我有一个“顶级”网站www.ccesd.ac.uk,以及运行它的各种“低级”网站,例如www.ccesd.ac.uk/BritSocAt,它们是独立的网站,但共享大量代码。这些较低级别的站点在 IIS 7.5 中被指定为 Web 应用程序,并从 www.ccesd.ac.uk 继承一个公共 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) 网站。

    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 文件)中都有相同的路由规则(“关于”)。我想我可以通过更改其中一个文件中的规则名称来解决这个问题;但这通常是不可取的,尤其是对于“Home”。

有什么我遗漏的或者我可以做些什么来解决它吗?

【问题讨论】:

  • 只是一个快速的想法,你能确保在使用failed request tracing tool之前没有调用重写模块
  • @cheesemacfly - 很好的建议,谢谢。我以前没用过这个工具。

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


【解决方案1】:

在与 MSDN 支持团队进行了长时间的会议之后,似乎无法做到这一点:官方的回应是 IIS ARR 和 URL 重写并非旨在用于以所述方式将单独的域名映射到子应用程序更多。这与不能将单独的域名绑定到 IIS 中的子应用程序,只能绑定到根级网站的事实有关。官方推荐的方法是在 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() 方法(按设计)。最后,我尝试将 all 我的路由规则移动到 IIS(来自 Global.asax);这让我更接近了,但我的网站仍然在做一些非常奇怪(且无法解释)的事情,此时是银行假日周末前的周五晚上 7 点,所以我放弃了。

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

【讨论】:

  • 只是想感谢您的提问和跟进。我们的项目遇到了类似的问题,并且花了很多时间来寻找问题和解决方案。直到找到解决方案后,我们才发现这个堆栈溢出帖子,但解释非常有帮助。在这里,您对 MS 的轻微失望与他们可能意识到的更多开发人员一样。
  • 不客气。我很高兴它对某人有所帮助,尤其是在这段时间之后!
猜你喜欢
  • 2014-09-30
  • 2016-02-16
  • 2017-10-10
  • 2013-06-02
  • 2010-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-26
相关资源
最近更新 更多