使用 Web API 路由 Angular 2 应用程序
Routing an Angular 2 app with Web API
我有一个使用 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 API 项目一无所知,因此我还需要 运行 从 Visual Studio 中启动 IIS Express http://localhost:5200
。
此设置运行良好,让我可以利用 Angular CLI 的实时重新加载支持。
对我来说最大的缺点是这个配置与我们对生产的期望不同。在那里,我希望有一个网络服务器 (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
中断。
我想我需要以下两件事之一:
- 一种创建路线的方法,因此对
/index.html
的引用服务于 /dist/index.html
,或
- 一种使用前面提到的 StaticFiles 程序集的方法。
那么我该如何实现呢?
您需要首先 禁用 angular 文件的 Web api 路由,将其添加到 web.config,在 <system.webServer> </system.webServer>
内:
<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>
然后,将 <base href="/">
添加到您的 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>
我无法让 为我工作,但他确实让我走上了正轨。
我需要两条规则:一条从根目录为 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>
首先,您应该像下面这样发布您的 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>
注意 <action type="Rewrite" url="/" />
中的 url 是 --base-href /
中的 url .
我有一个使用 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 API 项目一无所知,因此我还需要 运行 从 Visual Studio 中启动 IIS Express http://localhost:5200
。
此设置运行良好,让我可以利用 Angular CLI 的实时重新加载支持。
对我来说最大的缺点是这个配置与我们对生产的期望不同。在那里,我希望有一个网络服务器 (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
中断。
我想我需要以下两件事之一:
- 一种创建路线的方法,因此对
/index.html
的引用服务于/dist/index.html
,或 - 一种使用前面提到的 StaticFiles 程序集的方法。
那么我该如何实现呢?
您需要首先 禁用 angular 文件的 Web api 路由,将其添加到 web.config,在 <system.webServer> </system.webServer>
内:
<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>
然后,将 <base href="/">
添加到您的 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>
我无法让
我需要两条规则:一条从根目录为 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>
首先,您应该像下面这样发布您的 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>
注意 <action type="Rewrite" url="/" />
中的 url 是 --base-href /
中的 url .