我有一个使用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中运行它,它在http://localhost:5200
启动IIS Express。
此设置运行良好,并允许我利用Angular CLI的实时重新加载支持。
对我来说,最大的缺点是这种配置与我们对生产的预期不同。在那里,我希望有一个Web服务器(IIS),同时提供Web API项目(目前为/api/
)和Angular应用程序(最好是/
)。此外,在开发中,我不得不考虑CORS,生产设置不会。
为此,我需要更改WebApiConfig路由以提供我的静态文件,该文件将位于/dist/
下。
对于ASP.NET Core和MVC 4,有很多文章展示了如何在Microsoft.AspNetCore.StaticFiles
中使用Microsoft.AspNet.StaticFiles
(或Startup.cs
)。基本上,将以下两行添加到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
,或那我该如何实现呢?
答案 0 :(得分:4)
您需要第一次禁用角度文件的网络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>
答案 1 :(得分:2)
我无法让Dmitriy's answer为我工作,但他确实让我走上正轨。
我需要两个规则:一个是在维护Web API /api/
路由的同时从根服务Angular应用程序,另一个是为默认文档提供服务。
他们是:
<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>
答案 2 :(得分:0)
首先,您应该像下面这样发布您的 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="/" />
中的网址是 --base-href /
中的网址。