【问题标题】:How can I re-route a specific subdomain request to a different ASP.NET MVC controller?如何将特定的子域请求重新路由到不同的 ASP.NET MVC 控制器?
【发布时间】:2013-09-03 18:07:04
【问题描述】:

我有一个 ASP.NET MVC 4 Web 应用程序。它有一个默认主页来处理对http://www.mydomain.comhttp://mydomain.com 的所有请求。我还设置了一个 MVC 区域,可以通过 www.mydomain.com/Foo/Hello/ 访问(其中“Foo”是该区域的名称,“Hello”是该区域中的控制器)。

如果有人现在向foo.mydomain.com 发出请求,它会将他们路由到默认主页控制器。我希望对 foo 子域根的所有请求(例如,没有指定特定区域/控制器)自动重新路由到 /foo/hello/ 控制器。

此外,我希望将通过 www 子域对“Foo”区域的任何请求重定向到“foo”子域。 IE。我希望对www.mydomain.com/Foo/Goodbye 的所有请求都自动重定向到foo.mydomain.com/Foo/Goodbye

当然,我看过很多 lots of other samples/questions,但它们似乎都没有解决我的确切问题。

我不确定是否应该用路由、路由约束、路由处理程序等来解决这个问题。

此外:此应用程序托管在 Windows Azure 云服务 上,因此我无法完全控制 IIS 设置。

【问题讨论】:

    标签: c# asp.net asp.net-mvc asp.net-mvc-3 asp.net-mvc-4


    【解决方案1】:

    在您的 Web 服务器中,您站点的应用程序池必须具有集成管道模式,如下所示。

    或者您可以通过应用程序池的基本设置找到它,如下所示。

    然后我在我的示例 MVC 应用程序中添加了 HttpModule

    HttpModule

    public class MyModule1 : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.BeginRequest += context_BeginRequest;
        }
    
        public void Dispose() { }
    
        void context_BeginRequest(object sender, EventArgs e)
        {
            if (!System.Web.HttpContext
                           .Current
                           .Request
                           .Url
                           .Authority
                           .Contains("foo.mydomain.com"))
            {
                string URL = 
                    (System.Web.HttpContext.Current.Request.Url.Scheme + "://" +
                    "foo.mydomain.com" + 
                    HttpContext.Current.Request.Url.AbsolutePath + 
                    HttpContext.Current.Request.Url.Query);
                System.Web.HttpContext.Current.Response.Clear();
                System.Web.HttpContext.Current.Response.StatusCode = 301;
                System.Web.HttpContext.Current.Response.Status 
                                                        = "301 Moved Permanently";
                System.Web.HttpContext.Current.Response.RedirectLocation = URL;
                System.Web.HttpContext.Current.Response.End();
            }
        }
    }
    

    然后我为我的 HttpModule 添加了一些代码 n Web.config

    <system.webServer>
      <validation validateIntegratedModeConfiguration="false" />
      <modules>
        <add name="MyModule1" type="rewrite.MyModule1" />
      </modules>
      <handlers>
        <remove name="UrlRoutingHandler" />
      </handlers>
    </system.webServer>
    
    
    <system.web>
        <httpModules>
          <add name="MyModule1" type="rewrite.MyModule1" />
        </httpModules>
    </system.web>
    

    然后我在host文件中添加了以下代码。

    127.0.0.1  foo.mydomain.com
    

    然后我为我的网站添加了绑定

    【讨论】:

    • 我想这可以满足我的第二个要求,尽管我希望能够使用更多的本地 MVC 路由规则来做到这一点。按照您描述的方式,我还必须确认访问的第一个子目录包含“foo”(例如,我必须反转您的请求 URL 匹配并添加虚拟目录:host.Contains("www.mydomain.com/foo/") 它应该可以工作,但看起来有点乱.
    • 另外,我应该提到,为了正确检测子域,我需要从 HTTP 标头中提取 HOST 参数。使用 Url.Authority 对我不起作用。此外,我将它托管在 Azure 云服务上,因此我无法完全控制 IIS,但我相信集成管道是默认设置。
    • 致您的第一条评论:如果您注意条件,它只会更新HttpContext.Current.Request.Url.Authority或域名。就是这样。休息是件好事。
    • 也许我不是很清楚,但是我还有几十个其他的MVC区域,但只有这一个(Foo)有自己的子域。因此,我不能只将尚未针对 foo.* 子域的每个请求路由到 foo.* 子域。您提供的代码会将www.mydomain.com/Bar/Hola 的请求路由到 foo 子域,而它应该只保留在 www 子域上。这就是为什么我建议我还需要检测 /foo/ 子目录请求以识别目标是 Foo 区域。就像我说的,我宁愿用原生 MVC 路由来做这个,但这应该可以工作......
    【解决方案2】:

    您可以使用 IIS7+ 的 URL Rewrite 模块来实现您所描述的。文档在这里:URL Rewrite Module Configuration Reference

    简化的例子是:

    1. 重写 URL 以便 foo.mydomain.com 访问 /foo/hello(所以没有 重定向)
    2. 将 URL www.mydomain.com/foo 重定向到 foo.mydomain.com/foo

    在您的 web.config 中添加 system.webServer 节点 rewrite 部分:

    ...
        <rewrite>
          <rules>
            <rule name="Redirect mydomain.com/foo to foo.mydomain.com/foo" patternSyntax="Wildcard" stopProcessing="true">
              <match url="foo" negate="false" />
              <conditions>
                <add input="{HTTP_HOST}" pattern="mydomain.com" />
              </conditions>
              <action type="Redirect" url="http://foo.mydomain.com/{R:0}" redirectType="Temporary" />
            </rule>
            <rule name="Rewrite foo.mydomain.com to access /foo/hello" patternSyntax="Wildcard" stopProcessing="true">
              <match url="" />
              <conditions>
                <add input="{HTTP_HOST}" pattern="foo.mydomain.com" />
              </conditions>
              <action type="Rewrite" url="/foo/hello" />
            </rule>
          </rules>
      </rewrite>
    </system.webServer>
    

    您还可以使用 GUI 在 IIS 管理器中编辑/查看这些规则。单击您的网站并转到 IIS 部分/URL 重写模块。您可以在下面看到 GUI 中的第一条规则。

    【讨论】:

    • 根据我在@PKKG 的回答中的一位 cmets,此应用程序全部托管在 Windows Azure 云服务上,因此我无法完全控制 IIS 设置。还有其他方法可以创建这些规则吗?
    • 谷歌一分钟,似乎在 Azure 上安装了 URL 重写。您是否尝试在 web.config 中添加规则?
    猜你喜欢
    • 2011-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-10
    相关资源
    最近更新 更多