Recall that in Hour 5, in the discussion on the delegate controls, you had to register your custom sitemap provider by putting the following entry in the providers section of the web.config:
<add name="CustomSiteMapProvider"
siteMapFile="_layouts/DelegateControlDemo/custom.sitemap"
type="Microsoft.SharePoint.Navigation.SPXmlContentMapProvider,
Microsoft.SharePoint, Version=14.0.0.0,
Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
At that time you did this manually, and it might just work quite well in a development environment. But imagine in a production environment, where you have more than one WFEs (Web Front Ends), you would end up modifying manually web.config on the web front end. Fortunately the SPWebConfigModifications
class comes to the rescue.
The SPWebConfigModification
class helps you to define modifications to web.config that can then be applied by calling the ApplyWebConfigModifications
method on the current content web service object. To demonstrate the use of the SPWebConfigModification
class and the ApplyWebConfigModifications
let’s create a web application scoped feature that on activation adds the previous custom sitemap provider into the web application’s web.config and on deactivation, removes the previous entry.
The following code segment illustrates this process. As shown, we create the SPWebConfigModification
class’s object, get a reference to the current content web service, and apply the modifications to the same by calling the ApplyWebConfigModifications method:
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPWebApplication webApp = properties.Feature.Parent as SPWebApplication;
SPWebService webService = webApp.WebService;
// Create new modification
SPWebConfigModification myModification = new SPWebConfigModification();
myModification.Path = "configuration/system.web/siteMap/providers";
myModification.Name = "add[@name='CustomSiteMapProvider'][@siteMapFile="+
"'_layouts/DelegateControlDemo/custom.sitemap'] "+
" [@type='Microsoft.SharePoint.Navigation.SPXmlContentMapProvider, "+
"Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, "+
"PublicKeyToken=71e9bce111e9429c']";
myModification.Sequence = 0;
myModification.Owner = properties.Feature.DefinitionId.ToString();
myModification.Type = SPWebConfigModification.SPWebConfigModificationType. EnsureChildNode;
myModification.Value = "<add name='CustomSiteMapProvider'"+
"siteMapFile='_layouts/DelegateControlDemo/custom.sitemap'"+
"type='Microsoft.SharePoint.Navigation.SPXmlContentMapProvider,"+
"Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, "+
"PublicKeyToken=71e9bce111e9429c' />";
// Add the modification and save the changes
webService.WebConfigModifications.Add(myModification);
webService.Update();
webService.ApplyWebConfigModifications();
}
We track the modification, by assigning our feature’s definition id as the owner of the modification. On feature deactivation, we loop through all the modification objects and get the one modified by our feature. Finally we call the ApplyWebConfigModifications
method to save the changes, as demonstrated in the following code sample:
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
SPWebConfigModification modificationFound = null;
SPWebApplication webApp = properties.Feature.Parent as SPWebApplication;
SPWebService webService = webApp.WebService;
Collection<SPWebConfigModification>
modificationCollection =
webService.WebConfigModifications;
// Find the modification by owner
foreach (SPWebConfigModification modification in modificationCollection)
{
if (modification.Owner == properties.Feature.DefinitionId.ToString())
{
modificationFound = modification;
break;
}
}
// Remove the modification and save the changes
webService.WebConfigModifications.Remove(modificationFound);
webService.Update();
webService.ApplyWebConfigModifications();
}
When deploying your web application scoped feature through Visual Studio, it is better to set the Activate on Default property to false to prevent the feature from being activated for all the web applications. Otherwise, the feature would get activated on all the web applications and modify each web application’s web.config file.
Further, note that the modifications done using the preceding methodology are persisted in the configuration database, and on call to the SPWebService.ApplyWebConfigModifications
these changes become effective. For example, the owner related information that we are using in the preceding example to track the modifications by owner will not be present in the web.config itself and would be maintained in the configuration database. Due to this reason, manual modifications to the web.config should be avoided as these will not be persisted in the configuration database and application of a Service Pack might actually wipe these out.