Darcy
Darcy

Reputation: 5368

Can NuGet edit a config file or only add to it?

I've been working on a NuGet package for my company and one of the requirements is being able to update some of our config files.

I know it's possible to add to a config file, but is it possible to edit one?

Example:

<add name="conn" connectionString="Data Source=.\;Initial Catalog=DB;Integrated Security=True" />

changes to below

<add name="conn" connectionString="Data Source=.\;Initial Catalog=DB;User ID=ex;Password=example" />

Upvotes: 17

Views: 12235

Answers (4)

DreamEvil
DreamEvil

Reputation: 189

Yes, it's possible, but you have to include install.ps1 file into tools folder. And then when you will get your package from nuget server, visual studio run Powershell scripts. I use this script

# fileName can be App.Config Or Web.Config or something else 
$fileName = "App.Config" 
$file=$project.ProjectItems.Item($fileName)

if($file.Properties){
    # Get localpath
    $localPath = $file.Properties.Item("LocalPath")
    if($localPath){
        $localPath = $localPath.Value   
    }
}

if ($localPath -eq $null) {
    Exit
}

#Load our config file as XML file
[xml]$file = Get-Content $localPath
if($file){

    # Create node 
    $childNode = $file.CreateElement("add")
    $childNode.SetAttribute("connectionString", "DataSource=.\;InitialCatalog=GVE;User ID=ex;Password=example")

    #Get parent node   
    $node = $file.SelectSingleNode("configuration/connectionStrings")

    #Insert our node into parent
    $node.AppendChild($childNode)

    $file.Save($localPath)
}

Upvotes: 0

Darcy
Darcy

Reputation: 5368

EDIT: The answer is now YES as of NUGET 2.6 and above.

The answer is NO. From the nuget site I found the following answer:

"When NuGet merges a transform file into a project's configuration file, it only adds elements or adds attributes to existing elements in the configuration file; it does not change existing elements or attributes in any other way."

http://docs.nuget.org/docs/creating-packages/configuration-file-and-source-code-transformations

Upvotes: 3

Erik A. Brandstadmoen
Erik A. Brandstadmoen

Reputation: 10588

As of NuGet 2.6 and above, you can actually transform Web.config files using the XDT syntax that is used for Web.config transforms in Visual studio.

See http://docs.nuget.org/docs/creating-packages/configuration-file-and-source-code-transformations:

Support for XML-Document-Transform (XDT)

Starting with NuGet 2.6, XDT is supported to transform XML files inside a project. The XDT syntax can be utilized in the .install.xdt and .uninstall.xdt file(s) under the package's Content folder, which will be applied during package installation and uninstallation time, respectively.

For example, to add MyNuModule to web.config file like what's illustrated above, the following section can be used in the web.config.install.xdt file:

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <system.webServer>
        <modules>
            <add name="MyNuModule" type="Sample.MyNuModule" xdt:Transform="Insert" />
        </modules>
    </system.webServer>
</configuration>

On the other hand, to remove only the MyNuModule element during package uninstall, the following section can be used in the web.config.uninstall.xdt file:

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <system.webServer>
        <modules>
            <add name="MyNuModule" xdt:Transform="Remove" xdt:Locator="Match(name)" />
        </modules>
    </system.webServer>
</configuration>

Upvotes: 16

Lee Harold
Lee Harold

Reputation: 1147

NuGet transforms can't edit existing values. But NuGet lets you run Powershell scripts on package install, so you can edit the config file that way.

Create an Install.ps1 file and use this code:

# Install.ps1
param($installPath, $toolsPath, $package, $project)

$xml = New-Object xml

# find the Web.config file
$config = $project.ProjectItems | where {$_.Name -eq "Web.config"}

# find its path on the file system
$localPath = $config.Properties | where {$_.Name -eq "LocalPath"}

# load Web.config as XML
$xml.Load($localPath.Value)

# select the node
$node = $xml.SelectSingleNode("configuration/connectionStrings/add[@name='gveconn']")

# change the connectionString value
$node.SetAttribute("connectionString", "Data Source=.\;Initial Catalog=GVE;User ID=ex;Password=example")

# save the Web.config file
$xml.Save($localPath.Value)

Upvotes: 30

Related Questions