【问题标题】:OWIN send static file for multiple routesOWIN 为多条路由发送静态文件
【发布时间】:2014-12-01 05:10:52
【问题描述】:

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

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

【问题讨论】:

  • 所以您希望任何访问服务器的 URL 都使用静态文件中间件为 index.html 提供服务?
  • 是的,任何路由(或任何匹配/app/*的路由)都会返回index.html文件。

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


【解决方案1】:

为了简单起见,同时仍然保留 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/* 之外的任何地方提供欢迎页面,而/app/* 将始终提供 index.html。

【讨论】:

  • 当您还需要提供 SPA 所需的其他静态文件(*.css、*.js 等)时,这似乎不起作用。它返回 index.html 作为响应内容。
  • 是的,如果您必须在/app 下提供其他静态资产,则需要在替换路径之前包含一些条件。您还可以在覆盖之前包含一个单独的UseStaticFiles。这样,它只会在之前的静态文件 MW 失败时尝试请求 index.html。
  • 我接受了你的想法,并添加了另一个电话到UseStaticFiles,这似乎已经成功了。谢谢!
【解决方案2】:

我在使用 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;
    }
}

上面的sn-p在我们找不到匹配请求的页面时返回index.html,SPA的入口点。

为了使用这个委托处理程序,您必须在启动 Owin 主机时将以下行添加到您的 HttpConfiguration() 中:

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

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

【讨论】:

  • 这在一定程度上会起作用,但在许多情况下,建议在生产中使用这样的实现。 File.ReadAllText 将自动检测编码(这可能会导致问题),并且不会像其他方法那样有效。
  • 感谢您的意见。那么您是否建议我使用类似于已接受答案的解决方案,或者是否有首选的 File.ReadAllText 替代方案?
猜你喜欢
  • 2017-07-12
  • 2022-11-13
  • 1970-01-01
  • 1970-01-01
  • 2015-06-01
  • 1970-01-01
  • 2014-07-28
  • 2015-01-25
  • 1970-01-01
相关资源
最近更新 更多