- | rssFeed | My book on MSBuild and Team Build | Archives and Categories Saturday, March 02, 2013

MSDeploy: How to update app settings on publish based on the publish profile

On twitter @vishcious asked me a question related to publishing. The question was

I have a web project that I am publishing to multiple locations using Visual Studio. I have setup multiple profiles and would like to update the values for these app settings differently for each profile. How can I achieve this? I am using parameters.xml to define the MSDeploy parameters.

 

Note: If you are publishing from VS and don’t care about packaging then you can use profile specific transforms as a simpler way to achieve this result. The rest of the post here assumes you specifically want MSDeploy parameters. To learn more about profile specific transforms see my short video at http://www.youtube.com/watch?v=HdPK8mxpKEI

If you are not familiar you can create custom MSDeploy parameters when you publish/package your application by creating an XML file named parameters.xml in the root of the project. A good resource on this is Vishal’s blog post. I have  created a sample (links below) which demonstrates how to accomplish what the task. Below are the project artifacts that I’ve created to setup the parameters.

web.config

<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="email" value="default@example.com"/>
    <add key="url" value="example.com"/>
  </appSettings>
</configuration>

Parameters.xml

<?xml version="1.0" encoding="utf-8" ?>
<parameters >

  <parameter name="email" description="description">
    <parameterEntry kind="XmlFile" 
                    scope="\\web.config$" 
                    match="/configuration/appSettings/add[@key='email']/@value" />
  </parameter>

  <parameter name="url" description="description">
    <parameterEntry kind="XmlFile" 
                    scope="\\web.config$" 
                    match="/configuration/appSettings/add[@key='url']/@value" />
  </parameter>

</parameters>

In the parameters.xml file I have defined two new MSDeploy parameters., email and url. This file should be placed in the root of the project directory and it will automatically be picked up by the web publish process. If you are familiar with this you may have noticed that I have left off the DefaultValue attribute here. More to come on that later. Now that we have our parameters defined let’s see what customizations need to be made to the publish profiles (.pubxml files).

You can override the values by populating the MsDeployDeclareParameters item list. Let’s see how to do that. When you create a publish profile in Visual Studio a .pubxml file is written to the folder Properties\PublishProfiles. These are MSBuild files and they are consumed during the build+publish operation. You can customize these files in order to fine tune the publish process. In my sample project I have two publish profiles created; siteone and sitetwo. Both of these are web profiles pointing to Azure Web Sites. In the publish profiles with the samples you will find two sets of elements; properties for publishing and  my parameter customizations. You can see the content of these profiles below, I’ve left off the MSDeploy settings for brevity. Those profiles are shown below.

siteone.pubxml

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <!-- Web deploy settings here -->  

  <ItemGroup>
    <MsDeployDeclareParameters Include="email">
      <DefaultValue>one@email.com</DefaultValue>
    </MsDeployDeclareParameters>
    <MsDeployDeclareParameters Include="url">
      <DefaultValue>http://one.example.com/</DefaultValue>
    </MsDeployDeclareParameters>
  </ItemGroup>
</Project>

sitetwo.pubxml

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- Web Deploy settings here -->

  <ItemGroup>
    <MsDeployDeclareParameters Include="email">
      <DefaultValue>two@email.com</DefaultValue>
    </MsDeployDeclareParameters>
    <MsDeployDeclareParameters Include="url">
      <DefaultValue>http://two.example.com/</DefaultValue>
    </MsDeployDeclareParameters>
  </ItemGroup>
</Project>

In these profiles you can see that I’ve  added a usage of MSDeployDeclareParameters for both parameters in parameters.xml. In each case the value for the Include attribute is the name of the parameter (matches the name attribute in parameters.xml). Along with that I’ve declared a value for the DefaultValue metadata. This will contain the value of the parameter when it is published using that profile.

After publishing siteone the values for the app settings are below.

When publishing with sitetwo the values

 

That’s it. Now let’s move on to the comment I made previously regarding the DefaultValue attribute that I left off of the parameters.xml file.

 

DefaultValue

When you create parameters and set their values there are a few different places that these can come from including; parameters.xml, auto generated from con strings and custom declared parameters in MSBuild. Because of this the Web Publishing Pipeline has a mechanism to prioritize parameters when there are duplicates. This is facilitated by a Priority metadata value on the MSDeployDeclareParameters item list. If you want to Declare a DefaultValue inside of the parameters.xml file you can do that, but you have to be aware of the impact of that. When you add a DefaultValue parameter in parameters.xml by default those values will take precedence over the items in MSDeployDeclareParameters. Because of that you’ll have to add a Priority value. The way the Priority works is that the item with the lowest priority value for a given parameter will win. The default priority value for params from parameters.xml is –50 (defined in Microsoft.Web.Publishing.targets). Because of that we have to add priority less than –50. For example.

<ItemGroup>
  <MsDeployDeclareParameters Include="email">
    <DefaultValue>two@email.com</DefaultValue>
    <Priority>-100</Priority>
  </MsDeployDeclareParameters>
  <MsDeployDeclareParameters Include="url">
    <DefaultValue>http://two.example.com/</DefaultValue>
    <Priority>-100</Priority>
  </MsDeployDeclareParameters>
</ItemGroup>

 

In this case when I publish these values will override the default value from the parameters.xml.

 

You can see the latest version of this at https://github.com/sayedihashimi/publish-samples/tree/master/AppSettingsPerProfile.

 

Sayed Ibrahim Hashimi | @SayedIHashimi | http://msbuldbook.com

Saturday, March 02, 2013 3:36:00 AM (GMT Standard Time, UTC+00:00)  #     |