Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

SharePoint Feature to Extend SharePoint Site with AJAX 3.5 and Telerik Rad Controls

4.67/5 (2 votes)
21 Sep 2009CPOL4 min read 59K   301  
This article explains how to create SharePoint feature to extend SharePoint site with AJAX 3.5 and Telerik Rad Controls.

This article appears in the Third Party Products and Tools section. Articles in this section are for the members only and must not be used to promote or advertise products in any way, shape or form. Please report any spam or advertising.

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:

C#
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:

C#
public void Deploy(DeploymentType deploymentType)
{
	this.ModifyWebConfig(deploymentType);

	this.ModifyGac(deploymentType);
}

Look into the ModifyWebConfig method:

C#
private void ModifyWebConfig(DeploymentType deploymentType)
{
	Collection<SPWebConfigModification> webConfigModifications = 
             this.CreateWebConfigModifications();

	SPWebApplication webApplication = 
             SPWebService.ContentService.WebApplications[this.WebApplicationId];

	// Clears the SPWebConfigModification collection,
         // in order to prevent applying of earlier entered modifications.
	webApplication.WebConfigModifications.Clear();

	foreach (SPWebConfigModification 
			webConfigModification in webConfigModifications)
	{
		if(deploymentType == DeploymentType.Deploy)
			webApplication.WebConfigModifications.Add(
                               webConfigModification);
		else
			webApplication.WebConfigModifications.Remove(
                               webConfigModification);
	}

	// Applies all modifications to web.config.
	webApplication.WebService.ApplyWebConfigModifications();
	webApplication.Update();
}

It parses the web.config modifications using CreateWebConfigModifications method, which will be examined right after. When the collection of SPWebConfigModifications 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 SPWebConfigModifications for every node.

C#
private Collection<SPWebConfigModification> CreateWebConfigModifications()
{
	Collection<SPWebConfigModification> webConfigModifications =
             new Collection<SPWebConfigModification>();

	foreach (XmlNode node in this.Nodes)
	{
		// Throws out comments.
		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:

C#
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:
    1. Deploying of the Telerik.Web.UI.dll and Telerik.Web.Design.dll into the GAC.
    2. Specifying that those control are safe for SharePoint using SafeControl tag.
      XML
      <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" />
    3. Registering RadScriptManager handler into httpHandlers section.
      XML
      <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:

XML
<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.

XML
<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."

DeploymentFeature.GIF

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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)