Introduction
When I started to play with Telerik Rad controls under SharePoint, I realized that massive changes should be made manually to web application's web.config file. Therefore the DeploymentFeature
application was created. It presents the SharePoint feature, which applies all needed changes to the web application's web.config file. Moreover it installs needed DLLs to the GAC.
In general, this application can add any modifications to the web.config, by reading them from an external XML file, which has a structure similar to web.config. Moreover, since the modifications are located externally, they can be dynamically changed, without recompiling the application.
Examples of Use
An article SharePoint MVP with Telerik ORM can be considered as a good example of the employment of the application provided here.
Prerequisites
The usage of the solution implies the SharePoint 2007 existence, which means that the target OS is Win2003 or Win2008.
The source code project was created using SPVisualDev, which uses WSPBuilder for deployment. So you should download and install them from CodePlex, or deploy and activate SharePoint feature manually. (Those tools are really helpful for development and deployment of SharePoint projects).
Also, since the Telerik Rad controls were the target, the application implies that controls are installed and look for them at c:\Program Files\Telerik\RadControls for ASPNET AJAX Q1 2009\Bin35\. However it's not a problem if the controls aren't installed or installation path is different, since this information is stored in an external XML file and can be easily changed.
Using the Code
There are two classes in the solution:
Installer
- applies all needed changes and installs the DLLs into the GAC. Works in two modes Deploy
and UnDeploy
, which apply or remove changes respectively. FeatureEventReceiver
- traps the activation, deactivation, installation and uninstallation of SharePoint feature. When the feature is activated, it calls the Installer
in Deploy
mode and runs the Installer
in UnDeploy
mode for modifications removal.
FeatureEventReceiver
Look into FeatureActivated
method:
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
this.ReadDeploymentSettings(properties);
SPWebApplication webApplication = properties.Feature.Parent as SPWebApplication;
Installer installer = new Installer()
{
WebApplicationId = webApplication.Id,
Nodes = this.DeploymentNodes,
DllsToGac = this.DllsToGac
};
installer.Deploy(Installer.DeploymentType.Deploy);
}
This method calls ReadDeploymentSettings
in order to parse the XML file, which contains all the modifications. (The XML will be discussed right after this section.) The Installer
is generated and run in Deploy
mode.
The FeatureDeactivating
method makes the same things, only run the Installer
in UnDeploy
mode.
Installer
The main method of Installer
is Deploy
:
public void Deploy(DeploymentType deploymentType)
{
this.ModifyWebConfig(deploymentType);
this.ModifyGac(deploymentType);
}
Look into the ModifyWebConfig
method:
private void ModifyWebConfig(DeploymentType deploymentType)
{
Collection<SPWebConfigModification> webConfigModifications =
this.CreateWebConfigModifications();
SPWebApplication webApplication =
SPWebService.ContentService.WebApplications[this.WebApplicationId];
webApplication.WebConfigModifications.Clear();
foreach (SPWebConfigModification
webConfigModification in webConfigModifications)
{
if(deploymentType == DeploymentType.Deploy)
webApplication.WebConfigModifications.Add(
webConfigModification);
else
webApplication.WebConfigModifications.Remove(
webConfigModification);
}
webApplication.WebService.ApplyWebConfigModifications();
webApplication.Update();
}
It parses the web.config modifications using CreateWebConfigModifications
method, which will be examined right after. When the collection of SPWebConfigModification
s is created, all of them are applied, depending on the deployment type. The CreateWebConfigModifications
method parses the collection of XML nodes and creates the collection of SPWebConfigModification
s for every node.
private Collection<SPWebConfigModification> CreateWebConfigModifications()
{
Collection<SPWebConfigModification> webConfigModifications =
new Collection<SPWebConfigModification>();
foreach (XmlNode node in this.Nodes)
{
if (node.NodeType == XmlNodeType.Comment)
continue;
SPWebConfigModification webConfigModification =
new SPWebConfigModification();
webConfigModification.Name = node.Attributes["Name"].Value;
webConfigModification.Path = node.Attributes["Path"].Value;
webConfigModification.Sequence = 0;
webConfigModification.Type =
SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
webConfigModification.Value = node.InnerXml;
webConfigModifications.Add(webConfigModification);
}
return webConfigModifications;
}
Here is the ModifyGac
method:
private void ModifyGac(DeploymentType deploymentType)
{
foreach (string key in this.DllsToGac.Keys)
{
string assembly = this.DllsToGac[key] + key;
Publish p = new Publish();
if(deploymentType == DeploymentType.Deploy)
p.GacInstall(assembly);
else
p.GacRemove(assembly);
}
}
Web.Config Modifications
All modifications, which have to be done, can be divided for two independent groups, described by different help articles on the Telerik site.
- Extending your MOSS site with Microsoft ASP.NET AJAX 3.5 presents a bunch of modifications that should be made in order to allow AJAX 3.5 on SharePoint sites.
- Deploying RadControls for ASP.NET Ajax introduces changes, which should be done for allowing Rad Controls functionality:
- Deploying of the Telerik.Web.UI.dll and Telerik.Web.Design.dll into the GAC.
- Specifying that those control are safe for SharePoint using
SafeControl
tag.
<safecontrol safe="True" typename="*" namespace="Telerik.Web.UI"
assembly="Telerik.Web.UI, Version=2009.1.527.35,
Culture=neutral, PublicKeyToken=121fae78165ba3d4" />
<safecontrol safe="True" typename="*" namespace="Telerik.Web.Design"
assembly="Telerik.Web.UI, Version=2009.1.527.35,
Culture=neutral, PublicKeyToken=121fae78165ba3d4" />
- Registering
RadScriptManager
handler into httpHandlers
section.
<add validate="false" verb="*" type="Telerik.Web.UI.WebResource,
Telerik.Web.UI, Version=2009.1.527.35, Culture=neutral,
PublicKeyToken=121fae78165ba3d4"
path="Telerik.Web.UI.WebResource.axd" />
As it was mentioned earlier, web.config modifications are stored in an external file, which can be found at _layouts\WebConfigModification\DeploymentSettings\RadControlsWebConfigAdds.xml.
Let's look at the beginning of this file:
<WebConfigDeployments>
<DllToGac Name="Telerik.Web.UI.dll"
Folder="c:\Program Files\Telerik\RadControls for ASPNET AJAX Q1 2009\Bin35\" />
<DllToGac Name="Telerik.Web.Design.dll"
Folder="c:\Program Files\Telerik\RadControls for ASPNET AJAX Q1 2009\Bin35\" />
<Deployment Name="sectionGroup[@name='system.web.extensions']"
Path="configuration/configSections" Comment="1">
<sectionGroup name="system.web.extensions"
type="System.Web.Configuration.SystemWebExtensionsSectionGroup,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35">
<sectionGroup name="scripting"
type="System.Web.Configuration.ScriptingSectionGroup,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35">
<section name="scriptResourceHandler"
type="System.Web.Configuration.ScriptingScriptResourceHandlerSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices"
type="System.Web.Configuration.ScriptingWebServicesSectionGroup,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35">
<section name="jsonSerialization"
type="System.Web.Configuration.ScriptingJsonSerializationSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="Everywhere" />
<section name="profileService"
type="System.Web.Configuration.ScriptingProfileServiceSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication" />
<section name="authenticationService"
type="System.Web.Configuration.ScriptingAuthenticationServiceSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication" />
<section name="roleService"
type="System.Web.Configuration.ScriptingRoleServiceSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication" />
</sectionGroup>
</sectionGroup>
</sectionGroup>
</Deployment>
The WebConfigDeployments
is the root node. It can contain two types of nodes:
DllToGac
- describes the DLL, which should be installed into the GAC and path to this DLL. Has two attributes Name
and Folder
. Deployment
- contains inside the set of tags, which are going to be added/removed to/from web.config. Has two attributes: Name
, describes the unique name of the modification (see Name property of SPWebConfigModification for more details), and Path
, describes the XPath
expression that specifies the node, which is going to be modified.
Points of Interest
There were two points, which demanded additional effort from me.
Name Property of SPWebConfigModification
The Name
property is not only the unique name of the modification, but according to MSDN also "refers to an XPath
expression that uniquely identifies the node under the parent node." It took me some time to realize how to specify them, in each particular case. And one of them demanded special care.
dependentAssembly Tag of web.config
The dependentAssembly
tag of web.config requires a special format to be proceeded.
<Deployment Name="*[local-name()='dependentAssembly'][*/@name=
'System.Web.Extensions.Design'][*/@publicKeyToken='31bf3856ad364e35']"
Path="configuration/runtime/*[local-name()='assemblyBinding']" Comment="7.2">
<dependentAssembly>
<assemblyIdentity name="System.Web.Extensions.Design"
publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
</dependentAssembly>
</Deployment>
Pay attention to the format of Name
attribute. In many sources, it is said that there is no way to apply it. However, thanks to this blog, the problem was finally resolved.
Usage
After deployment of the application to the SharePoint, you will see the feature under "Central Administration > Application Management > Manage Web Application Features."
Choose the web application in the upper right corner and activate the feature. See the changes to the web application's web.config file.
History
- 16.09.2009 - Review of web.config modifications for Rad Controls is added
- 25.08.2009 - Initial post