[英]Asp.net core and Angular in production: Spa is not being served
My web application was scaffolded from the dotnet core 3.0 Angular template.我的 web 应用程序是从 dotnet core 3.0 Angular 模板构建的。 I want to deploy the first version into production but I am struggling to have the Angular app served.
我想将第一个版本部署到生产中,但我正在努力提供 Angular 应用程序。 I am using Kestrel as the webserver (it's an intranet application).
我使用 Kestrel 作为网络服务器(它是一个 Intranet 应用程序)。
I have published the application with dotnet publish -c Release -o../app-dist
which build the Asp.net application and it triggered ng
to build a production release of the client.我已经使用
dotnet publish -c Release -o../app-dist
了应用程序,它构建了 Asp.net 应用程序,它触发了ng
来构建客户端的生产版本。 The resulting folder structure includes a app-dist/wwwroot
folder which has some assets like favicon and it has a app-dist/ClientApp/dist/app
folder with the index.html
and the compiled js
and css
assets.生成的文件夹结构包括一个
app-dist/wwwroot
文件夹,其中包含一些资产,例如 favicon,它有一个app-dist/ClientApp/dist/app
文件夹,其中包含index.html
以及编译后的js
和css
资产。 If I start the application by running dotnet app.dll
in app-dist
, Kestrel starts but it fails to serve the client application.如果我通过在
app-dist
中运行dotnet app.dll
来启动应用程序,Kestrel 会启动,但它无法为客户端应用程序提供服务。 I can access the minor assets from wwwroot
as well as the Razor pages that are used for user authentication.我可以从
wwwroot
以及用于用户身份验证的 Razor 页面访问次要资产。
In my docker deployment, I get the following error when trying to access https://host/
or https://host/index.html
(as well as http
equivalents): In my docker deployment, I get the following error when trying to access
https://host/
or https://host/index.html
(as well as http
equivalents):
System.InvalidOperationException: The SPA default page middleware could not return the default page '/index.html' because it was not found, and no other middleware handled the request.
System.InvalidOperationException:SPA 默认页面中间件无法返回默认页面“/index.html”,因为未找到它,并且没有其他中间件处理该请求。 Your application is running in Production mode, so make sure it has been published, or that you have built your SPA manually.
您的应用程序正在生产模式下运行,因此请确保它已发布,或者您已手动构建了 SPA。 Alternatively you may wish to switch to the Development environment.
或者,您可能希望切换到开发环境。
When I run the same command in app-dist
on my macOS development system I get the same error (after first setting export ASPNETCORE_ENVIRONMENT=production
).当我在我的 macOS 开发系统上的
app-dist
中运行相同的命令时,我得到了同样的错误(在第一次设置export ASPNETCORE_ENVIRONMENT=production
之后)。
In my Startup.cs
I have the following:在我的
Startup.cs
中,我有以下内容:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseStaticFiles();
if (!env.IsDevelopment())
{
app.UseSpaStaticFiles();
}
...
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}
In my csproj:在我的 csproj 中:
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
<IsPackable>false</IsPackable>
<SpaRoot>ClientApp\</SpaRoot>
<DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
<BuildServerSideRenderer>false</BuildServerSideRenderer>
</PropertyGroup>
...
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm run build -- --prod" />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm run build:ssr -- --prod" Condition=" '$(BuildServerSideRenderer)' == 'true' " />
<ItemGroup>
<DistFiles Include="$(SpaRoot)dist\**; $(SpaRoot)dist-server\**" />
<DistFiles Include="$(SpaRoot)node_modules\**" Condition="'$(BuildServerSideRenderer)' == 'true'" />
<ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
<RelativePath>%(DistFiles.Identity)</RelativePath>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</ResolvedFileToPublish>
</ItemGroup>
</Target>
I have tried copying the Angular index.html
and compiled files to the wwwroot
as well as the ClientApp
folder, but neither made a difference.我尝试将 Angular
index.html
和编译文件复制到wwwroot
以及ClientApp
文件夹,但两者都没有区别。 I also tried setting spa.Options.SourcePath = "ClientApp/dist/app";
我也尝试设置
spa.Options.SourcePath = "ClientApp/dist/app";
. . What seems incorrectly configured, or what should I investigate next?
什么似乎配置不正确,或者我接下来应该调查什么?
If you want to change the directory of the served app in production you can do it in ConfigureServices
following way:如果您想在生产环境中更改服务应用程序的目录,您可以在
ConfigureServices
中通过以下方式进行:
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
}
Aborve the configuration.RootPath
should be changed to your wished path.放弃
configuration.RootPath
。RootPath 应该更改为您希望的路径。
The location of the files was wrong.文件的位置错误。 I moved the files to
ClientApp\dist\
and that was the location that the middleware was looking for.我将文件移动到
ClientApp\dist\
,这就是中间件正在寻找的位置。 Strange configuration.奇怪的配置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.