Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web.config transforms - the missing manual

You can read web.config transforms documentation here and there, but there are two white-elephants that nobody seems to discuss:

  1. How do you perform a variable substitution in a Condition or XPath transform, and...
  2. Can a Locator be meaningfully nested inside a Transform?

Let me give an example that would benefit from either of those options. Suppose I have this:

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
      <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
    </dependentAssembly>
    <dependentAssembly>
      <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
      <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
    </dependentAssembly>
  </assemblyBinding>
</runtime>

Suppose I want to completely erase the dependentAssembly node, and its children, that matches the xpath //runtime/assemblyBinding/dependentAssembly[assemblyIdentity@name='System.Web.Mvc']. To do that, I might want something like this:

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity 
          name="System.Web.Mvc" 
          xdt:Remove 
          xdt:Locator="Condition(..[*@name=$name])" 
      />
    </dependentAssembly>
  </assemblyBinding>
</runtime>

Well obviously I made up the syntax @name=$name based on xpath variable concepts, but this example demonstrates why I'd want that feature. Is this supported? How must I adjust my syntax to take advantage of this? I could put in a string literal, but I just want to know if this is possible.

Another way I might try to delete the dependentAssembly node, is with this:

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1" xdt:Transform="Remove">
    <dependentAssembly>
      <assemblyIdentity name="System.Web.Mvc" xdt:Locator="Match(name)" />
    </dependentAssembly>
  </assemblyBinding>
</runtime>

Notice the Transform is on a grand-parent node, and the locator is on leaf node. Is the above legitimate? The idea is to remove only the dependantAssembly node that has an internal Locator Match.

These two approaches aside, how would you go about deleting the targeting dependantAssembly and all its child nodes?

like image 830
Brent Arias Avatar asked Oct 09 '12 03:10

Brent Arias


People also ask

How does web config transform work?

A Web. config transformation file contains XML markup that specifies how to change the Web. config file when it is deployed. You can specify different changes for specific build configurations and for specific publish profiles.

How do I create a new transformation in web config?

If you have a web application project, Right-click on web. config and choose Add Config Transform. This will add any config transforms that are missing from your project based on build configurations (i.e. if you have Production and Staging build configs, both will get a transform added).


3 Answers

The problem is the namespace attribute on the assemblyBinding tag.

Removing the AspNetHelper reference works for me with this:

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly xdt:Transform="Remove" 
                           xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='Microsoft.VisualStudio.Enterprise.AspNetHelper')">
        </dependentAssembly>
    </assemblyBinding>
</runtime>
like image 84
Thommy Avatar answered Oct 12 '22 01:10

Thommy


@Thommy's solution worked for me, and @LifeintheGrid's solution used the actual assemblies I wanted to remove, so I combined the two and simplified to get:

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly xdt:Transform="RemoveAll"
                           xdt:Locator="Condition(starts-with(./_defaultNamespace:assemblyIdentity/@name,'Microsoft.VisualStudio.QualityTools'))">
        </dependentAssembly>
    </assemblyBinding>
</runtime>
like image 41
MCattle Avatar answered Oct 12 '22 01:10

MCattle


This code ended up working for me. I moved the transform to the dependentAssembly node.

<runtime>
  <assemblyBinding>
    <!-- ending /dependentAssembly is required or tranforms fail -->
    <dependentAssembly xdt:Transform="Remove" xdt:Locator="Condition(assemblyIdentity/@name='Microsoft.VisualStudio.QualityTools.HostAdapters.ASPNETAdapter')"  ></dependentAssembly>
    <dependentAssembly xdt:Transform="Remove" xdt:Locator="Condition(assemblyIdentity/@name='Microsoft.VisualStudio.QualityTools.Common')"  ></dependentAssembly>
    <dependentAssembly xdt:Transform="Remove" xdt:Locator="Condition(assemblyIdentity/@name='Microsoft.VisualStudio.QualityTools.ExecutionCommon')"></dependentAssembly>
    <dependentAssembly xdt:Transform="Remove" xdt:Locator="Condition(assemblyIdentity/@name='Microsoft.VisualStudio.QualityTools.Resource')"  ></dependentAssembly>
  </assemblyBinding>
</runtime>  
like image 32
LifeintheGrid Avatar answered Oct 12 '22 01:10

LifeintheGrid