dotnet / sdk

Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI
https://dot.net/core
MIT License
2.59k stars 1.03k forks source link

Including additional "Web.config" files in WebConfigsToTransform causes ParameterizeTransformXml to fail #12481

Open richardszalay opened 5 years ago

richardszalay commented 5 years ago

Steps to reproduce

  1. In an ASP.NET ("classic") Project, include transforms on Views\Web.config (or otherwise include an additional WebConfigsToTransform on a file named Web.config)
  2. Publish to an MSDeploy target (eg. package)

Expected behavior

Connection strings in Web.config are auto-parameterised. The additional Web.config does not cause an error.

Actual behavior

The following error is generated:

C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web .Publishing.targets(2311,5): error : Could not open Source file: Could not find a part of the path 'obj\Debug\TransformWebConfig\transformed\Views\Web.config;obj\Debug\TransformWebConfig\transformed\Web.config'.

Root cause

The issue is that ParameterizeTransformXml.Source is a string rather than an ITaskItem, but it's use in AutoParameterizationWebConfigConnectionStringsCore makes it look like it's batchable. The net result is that while all of the metadata values cause the invocation to be batched, the Source property itself just gets the same semicolon-delimited string representation of the items when there is more than one.

Workaround

Setting AutoParameterizationWebConfigConnectionStrings to false works, but it also disables auto-parameterization of Web.config connection strings (unsurprisingly).

AutoParameterizationWebConfigConnectionStringsCore uses _WebConfigsToAutoParmeterizeCS, which is copied from WebConfigsToTransform in PreAutoParameterizationWebConfigConnectionStrings. The workaround is therefore to hook in after that and remove all Web.config items from _WebConfigsToAutoParmeterizeCS that aren't "/Web.config":

<Target Name="RemoveAdditionalWebConfigsToTransformToPreventParameterizeTransformXmlError" AfterTargets="PreAutoParameterizationWebConfigConnectionStrings">
  <ItemGroup>
    <_WebConfigsToAutoParmeterizeCS Remove="@(_WebConfigsToAutoParmeterizeCS)" 
      Condition="'%(TransformScope)' != '$([System.IO.Path]::GetFullPath($(WPPAllFilesInSingleFolder)\Web.config)'" />
  </ItemGroup>
</Target>
Shilohe commented 5 years ago

Richard, where do place that hook? in a custom build file?

Shilohe commented 5 years ago

Rich, I saw a post from you in another site and I think I was able to fix the problem by creating a ProjectName.wpp.target file like this

`

<_WebConfigsToAutoParmeterizeCS Remove="@(_WebConfigsToAutoParmeterizeCS)" Condition="'%(TransformScope)' != '$([System.IO.Path]::GetFullPath($(WPPAllFilesInSingleFolder)\Web.config)'" />

`

richardszalay commented 5 years ago

@Shilohe Correct, ProjectName.wpp.targets is the most appropriate place to put it.