Jeff Tillwick
Jeff Tillwick

Reputation: 41

ASP.net OWIN AngularJS html5mode url redirecting

I am trying to setup a single page application with a Web API restful back-end. I used the "OWIN WebAPI SPA Template" to start my project. This template defaults the static file serving to the public/ folder within the solution's root directory. I want to support html5 urls, IE. localhost/madeUpPath which should hit the index.html page. In order to do this, I setup a rewrite rule in the Web.config file:

<system.webServer>
  <rewrite>
      <rules>
          <rule name="Main Rule" stopProcessing="true">
              <match url=".*" />
              <conditions logicalGrouping="MatchAll">
                  <add input="{REQUEST_URI}" pattern="api/" ignoreCase="true" negate="true" />

                  <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                  <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
              </conditions>
              <action type="Rewrite" url="/" />
          </rule>
      </rules>
  </rewrite>
</system.webServer>

The issue I am having is that since the static files live in /public/ the {REQUEST_FILENAME} thinks the file is relative to / and the url localhost/main.css is rewritten to localhost/

I have tried changing the rule to this:

                  <add input="public/{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                  <add input="public/{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />

but that did not work. How can I achieve my desired result? Thank you.

Edit: I found something that seems to work, but isn't exactly what I was looking for.

<rewrite>
    <rules>
        <rule name="Main Rule" stopProcessing="true">
            <match url="([a-zA-Z0-9-_.\/]+\.(css|js|less|json|jpeg|jpg|png|gif|svg|xml|html))$" />
            <action type="Rewrite" url="/public/{R:0}" />
        </rule>
        <rule name="Second Rule" 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>
    </rules>
</rewrite>

Upvotes: 1

Views: 692

Answers (2)

Jonathan L.
Jonathan L.

Reputation: 682

We also use Owin to serve content out of a sub folder and the following works perfectly for us:

<rewrite>
  <rules>
    <rule name="Angular Routes" stopProcessing="true">
      <match url=".*" />
      <conditions logicalGrouping="MatchAll">
        <add input="{APPL_PHYSICAL_PATH}public{URL}" matchType="IsFile" ignoreCase="true" negate="true" />
        <add input="{APPL_PHYSICAL_PATH}public{URL}" matchType="IsDirectory" ignoreCase="true" negate="true" />
        <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
      </conditions>
      <action type="Rewrite" url="/" />
    </rule>
  </rules>
</rewrite>

It's very similar to this comment, but I changed their {REQUEST_URI} variables to {URL} so that it will also ignore existing files even if they have query strings, which is necessary for cache busting resources, like site.css?ec99043d9af49f2bd7c2.

Edit: I also just found this Microsoft example which with some tweaking may also work for this scenario, but I haven't tested it myself:

  <rewrite>
    <rules>
      <rule name="Angular Routes" 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="/MyApp/" />
      <!--<action type="Rewrite" url="/" />-->
      </rule>
    </rules>
  </rewrite>

Upvotes: 0

4ra
4ra

Reputation: 219

Firstly, this code doesn't because you're using OWIN server for static files:

           <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
        </conditions>

Could you please to use next code:

<rewrite>
    <rules>
        <rule name="Main Rule" stopProcessing="true">
            <match url="^((?!(api|\.)).)*$" />
            <action type="Rewrite" url="/" />
        </rule>
    </rules>
</rewrite>

Regular expression gives us ability to ignore api and any file paths.

Upvotes: 1

Related Questions