0
votes

I am trying to combine IIS URL Rewriting with routing in an ASP.Net 4.5 webforms site for subdomains and sub-directories.

I am trying to combine URL Rewriting in IIS with Routing in ASP.Net 4.5 for a webforms site. The solution I have right now works great for rewriting a subdomain with optional parameters to routing values, but I am struggling to pass sub-directory URLs to routes or querystrings. Most of the parameters I am working with are also optional so the rules have to consider any combination of those parameters or nothing.

The end goal is a feathering effect with hyphen separated locations on the subdomain side and categories on the sub-directory side. For instance a URL containing all parameters would be something like http://city-state.example.com/categoryslug/subcategoryslug

The rule I have in place in my web.config for the subdomains and the routes I have in my RouteConfig.cs are as follows:

<rewrite>
      <rules>
      <rule name="Rewrite subdomains">
        <match url=".*" />
        <conditions>
          <add input="{HTTP_HOST}" pattern="^(^$|[^\-]*)(^$|[\-]?)([^\-]\w)\.example\.net$" />
          <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        </conditions>
        <action type="Rewrite" url="{ToLower:/local/{C:3}/{C:1}}" />
    </rule>

      </rules>
      <outboundRules>
        <rule name="RewriteRelativePaths" preCondition="ResponseIsHtml1">
          <match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script" pattern="^/(.*)" negate="false" />
          <action type="Rewrite" value="http://example.net/{R:1}" />
        </rule>
        <preConditions>
          <preCondition name="ResponseIsHtml1">
            <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
          </preCondition>
        </preConditions>
      </outboundRules>
    </rewrite>


From RouteConfig.cs

// Geographic SubDomains
            routes.MapPageRoute("local/state", "local/{state}", "~/local/Default.aspx");
            routes.MapPageRoute("local/state/city", "local/{state}/{city}", "~/local/Default.aspx");


Potential Conflicting routes:

//Category
            routes.MapPageRoute("category", "{catslug}", "~/category/Default.aspx");
            //SubCategory
            routes.MapPageRoute("category/subcategory", "{catslug}/{scatslug}", "~/category/Default.aspx");

The expected result in the end should rewrite something like http://city-state.example.com/categoryslug/subcategoryslug to ~/local/{state}/{city}/{categoryslug}/{subcategoryslug} but I see a potential conflict between that route and something like ~/local/{state}/{categoryslug} in which I don't think the application will be able to distinguish between state/category and state/city.

I also have some potentially conflicting routes for category/subcategory where the root domain displays categories using slugs. My concern there is that a route containing the same pattern of category/subcategory might end up being sent to the root domain instead of the subdomain.

Due to the aforementioned concerns I think using querystrings for the categories would be better than using routes. right now I can load a page at http://city-state.example.com/?category=categoryslug&subcategory=subcategoryslug just fine. Next I would like to be able to change those querystrings to categoryslug/subcategoryslug and rewrite it to /local/{state}/{city}/?categoryslug=categoryslug&subcategoryslug=subcategoryslug. I DO NOT want the url rewritten to anything like ?category=&subcategory= because that would not be compatible with how the pages select data based on querystrings.

1
Could you please explain your requiremnet in detail? I can not understand what you exactly want to do. - Jalpa Panchal
Well what I have has changed slightly the routes are now {state}-{city} and the pattern now ends with \.net(.*) rewritten as condition 4. I have tested the routing without the rewrite rule and it works fine. It seems like the problem is that the rewrite rule does not pass the fourth condition. That being anything after \.net - CopBlaster
Thanks for sharing your experience. It will be appreciated if you could post the solution and mark yourself as an answer. So that your post could help more people. - Jalpa Panchal
Posted the answer, should be useful for anyone trying to route wildcard subdomains and path info, which is what I should have had all along instead of R:1 - CopBlaster

1 Answers

0
votes

  <rule name="Rewrite subdomains">
    <match url=".*" />
    <conditions>
      <add input="{HTTP_HOST}" pattern="^(^$|[^\-]*)(^$|[\-]?)([^\-]\w)\.example\.com$" />
      <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    </conditions>
    <action type="Rewrite" url="{ToLower:/local/{C:3}{C:2}{C:1}{PATH_INFO}}" appendQueryString="true" />
</rule>

  </rules>
  <outboundRules>
    <rule name="RewriteRelativePaths" preCondition="ResponseIsHtml1">
      <match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script" pattern="^/(.*)" negate="false" />
      <action type="Rewrite" value="http://example.com/{R:1}" />
    </rule>
    <preConditions>
      <preCondition name="ResponseIsHtml1">
        <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
      </preCondition>
    </preConditions>
  </outboundRules>
</rewrite>