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

Ed *_*ham 5 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,以便较低级别的站点可以拥有自己不同的 URL,例如 www.BritSocAt.com,它映射到 www.ccesd.ac.uk/BritSocAt。

IIS 7.5 中的网站配置

每个站点都有自己的 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" } });
    }
Run Code Online (Sandbox Code Playgroud)

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

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

Ed *_*ham 5

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

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