I am building an application that is an ASP.NET MVC and Angular 1.x hybrid. I use MVC as a shell and then layered Angular on top of it. I did this for a couple of reasons. First, it provided me with the ability to create an HTML helper class for script references to support cache busting. Second, it allows me to "push" a set of server side configurations to angular for things like web service URLs, etc. All of this seems to be working ok except for a single issue.
Currently, I am having to process a couple of IIS rewrite rules to make all of this work properly. In testing in a staged environment today, I published a link to Facebook that does not appear to work properly though and I'm not really sure why. Based on my understanding of the rule syntax, I thought it would work, but isn't.
Here are the IIS rewrite rules I currently have in web.config and why I have each rule:
<system.webServer>
<rewrite xdt:Transform="Replace">
<rules>
<rule name="cachebust">
<match url="([\S]+)(/v-[0-9]+/)([\S]+)" />
<action type="Rewrite" url="{R:1}/{R:3}" />
</rule>
<rule name="baseindex" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
<rule name="non-www" stopProcessing="true">
<match url="(.*)" negate="false"></match>
<conditions>
<add input="{HTTP_HOST}" pattern="^exampledomain\.org$" negate="true"></add>
</conditions>
<action type="Redirect" url="http://exampledomain.org/{R:1}"></action>
</rule>
</rules>
</rewrite>
</system.webServer>
1) The "cachebust" rule is used for script cache busting. The HTML helper I wrote takes the path of the script file and inserts a fake version # into the path. For example, "scripts/example.js" would become "scripts/v-123456789/example.js", where "123456789" are the ticks from the current date and time. This rule will rewrite the URL back to the original but since the page is output with the version stamped path, it will force my angular scripts to be reloaded by the browser in the event that they change. This rule appears to be working fine. Credit to Mads for this: https://madskristensen.net/blog/cache-busting-in-aspnet/
2) The "baseindex" rule is used to rewrite the URL so that ASP.NET will always serve the index.cshtml page that is used as the root for my site. This rule also appears to work fine. Credit to this SO QA: How do I configure IIS for URL Rewriting an AngularJS application in HTML5 mode?
3) The "non-www" rule is the problematic one. The goal of the rule is to redirect all www requests to non-www requests based on ScottGu's blog post (link below) about canonical host names and how they affect SEO. This rule works perfectly fine for www.example.org as it redirects the URL to example.org, but it fails when the URL looks like this: www.example.org/entity/1 where entity is a detail page for id = 1. In practice, it fails for www.example.org/about too. Since my web services require CORS to be enabled as they are on separate domains, this also needs to happen for that. https://weblogs.asp.net/scottgu/tip-trick-fix-common-seo-problems-using-the-url-rewrite-extension
For sake of completeness: HTML 5 mode is enabled for Angular and my route to the specified page is defined as such:
.state('entityDetail', {
url: '/entity/{id}',
templateUrl: 'app/pages/entity/entityDetail.html',
controller: 'entityDetailController',
controllerAs: 'entityDetailCtrl'
})
Also, my _Layout.cshtml contains the base href of:
<base href="/" />
and script references like such (except for the angular scripts that require the cachebust rule listed above):
<script type="text/javascript" src="scripts/jquery-2.2.0.min.js"></script>
I've tried several different versions of the rule, but they all lead to different issues. Since there are so many different things at play here, I am concerned that I am overlooking something or that I am wrong in my thinking on how this "should" work.
Any help would be greatly appreciated.