如何使用 OWIN 自托管的 Web api 提供 index.html 服务

问题描述 投票:0回答:2

应该是一个简单的问题,只是找不到答案。

我有一个带有 Web api 的 SPA (AngularJS),它由 Owin 自托管。我使用 Nancy 来提供页面服务,但我想摆脱 Nancy 并使用 Index.html 作为我的单页面。

我在这里看到了这个问题:如何将除 Web API 之外的所有内容路由到 /index.html

我无法使用接受的答案,因为我没有 MVC 和 HomeController,更新的问题中建议的方式也不起作用,我得到

No HTTP resource was found that matches the request URI 'http://admin.localhost:33333/'.
No route providing a controller name was found to match request URI 'http://admin.localhost:33333/'

asp.net-web-api routes single-page-application owin
2个回答
45
投票

将 Index.html 移至项目的根目录。然后在 Package Manager Console 中

install-package Microsoft.Owin.StaticFiles
并添加以下代码:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {

        const string rootFolder = ".";
        var fileSystem=new PhysicalFileSystem(rootFolder);
        var options = new FileServerOptions
                      {
                          EnableDefaultFiles = true,
                          FileSystem = fileSystem
                       };

        app.UseFileServer(options);

    }
}

这将默认提供您的 Index.html。

您可以查看 Scott Allen 的博客以获取更多阅读内容:

http://odetocode.com/blogs/scott/archive/2014/02/10/building-a-simple-file-server-with-owin-and-katana.aspx


0
投票

我最近遇到了同样的问题,我需要提供一个 单页应用程序(在我的例子中是 React)和来自同一个自托管 OWIN 管道的一些 api 控制器。接受的答案非常适合为客户端文件提供服务,但如果您的 SPA 使用客户端路由,则会失败。

如果您的 SPA 需要客户端路由(我使用了 React-router-dom),您需要将未映射到文件或 api 控制器的请求重定向到您的

index.html
文件。为此,您可以在管道末尾添加自定义中间件,并使用
Microsoft.Owin.StaticFiles
中的 SendFileAsync() 方法返回
index.html
:

public class OwinPipeline
{
    public void Configuration(IAppBuilder appBuilder)
    {
        // SPA files from /wwwroot
        var opts = new FileServerOptions
        {
            EnableDefaultFiles = true,
            FileSystem = new PhysicalFileSystem("./wwwroot"),
        };
        appBuilder.UseFileServer(opts);

        // Web API
        var config = new HttpConfiguration
        {
            IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always
        };
        config.MapHttpAttributeRoutes();
        appBuilder.UseWebApi(config);

        // Use index.html if not a file or controller route
        appBuilder.Use(async (context, _) =>
        {
            // If no middleware handled the request, send index.html.
            // this way the client side router can handle the route.
            await context.Response.SendFileAsync("./wwwroot/index.html");
        });
    }
}

这里有两点很重要:

  1. 中间件必须是管道中的最后一个。这样,只有当没有其他中间件匹配请求时,它才会被调用。
  2. 不要在最后一个中间件中调用
    await next()
    ,因为这会将响应代码更改为 404。这是 OWIN 管道的默认行为。

注:

  • 我将
    index.html
    和所有其他 SPA 文件放在项目中的
    wwwroot
    文件夹中。
  • 当您在
    SendFileAsync()
    中使用相对路径时,它使用
    Directory.GetCurrentDirectory()
    作为基本路径来定位您的文件。如果您的 Web 文件系统根目录与此不同,则会引发 FileNotFound 异常。在这种情况下,可能需要提供
    index.html
    文件的绝对路径。
© www.soinside.com 2019 - 2024. All rights reserved.