【问题标题】:Routing an Angular 2 app with Web API使用 Web API 路由 Angular 2 应用程序
【发布时间】:2017-06-12 00:52:34
【问题描述】:

我有一个使用 Angular CLI 创建的 Angular 2 应用程序。这必须调用 .NET 4.6 Web API。这个路线设置让我发疯了。

对于 Angular,输出的默认文件夹是 /dist。 Angular CLI 完成了所有你梦寐以求的缩小和摇树,然后将其 JavaScript 文件和 index.html 输出到该文件夹​​。

所以如果我运行index.html,这些文件将从同一个文件夹中检索。一切正常,因为index.html 包含这样的标签:

<base href="/">

Web API 项目具有预期的结构,Angular 应用程序是其根目录中的寄生虫。

所以它看起来像这样:

WebAPI_Project
|- App_Start
|    |
|    |-WebApiConfig.cs
|- Controllers
|- Models
|- src /* This is the root of the Angular app */
|    |- app
|    |    |- core           /* These three folders */
|    |    |- shared         /* are for the modules */
|    |    |- another_module /* used in the app     */
|    |    |- app.component.ts
|    |    |- app.module.ts
|    |- index.html
|- dist /* This is the Angular output folder */
     |- index.html
     |- main.bundle.js

WebApiConfig.cs 具有默认设置:

public static void Register(HttpConfiguration config)
{
    // Web API routes
    config.MapHttpAttributeRoutes();

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}

为了运行 Angular 应用程序,我使用普通的 ng serve,它在 http://localhost:4200 创建一个 Web 服务器。这个 Web 服务器对 Web API 项目一无所知,所以我也需要在 Visual Studio 中运行它,它会在 http://localhost:5200 启动 IIS Express。

这个设置工作得相当好,让我可以利用 Angular CLI 的实时重新加载支持。

对我来说最大的缺点是这种配置与我们对生产的期望不同。在那里,我希望有一个 Web 服务器 (IIS),同时为 Web API 项目(目前位于 /api/)和 Angular 应用程序(最好位于 /)提供服务。另外,在开发中,我不得不考虑 CORS,而生产设置不会。

为此,我需要更改 WebApiConfig 路由以提供我的静态文件,该文件将位于 /dist/ 下。

对于 ASP.NET Core 和 MVC 4,有许多文章展示了我应该如何在 Startup.cs 中使用 Microsoft.AspNetCore.StaticFiles(或 Microsoft.AspNet.StaticFiles)。基本上,将以下两行添加到Configure 函数中:

public void Configure(IApplicationBuilder app, IHostingEnvironment env,
    ILoggerFactory loggerFactory)
{
    // Other stuff

    // Two new lines
    app.UseStaticFiles();
    app.UseDefaultFiles();

    app.UseMvc(m =>
    {
        // Other routes specified here
    });
}

问题是我既不使用 ASP.NET Core 也不使用 MVC。

尽管 Web API 显然是没有视图的 MVC,但 Web API 项目只带有 WebApiConfig.cs 文件,没有 Startup.cs 和 `IApplicationBuilder'。

我尝试将此行添加到我的 Register 函数中:

config.Routes.IgnoreRoute("StaticFiles", "*.html");

这服务于 index.html(但在 localhost:5200/dist/index.html),但它找不到它的任何资产,因为 base href="/"。我可以在 index.html 中更改它,但随后 ng serve 会中断。

我认为我需要以下两件事之一:

  1. 一种创建路由的方法,以便对/index.html 的引用服务于/dist/index.html,或者
  2. 一种使用前面提到的 StaticFiles 程序集的方法。

那我该怎么做呢?

【问题讨论】:

    标签: angular asp.net-web-api url-routing angular-cli asp.net-web-api-routing


    【解决方案1】:

    您需要首先禁用 Angular 文件的 Web api 路由,将其添加到 web.config 中的&lt;system.webServer&gt; &lt;/system.webServer&gt;

    <rewrite>
      <rules>
        <rule name="AngularJS" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
            <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
          </conditions>
          <action type="Rewrite" url="/index.html" />
        </rule>
      </rules>
    </rewrite>
    

    然后,将&lt;base href="/"&gt; 添加到您的 index.html。

    UPD:重写对 index.html 的访问

    您可以添加另一个重写规则来覆盖对您的 /dist/ 文件夹的访问权限:

    <rewrite>
        <rules>
            <rule name="DistAccess" stopProcessing="true">
                <match url="^(.*)/dist/(.*)" />
               <action type="Rewrite" url="{R:1}/{R:3}" />
            </rule>
        </rules>
    </rewrite>
    

    【讨论】:

    • 太棒了!我现在可以从 Visual Studio 或 ng serve 提供我的 Angular 应用程序。有没有办法让我重写它,使 index.html 位于 /,而不是 /dist/
    • 我完全不明白你需要什么,如果你需要像yourdomain.com/some-angular-url 这样访问你的应用程序,你需要将重写操作更改为&lt;action type="Rewrite" url="/dist/index.html" /&gt;,但是如果你想存储你的 index.html dist 文件夹,你需要使用你的模块绑定器
    • HTML和JS文件都在/dist/下。我希望它们在/ 上提供服务,因此如果用户在www.something.com/ 上加载站点,他将在index.html 上提供服务,它应该可以访问其所有脚本文件。
    • 如果您将您的操作链接到/dist/index.html,您将获得相同的结果,但只有数据将存储在/dist/ 中,但用户也会看到www.something.com/
    • 我们在某个地方错过了彼此。使用您的答案,我仍然只能在/dist/index.html 访问应用程序,地址栏反映/dist/ 并且无法加载资源(base href = "/")。我想要的是地址栏显示//dist/index.html 来提供服务。它的 JS 文件可以使用 /script.js 访问,但实际上是从 /dist/script.js 提供的。
    【解决方案2】:

    我无法让 Dmitriy's answer 为我工作,但他确实让我走上了正轨。

    我需要两条规则:一条从根目录为 Angular 应用程序提供服务,同时维护 Web API /api/ 路由,另一条用于提供默认文档。

    他们在这里:

    <rewrite>
      <rules>
          <rule name="Serve Angular app from root" stopProcessing="true">
            <match url="([\w\.]+)" />
            <conditions>
              <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
            </conditions>
            <action type="Rewrite" url="/dist/{R:1}" />
          </rule>
          <rule name="Default document" stopProcessing="true">
            <match url="^$" />
            <action type="Rewrite" url="/dist/index.html" />
          </rule>
        </rules>
    </rewrite>
    

    【讨论】:

    • 我也有类似的情况。将此添加到 web.config 文件似乎对我不起作用。我将此添加到 部分
    • 这对我有用,除了我在 root 本身中部署了 angular 2 文件,所以我从你的示例中删除了 /dist。谢谢。
    • 这在使用域名时有效。如果我们在 URL 中有路由并将其粘贴到地址栏上,它仍然会搜索 API,而不是使用路由参数加载 index.html
    【解决方案3】:

    首先你应该像下面这样发布你的 Angular 项目。

    ng build --prod="true" --base-href /
    

    然后将 Web 配置文件添加到您的 Angular 项目中。

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
    <system.webServer>
    <rewrite>
      <rules>
        <rule name="AngularJS Routes" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
            <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
          </conditions>
          <action type="Rewrite" url="/" />
        </rule>
      </rules>
    </rewrite>
    </system.webServer>
    </configuration>
    

    注意&lt;action type="Rewrite" url="/" /&gt;中的url是--base-href /中的url。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-28
      • 2019-01-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多