简体   繁体   English

生产中的 Asp.net 内核和 Angular:Spa 未提供服务

[英]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以及编译后的jscss资产。 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.奇怪的配置。

In my case this was because of a trailing slash in the Angular Api root在我的情况下,这是因为 Angular Api 根中的斜杠

Instead of代替

http://localhost:81

i had我有

http://localhost:81/

Remove the slash and you will be fine.删除斜线,你会没事的。 I have answered this here在这里回答了这个

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM