OWIN为多个路由发送静态文件

我正在制作一个位于ASP.Net WebAPI之上的SPA。 我正在等待使用HTML5历史而不是#/用于历史路由但是这会给深度链接带来问题,我需要确保//foo/bar都返回相同的HTML文件(我的JS将呈现正确的部分SPA)。

如何让OWIN / Katana为多个不同的url返回相同的HTML文件?

为了简单起见,同时仍保留StaticFiles中间件的所有缓存优势等,我只需使用内联中间件重写请求路径,就像这样

 public class Startup { public void Configuration(IAppBuilder app) { app.Map("/app", spa => { spa.Use((context, next) => { context.Request.Path = new PathString("/index.html"); return next(); }); spa.UseStaticFiles(); }); app.UseWelcomePage(); } } 

这将提供除/app/*任何内容的欢迎页面,它将始终为index.html提供服务。

我在使用Angular js时遇到了类似的问题,并使用了稍微不同的方法来解决问题。

我们使用Owin将路线映射到SPA的入口点(index.html)。 这允许您访问SPA并导航到不同的页面。 但是,如果你刷新了页面,你会得到404.基本上,AngularJS的路由和Owin / Katana的路由都是踩到彼此的脚趾。

我通过创建自定义DelegatingHandler解决了这个问题。 每当Owin / Katana无法找到与请求匹配的路由时,就使用该委托处理程序(404)。

 public class CustomDelegatingHandler : DelegatingHandler { protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { Task response = base.SendAsync(request, cancellationToken); if (response.Result.StatusCode == HttpStatusCode.NotFound) { response.Result.Content = new StringContent(File.ReadAllText(@"index.html")); response.Result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html"); response.Result.StatusCode = HttpStatusCode.OK; } return response; } } 

当我们无法找到与请求匹配的页面时,上面的代码段会返回SPA的入口点index.html。

要使用此委托处理程序,必须在启动Owin主机时将以下行添加到HttpConfiguration():

  var httpConfig = new HttpConfiguration(); httpConfig.MessageHandlers.Add(new CustomDelegatingHandler()); 

简而言之,我有一个映射到SPA的默认路由,任何无法识别的路由都将通过DelegatingHandler并提供相同的SPA。 我们不修改Request.Path,允许SPA将请求路由到正确的页面。