Click here to Skip to main content
Click here to Skip to main content

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

By , 21 Sep 2009
Rate this:
Please Sign up or sign in to vote.

Editorial Note

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:

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];

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

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:

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

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)

About the Author

Michael Raizman
Software Developer (Senior) CPP Investment Board
Canada Canada
No Biography provided

Comments and Discussions

 
GeneralError in logic to apply web.config modifications PinmemberGPetrites11-Aug-10 9:49 
There is actually a pretty serious error in the ModifyWebConfig method.
 
Before you apply the modifications, you have:
 
	// Clears the SPWebConfigModification collection,
        // in order to prevent applying of earlier entered modifications.
	webApplication.WebConfigModifications.Clear();
 
This logic will remove all modifications made to the web.config by any feature...not just this feature.
 
What we really want to do is set the Owner property on each SPWebModiciation while Deploying. When we want to remove, we should loop through the existing SPWebModifications and only Remove the ones whose Owner property indicates that we added them.
GeneralRe: Error in logic to apply web.config modifications PinmemberMichael Raizman12-Aug-10 5:40 
GeneralRe: Error in logic to apply web.config modifications PinmemberGPetrites12-Aug-10 6:37 
Generalsharepoint module problem Pin Pinmembersaiprakashsai19-Apr-10 20:43 
QuestionHow to deploy this to sharepoint using Visual Studio 2008 Pinmemberrhap4boy26-Mar-10 19:41 
AnswerRe: How to deploy this to sharepoint using Visual Studio 2008 PinmemberMichael Raizman29-Mar-10 5:24 
GeneralNice Pinmemberwildcatfan21-Jan-10 13:01 
GeneralSharePoint Features it is easy Pinmemberitsaranga29-Sep-09 1:22 
General[Message Deleted] Pinmemberitsaranga28-Sep-09 3:03 
GeneralRe: Simple Solution PinmemberMichael Raizman28-Sep-09 3:19 
GeneralGreat Solution PinmemberWimmo21-Sep-09 21:36 
GeneralRe: Great Solution PinmemberMichael Raizman22-Sep-09 2:53 
GeneralNice Solution PinmemberMAHESHSETHI26-Aug-09 10:14 
GeneralRe: Nice Solution PinmemberMichael Raizman26-Aug-09 11:14 
GeneralRe: Nice Solution PinmemberMAHESHSETHI27-Aug-09 3:36 
GeneralRe: Nice Solution PinmemberMichael Raizman27-Aug-09 4:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140415.2 | Last Updated 21 Sep 2009
Article Copyright 2009 by Michael Raizman
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid