2

I have an ASP.NET MVC 4 web app. It has a default home page that handles all requests to http://www.mydomain.com as well as http://mydomain.com. I also have an MVC Area set up that can be accessed via www.mydomain.com/Foo/Hello/ (where "Foo" is the name of the area and "Hello" is a controller in that area).

If someone makes a request to foo.mydomain.com right now, it will route them to the default home page controller. I would like all requests to the foo subdomain root (eg. without a specific area/controller specified) to automatically be rerouted to the /foo/hello/ controller.

Additionally, I want any requests to the "Foo" Area via the www subdomain to be redirected to the "foo" subdomain. ie. I want all requests to www.mydomain.com/Foo/Goodbye to be automatically redirected to foo.mydomain.com/Foo/Goodbye

I have, of course, looked at lots and lots of other samples/questions, but none of them seem to address my exact issue.

I'm not sure if I should solve this issue with routes, route constraints, route handlers, etc.

Additionally: this application is hosted on Windows Azure Cloud Services, so I don't have full control over IIS settings.

Community
  • 1
  • 1
user2719100
  • 1,704
  • 3
  • 20
  • 25

2 Answers2

1

In your Web Server, the Application Pool of your site must have Integrated PipeLine Mode as highlighted below..

enter image description here

or you can find it through the Basic settings of your Application Pool like below..

enter image description here

Then I added the HttpModule in my sample MVC application

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

Then i added some code n Web.config for my HttpModule

<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>

Then in the host file I added the following code.

127.0.0.1  foo.mydomain.com

Then I added the Bindings for my website

enter image description here

Imad Alazani
  • 6,688
  • 7
  • 36
  • 58
  • I suppose this sort of answers my second requirement, although I was hoping to be able to do it using more of the native MVC routing rules. The way you described, I would also have to confirm that the first subdirectory accessed contains "foo" (eg. I would have to inverse your request URL match and add the virtual directory: `host.Contains("www.mydomain.com/foo/")` It should work, but seems kind of messy. – user2719100 Sep 03 '13 at 19:57
  • Also, I should mention that in order to properly detect the subdomain, I need to pull the HOST parameter from the HTTP headers. Using Url.Authority does not work for me. Additionally, I'm hosting this on Azure Cloud Services, so I don't have full control over IIS, although, I believe Integrated pipeline is the default. – user2719100 Sep 03 '13 at 19:59
  • To your first comment : If you pay attention to the condition, it will only update `HttpContext.Current.Request.Url.Authority` or Domain Name. That's it. Rest is in piece. – Imad Alazani Sep 03 '13 at 20:00
  • Perhaps I wasn't clear, but I have dozens of other MVC Areas, but only this one (Foo) has its own subdomain. So, I can't just route every request that isn't already for the foo.* subdomain over to the foo.* subdomain. The code you provided would route requests for `www.mydomain.com/Bar/Hola` to the foo subdomain, when it should just stay on the www subdomain. That is why I suggested that I need to also detect the /foo/ subdirectory request to identify that the target is the Foo area. Like I said I would rather do this with native MVC Routing, but this should work... – user2719100 Sep 03 '13 at 20:39
0

You can use URL Rewrite module for IIS7+ to achieve what you described. Documentation is here: URL Rewrite Module Configuration Reference.

Simplified example would be:

  1. Rewrite URL so that foo.mydomain.com access /foo/hello (so no redirect)
  2. Redirect URL www.mydomain.com/foo to foo.mydomain.com/foo

Add in your web.config, system.webServer node rewrite section:

...
    <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>

You can also edit/view those rules in IIS Manager, using GUI. Click your web site and go to IIS section / URL Rewrite module. Bellow you can see 1st rule in GUI.

URL Rewrite rule in IIS Manager

Nenad
  • 24,809
  • 11
  • 75
  • 93
  • 1
    Per one of my comments on @PKKG's answer, this application is all hosted on Windows Azure Cloud Services, so I don't have full control over the IIS settings. Is there another way I can create these rules? – user2719100 Sep 03 '13 at 23:33
  • 1
    Googling for a minute, it seems that URL rewrite is installed on Azure. Did you try to add rules in your web.config? – Nenad Sep 04 '13 at 19:11