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.