Updating variables in web.config outside appSettin

2020-04-11 10:56发布

问题:

I need to update values in web.config in Azure TFS. I am able to get the value for connectionString replaced which is part of the appSettings (for this to work, I needed to enable the setting named XML variable substitution (under IIS Web Deploy).

However, there are other areas within web.config which do not get replaced.

I have tried several different approaches, using different tasks for token replacement, using the "Release" or "Environment" setting for variables, using variable groups. However, none of these worked.

Currently I am using the Replace tokens task (available at https://github.com/qetza/vsts-replacetokens-task#readme )

I have set the Token Prefix and Suffix to __ (to match with what is web.config)

Here is an extract of the web.config file

<?xml version="1.0"?>
<configuration>
    <appSettings>
        <add key="ConnectionString" value="__ConnectionString__"/>
    </appSettings>
    <system.web>
        <pages theme="__Theme__" controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID">
            <controls>
                <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
            </controls>
        </pages>
    </system.web>
    <system.serviceModel>       
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
        <bindings>
            <customBinding>
                <binding name="TestBinding1">
                    <textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16" messageVersion="Soap12" writeEncoding="utf-8">
                        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    </textMessageEncoding>
                    <httpsTransport manualAddressing="false" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous" bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard" keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous" realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false" useDefaultWebProxy="true" requireClientCertificate="false" />
                </binding>
            </customBinding>
            __basicHttpBindingOptionalBinding__
        </bindings>
        <client>
            <endpoint address="__TestEndPoint__" binding="customBinding" bindingConfiguration="TestBinding1" contract="BSEInspectionsWebServiceForFDA.StateDataTransfer" name="StateDataTransferPort" />
            __endpointOptionalEndpoint__
        </client>
    </system.serviceModel>
</configuration>

I expect only blank lines for basicHttpBindingOptionalBinding and endpointOptionalEndpoint. The Theme needs to be replaced with TestTheme and TestEndPoint needs to be set with the value defined in variables.

回答1:

For replacing __Theme__, __TestEndPoint__, I recommend extension task Magic Chunks.

You can install Magic Chunks task to your organization and add it to your pipeline. It tested your web.config with below example settings for magic chunk task:

For replacing basicHttpBindingOptionalBinding , i recommend another extension task RegEx Find & Replace

You can reference your pipeline variables in both the tasks. I added above two tasks to my test pipeline. The values in web.config was replaced successfully.

Update: To extract the web.config from the build artifacts using powershell task to run below scripts:

You need to config $sourceFile and $destFile yourself. $sourceFile should be the absolute path to zip file.

$sourceFile="$(Build.ArtifactStagingDirectory)\AboutSite.zip"
$destFile="$(Build.BinariesDirectory)\web.config"

Add-Type -Assembly System.IO.Compression.FileSystem
$zip = [IO.Compression.ZipFile]::OpenRead($sourceFile)
$zip.Entries | where {$_.Name -like 'web.config'} | foreach {[System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, $destFile, $true)}
$zip.Dispose()