Thursday, January 10, 2008

Adding a BindingRedirect to Web.Config Using SPWebConfigModification

Had a need to remap some DLLs developed for a SharePoint site to different versions of third party libraries (the DLLs had been compiled against other versions of the libraries).

Found that this can be achieved by adding Binding Redirect nodes to the web.config file of the SharePoint web application. Actually getting this to work, however, is not straightforward; the main cause for complexity is that the parent node in the config file (the assemblyBinding node) has it's own namespace. This requires careful Xpath in the SPWebConfigModification name and path values.

Here are the necessary values:

string path "configuration/runtime/*[namespace-uri()='urn:schemas-microsoft-com:asm.v1' and local-name()='assemblyBinding']";

string 
name = string.Format("*[namespace-uri()='urn:schemas-microsoft-com:asm.v1' and local-name()='dependentAssembly']/*[namespace-uri()='urn:schemas-microsoft-com:asm.v1' and local-name()='assemblyIdentity'][@name='{0}']/parent::*", LibraryName);

Use these in conjunction with the following code to create the necessary value to be inserted into the web config file:

string WebConfigElement @"<dependentAssembly>
        <assemblyIdentity name='{0}' publicKeyToken='{1}' culture='neutral' />
        <bindingRedirect oldVersion='{2}' newVersion='{3}' />
      </dependentAssembly>"
;
string 
webConfigValue = string.Format(WebConfigElement, LibraryPublicToken, LibraryName, OldVersion, NewVersion);

Where LibraryPublicToken, LibraryName, OldVersion and NewVersion are the string values to be inserted into the bindingRedirect node that will be added to the web.config.

Set the owner, sequence and type for the SPWebConfigModification, and apply to create the new config file entry:

SPWebConfigModification mod = new SPWebConfigModification(name, path);
mod.Value = webConfigValue;
mod.Owner = string.Format("SetAsposeVersions.{0}", LibraryName);
mod.Sequence = 0;
mod.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;

webApp.WebConfigModifications.Add(mod);
webApp.Update();
SPFarm.Local.Services.GetValue<SPWebService>().ApplyWebConfigModifications();

3 comments:

BlauweTulp said...

Today, you're my hero! This is exactly what I needed.I would never have figured this out myself...

Wez said...

Thank you very much for this information, you saved me a lot of time puzzling with XPath and namespaces in SPWebConfigModification.

Rikard said...

Brilliant, except that you've switched places with name and publictoken in the string.Format.

Thanks a bunch!