Wrapping StaticFileMiddleware to redirect 404 errors Wrapping StaticFileMiddleware to redirect 404 errors angularjs angularjs

Wrapping StaticFileMiddleware to redirect 404 errors


From your question I am not sure whether you are using IIS or selfhost. If you are using IIS, there is a much cleaner/faster solution than messing up with owin middleware:You can use IIS rewrite engine, copy the following inside your web config.

<system.webServer><rewrite>  <rules>    <!--Redirect selected traffic to index -->    <rule name="Index Rule" stopProcessing="true">      <match url=".*" />      <conditions logicalGrouping="MatchAll">        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />         <add input="{REQUEST_URI}" matchType="Pattern" pattern="^/api/" negate="true" />      </conditions>      <action type="Rewrite" url="/index.html" />    </rule>  </rules></rewrite>...</system.webServer>

This line allows all files to be served normally:

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

this line allows the api to be served normally

<add input="{REQUEST_URI}" matchType="Pattern" pattern="^/api/" negate="true" />

Everything else gets index.html


I didn't want to be tied to IIS, with the way asp.net core is moving forward. Here's how I got it to work using OWIN:

// catch all for html5/angular2 client routing urls that need to be redirected back to index.html// for original, see: http://stackoverflow.com/questions/27036448/how-to-intercept-404-using-owin-middleware/30741479#30741479app.Use(async (ctx, next) =>{    // execute the rest of the pipeline    //  though really, we're last in this configuration    //  but, this allows the other static file handlers    //  and web api route handlers to fail    await next();    // double check that we have a 404    //  we could also double check that we didn't request a file (with an extension of some sort)    if (ctx.Response.StatusCode != 404)    {        return;    }    // we have a 404, serve our default index.html    var middleware = new StaticFileMiddleware(        env => next(), new StaticFileOptions        {            FileSystem = new PhysicalFileSystem("./wwwroot"),            RequestPath = PathString.Empty        });    ctx.Request.Path = new PathString("/index.html");    await middleware.Invoke(ctx.Environment);});

I needed to call next() before I checked for the status code, because I assume the other middleware won't set the 404 until all middleware has a chance to handle it.

DISCLAIMER: I'm only starting to explore OWIN based hosting, so while this seems to work, there could be some non-best practices.