生产环境中的 Asp.net 核心和 Angular : Spa is not being served

标签 asp.net angular production

我的 Web 应用程序是从 dotnet core 3.0 Angular 模板构建的。我想将第一个版本部署到生产环境中,但我很难为 Angular 应用程序提供服务。我使用 Kestrel 作为网络服务器(它是一个内部网应用程序)。

我已经使用构建 Asp.net 应用程序的 dotnet publish -c Release -o ../app-dist 发布了应用程序,它触发了 ng 来构建一个客户端的生产发布。生成的文件夹结构包括一个 app-dist/wwwroot 文件夹,其中包含一些 Assets ,例如 favicon,还有一个 app-dist/ClientApp/dist/app 文件夹,其中包含 index.html 和编译后的 jscss 资源。如果我通过在 app-dist 中运行 dotnet app.dll 来启动应用程序,Kestrel 会启动但无法为客户端应用程序提供服务。我可以从 wwwroot 访问次要 Assets 以及用于用户身份验证的 Razor 页面。

在我的 docker 部署中,尝试访问 https://host/https://host/index.html 时出现以下错误(以及作为 http 等价物):

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. Your application is running in Production mode, so make sure it has been published, or that you have built your SPA manually. Alternatively you may wish to switch to the Development environment.

当我在我的 macOS 开发系统上的 app-dist 中运行相同的命令时,我得到了同样的错误(在第一次设置 export ASPNETCORE_ENVIRONMENT=production 之后)。

在我的 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");
        }
    });
}

在我的 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>

我尝试将 Angular index.html 和编译后的文件复制到 wwwroot 以及 ClientApp 文件夹,但都没有生成区别。我还尝试设置 spa.Options.SourcePath = "ClientApp/dist/app";什么似乎配置不正确,或者接下来我应该调查什么?

最佳答案

如果您想在生产环境中更改服务应用程序的目录,您可以通过以下方式在 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";
    });
}

放弃 configuration.RootPath 应更改为您希望的路径。

关于生产环境中的 Asp.net 核心和 Angular : Spa is not being served,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58882081/

相关文章:

javascript - 在生产中自动关闭调试变量

c# - asp.net gridview 中的动态链接

asp.net - 如何将 Web 表单保存到 MySQL 数据库中?

c# - 识别未使用的类/控件/页面

angular - next.angular.io 和 angular.io 的区别

javascript - 检查所有控制表

javascript - 使用 css 和 javascript 突出显示单击文本框 div

angular - 使用 angularfire2 时要在 ngrx/store 中存储什么?

linux - ubuntu 服务器的正常磁盘读/写值

mysql - 需要洞察力 - 同步将在实时站点上使用的生产数据库的最佳实践是什么? CakePHP, Mysql