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

时间:2014-12-01 05:10:53

标签: c# owin single-page-application katana

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

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

2 个答案:

答案 0 :(得分:23)

为了简单起见,同时仍保留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提供服务。

答案 1 :(得分:0)

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

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

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

public class CustomDelegatingHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        Task<HttpResponseMessage> 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将请求路由到正确的页面。