如何在 ASP.NET Core Web 部署包中设置 ACL? 1.重新创建清单 XML2.重新创建参数 XML

问题描述

在 ASP.NET Core 之前,使用 certain MSBuild targets 调整 Web 部署包中的 ACL 非常容易:您可以在 AddIisSettingAndFileContentsToSourceManifestAddIisAndContentDeclareParametersItems 目标之后添加一些自定义步骤。

现在,在 Core 中,根据我自己的实验和 issues like this one,这些技巧不再起作用,因为

重新编写了 ASP.NET Core 项目的任务和目标...... ASP.NET 项目中使用的目标名称与 ASP.NET Core 不同。

我已经尝试使用出现在 Microsoft.NET.Sdk.Publish.MSDeployPackage.targets 中的目标,但我似乎无法让它发挥作用。我在包构建过程中遇到这种错误

The target "MSDeployPackagePublish" listed in a BeforeTargets attribute ... does not exist in the project,and will be ignored.

新的目标是什么?如何更改 ASP.NET Core Web Deploy 项目中的 ACL?

解决方法

令人困惑的是,Core 团队似乎删除了通过 MSBuild 自定义 MS Deploy 管道的能力。这些担忧在 several GitHub issues 中至少可以追溯到 2017 年,因此他们似乎无意恢复此功能。

问题的症结在于 MS Deploy 目标已经“简化以提高可读性”。 ?

_CreateManifestFiles target 过去由多个目标组成,我们可以在这些目标之间注入我们自己的目标,现在这样做:

  1. 删除所有先前指定的 MsDeploySourceManifest 规则。 ?
  2. 添加几个硬编码的 MsDeploySourceManifest 规则。
  3. 将清单 XML 写入磁盘。

同样,_CreateParameterFiles target 现在会这样做:

  1. 删除所有先前指定的 MsDeployDeclareParameters 规则。 ?
  2. 添加几个硬编码的 MsDeployDeclareParameters 规则。
  3. 将参数 XML 写入磁盘。

幸运的是,新的锁定设计有一个非常糟糕的解决方法。

1.重新创建清单 XML

所有目标都是公开可用的,所以我的解决方案只是用我自己的目标重写 _CreateManifestFiles 目标 -- 并覆盖清单 XML。以下是我在 .pubxml 中的最终结果:

<Target Name="ReCreateManifestFile" AfterTargets="_CreateManifestFiles">
  <ItemGroup>
    <MsDeploySourceManifest Remove="@(MsDeploySourceManifest)" />
    <MsDeploySourceManifest Include="IisApp">
      <Path>$(PublishIntermediateOutputPath)</Path>
    </MsDeploySourceManifest>
    <MsDeploySourceManifest Include="setAcl">
      <Path>$(PublishIntermediateOutputPath)logs</Path>
      <setAclAccess>Read,Write</setAclAccess>
      <setAclResourceType>Directory</setAclResourceType>
      <AdditionalProviderSettings>setAclAccess;setAclResourceType</AdditionalProviderSettings>
    </MsDeploySourceManifest>
  </ItemGroup>
  <CreateManifestFile Manifests="@(MsDeploySourceManifest)" ManifestFile="$(_MsDeploySourceManifestPath)" />
</Target>

请注意,此目标在 _CreateManifestFiles 之后立即执行。

那是最简单的部分!

2.重新创建参数 XML

我使用相同的策略创建参数文件。如果您复制 _CreateParameterFiles 但添加自己的 MsDeployDeclareParameters,它几乎可以满足您的所有需求。不幸的是,新的 SDK 还取消了这些规则设置 ExcludeFromSetParameter 的能力——如果您 read the code,则该值甚至永远不会反序列化。 ?

如果无法从 SetParameters.xml 中排除参数,您最终会得到一个如下所示的 SetParameters.xml:

<parameters>
  <setParameter name="IIS Web Application Name" value="Default Web Site/GeoGrok" />
  <setParameter name="LogsSetAclParam" value="" />  <!-- not what you want :( -->
</parameters>

SetParameters.xml 中的任何参数在部署时都不能被忽略,即使它有 DefaultValue。这意味着如果您的默认值是 {IIS Web Application Name}/logs,MSDeploy 不会自动替换 IIS 应用程序名称。

此外,SDK 的 CreateParameterFile 调用甚至不包含 DeclareParameterFile 属性,因此 DefaultValue 从未被写入到 parameters.xml 中! ?

我采用的(再次,糟糕的)解决方案是:

  1. 用您自己的 _CreateParameterFiles 元素重写 MsDeployDeclareParameters
  2. 调整 CreateParameterFile 以创建正确的 parameters.xml 文件。
  3. 复制静态 SetParameters.xml 文件,该文件仅包含您希望部署团队查看的参数。就我而言,它只有 IIS Web 应用程序名称 参数。

我的静态 SetParameters.xml 文件(我放在我的项目根目录中)如下所示:

<?xml version="1.0" encoding="utf-8"?>
<parameters>
  <setParameter name="IIS Web Application Name" value="Default Web Site" />
</parameters>

这是我的 .pubxml 文件中完成的参数目标:

<Target Name="ReCreateParametersFile" AfterTargets="_CreateParameterFiles">
  <ItemGroup>
    <MsDeployDeclareParameters Remove="@(MsDeployDeclareParameters)" />
    <MsDeployDeclareParameters Include="IIS Web Application Name">
      <Kind>ProviderPath</Kind>
      <Scope>IisApp</Scope>
      <Match>$(PublishIntermediateOutputPath)</Match>
      <DefaultValue>$(DeployIisAppPath)</DefaultValue>
      <Value>$(DeployIisAppPath)</Value>
      <Tags>IisApp</Tags>
      <Priority></Priority>
      <ExcludeFromSetParameter>false</ExcludeFromSetParameter>
    </MsDeployDeclareParameters>
    <MsDeployDeclareParameters Include="LogsSetAclParam">
      <Kind>ProviderPath</Kind>
      <Scope>setAcl</Scope>
      <Match>$(PublishIntermediateOutputPath)logs</Match>
      <DefaultValue>{IIS Web Application Name}/logs</DefaultValue>
      <Tags>Hidden</Tags>
      <Priority>$(VsSetAclPriority)</Priority>
      <ExcludeFromSetParameter>true</ExcludeFromSetParameter>  <!-- I'm useless! -->
    </MsDeployDeclareParameters>
  </ItemGroup>
  <CreateParameterFile Parameters="@(MsDeployDeclareParameters)"
                       DeclareParameterFile="$(_MSDeployParametersFilePath)"
                       DeclareSetParameterFile="$(_MSDeploySetParametersFilePath)"
                       IncludeDefaultValue="True"
                       OptimisticParameterDefaultValue="$(EnableOptimisticParameterDefaultValue)"
                       SetParameterFile="$(_MSDeploySetParametersFilePath)"
                       GenerateFileEvenIfEmpty="True" />
  <Copy SourceFiles="$(MSBuildProjectDirectory)\GeoGrok.Web.SetParameters.xml" DestinationFiles="$(_MSDeploySetParametersFilePath)" />
</Target>

注意 Copy 最后一步。

祝你好运!