Brent Arias
Brent Arias

Reputation: 30195

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?

Upvotes: 7

Views: 3590

Answers (3)

LifeintheGrid
LifeintheGrid

Reputation: 31

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>  

Upvotes: 3

MCattle
MCattle

Reputation: 3167

@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>

Upvotes: 7

Thommy
Thommy

Reputation: 91

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>

Upvotes: 9

Related Questions