当我使用 Visual Studio 发布向导将我的 Blazor WASM 站点发布到第三方主机时,我的 web.config 转换没有任何效果

My web.config transformations are not having any effect when I publish my Blazor WASM site to a third party host using Visual Studio publish wizard

当我从 Visual Studio 2019 的发布向导将我的网站发布到我的第三方主机时,我的 web.config 转换没有任何效果。

我有一个 Blazor WebAssembly 应用程序和三个环境:开发、暂存和生产。

MyProject\Properties\PublishProfiles 中,我有一个 .pubxml 文件,每个文件用于第三方托管服务提供商的暂存和生产。 (我不需要 .pubxml 用于开发,因为我只计划在我的本地开发 PC 上使用 运行。

这是 Staging.pubxml 的样子:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <EnvironmentName>Staging</EnvironmentName>
        <WebPublishMethod>FTP</WebPublishMethod>
        <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
        <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
        <LastUsedPlatform>Any CPU</LastUsedPlatform>
        <SiteUrlToLaunchAfterPublish>staging.myproject.com</SiteUrlToLaunchAfterPublish>
        <ExcludeApp_Data>False</ExcludeApp_Data>
        <ProjectGuid>12c14c2e-4d13-4e23-bf64-8e92faf909e9</ProjectGuid>
        <publishUrl>ftp.hostingprovider.net</publishUrl>
        <DeleteExistingFiles>False</DeleteExistingFiles>
        <FtpPassiveMode>True</FtpPassiveMode>
        <FtpSitePath>myproject-blazor-stag</FtpSitePath>
        <UserName>myloginname</UserName>
        <_SavePWD>True</_SavePWD>
    </PropertyGroup>
</Project>

每当使用 Staging.pubxml 配置文件发布项目时,我想在 web.config 文件的 <configuration> 元素中插入以下内容:

<system.webServer>
   <httpProtocol>
      <customHeaders>
         <add name="blazor-environment" value="Staging" />
      </customHeaders>
   </httpProtocol>
</system.webServer>

https://docs.microsoft.com/en-us/aspnet/core/blazor/fundamentals/environments?view=aspnetcore-5.0#set-the-environment-via-header

我应该可以使用 web.config 转换来完成。

https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/transform-webconfig?view=aspnetcore-5.0

因此,在我的项目根目录中,我添加了一个名为 Web.Staging.config 的 XML 转换 内容如下:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
   <location>
      <system.webServer xdt:Transform="InsertIfMissing">
         <httpProtocol xdt:Transform="InsertIfMissing">
            <customHeaders xdt:Transform="InsertIfMissing">
               <add name="blazor-environment" value="Staging"
                    xdt:Locator="Match(name)"
                    xdt:Transform="InsertIfMissing" />
            </customHeaders>
         </httpProtocol>
      </system.webServer>
   </location>
</configuration>

我原以为,当我使用 Staging.pubxml 配置文件发布我的网站时,此 Web.Staging.config 转换会将缺少的部分添加到部署到第三方主机的 web.config 文件中.然后,当我在浏览器中加载 Blazor 应用程序时,它应该使用暂存环境的设置。不幸的是,转换从未应用于 web.config 文件。我下载了文件进行检查,并没有添加任何内容。因此,Blazor 应用程序使用生产环境的设置而不是暂存环境运行。

有人能看出我做错了什么吗?

编辑:现在有一个 minimal reproducible sample on my GitHub issue

您可以通过 SlowCheetah NuGet 包进行转换。
这个包在 Microsoft Dotnet Foundation 下,所以我可以确认 Visual Studio 项目的最新稳定版本目前支持它,包括 Blazor WASM。

解决方案

TheProject.csproj

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <PublishIISAssets>true</PublishIISAssets>
    <Configurations>Debug;Release;Staging</Configurations>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.9" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.9" PrivateAssets="all" />
    <PackageReference Include="Microsoft.VisualStudio.SlowCheetah" Version="3.2.26">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
  </ItemGroup>

  <ItemGroup>
    <None Include="web.config">
      <TransformOnBuild>True</TransformOnBuild>
    </None>
    <None Include="web.Release.config">
      <DependentUpon>web.config</DependentUpon>
      <IsTransformFile>True</IsTransformFile>
    </None>
    <None Include="web.Staging.config">
      <DependentUpon>web.config</DependentUpon>
      <IsTransformFile>True</IsTransformFile>
    </None>
  </ItemGroup>
</Project>

web.config

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <staticContent>
      <remove fileExtension=".blat" />
      <remove fileExtension=".dat" />
      <remove fileExtension=".dll" />
      <remove fileExtension=".json" />
      <remove fileExtension=".wasm" />
      <remove fileExtension=".woff" />
      <remove fileExtension=".woff2" />
      <mimeMap fileExtension=".blat" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".dll" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".dat" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".json" mimeType="application/json" />
      <mimeMap fileExtension=".wasm" mimeType="application/wasm" />
      <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
      <mimeMap fileExtension=".woff2" mimeType="application/font-woff" />
    </staticContent>
    <httpCompression>
      <dynamicTypes>
        <add mimeType="application/octet-stream" enabled="true" />
        <add mimeType="application/wasm" enabled="true" />
      </dynamicTypes>
    </httpCompression>
    <rewrite>
      <rules>
        <rule name="Serve subdir">
          <match url=".*" />
          <action type="Rewrite" url="wwwroot\{R:0}" />
        </rule>
        <rule name="SPA fallback routing" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
          </conditions>
          <action type="Rewrite" url="wwwroot\" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

web.Release.config

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <system.webServer xdt:Transform="InsertIfMissing">
      <httpProtocol xdt:Transform="InsertIfMissing">
        <customHeaders xdt:Transform="InsertIfMissing">
          <add name="blazor-environment" value="Prod"
               xdt:Locator="Match(name)"
               xdt:Transform="InsertIfMissing" />
        </customHeaders>
      </httpProtocol>
    </system.webServer>
</configuration>

web.Staging.config

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <system.webServer xdt:Transform="InsertIfMissing">
    <httpProtocol xdt:Transform="InsertIfMissing">
      <customHeaders xdt:Transform="InsertIfMissing">
        <add name="blazor-environment" value="Staging"
             xdt:Locator="Match(name)"
             xdt:Transform="InsertIfMissing" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>
</configuration>

我创建了两个发布配置文件,一个用于 Release,一个用于 Staging,两者都按预期工作。

如果您发布到文件夹,web.config 将在 bin\Staging\net5.0\browser-wasm\publish 文件夹中可用。

备注

感谢 SlowCheetah,您的转换将应用于 Build 过程,而不仅仅是 Publishing 过程。

因此您可以在 output 文件夹中找到转换后的 web.config,例如 bin\Staging\net5.0