Tuesday, August 12, 2008

Constructing Pages with User Controls in SharePoint

In my previous post I discussed how one can create "Custom Controls" in SharePoint. However, Custom Control have certain limitations. Custom Controls limits developer to build rich web UI quickly also, for any minute UI change, code needs to re-compiled and new dll needs to be deployed. This is where User Controls come in.

User controls provide a more productive alternative to custom controls. They are easier to develop as, they are deployed on the front-end Web server as simple text files with an .ascx extension. The ASP.NET runtime provides the functionality to parse these .ascx files at run time and compile them into assembly DLLs just as it does for .aspx files.

[Click on image to zoom in]

12 hive = "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12"

WSS provides a virtual directory for deploying user controls. Inside the "12 hive"/TEMPLATE directory resides a nested directory named CONTROLTEMPLATES. This directory contains many different user controls that are deployed as part of the standard WSS installation.

The CONTROLTEMPLATES directory is also a place where you should deploy custom user control files. However, it’s a good practice to create your own nested directory inside the CONTROLTEMPLATES directory to avoid potential file name conflicts. The CustomSitePages project creates a company-specific inner directory named Litware and copies its user controls into that directory. Each custom user control is copied to a physical path that looks like the following:


Each Web application is configured with a virtual directory named _controltemplates that points to the physical CONTROLTEMPLATES directory. This makes it possible to reference any user control file by using a standard path relative to the hosting Web application. For example, one of the user controls from the CustomSitePages project can be referenced by using a virtual path that looks like the following:

Just like custom controls, we need to follow same rule with respect to safe mode processing. i.e. we need to make entry in safe controls of sharepoint site's web.config as shown in my previous post:


Assembly="CustomSitePages, ...,public token"

Now the sharepoint documentation say's that, we need not worry about adding an entry to safe control list in site's web.config as, web.config file contains a generic entry specific to custom controls. Following is the entry:


Also, But this does not seem to work in my scenario. I had to add specific Assembly (safe control) entry in site's web.config.

Another wierd observation I made in case of user control is that, WSS documentation says, we simply need to add DLL file in site's bin directory, but am afraid this did not behave in my scenario either.

To place a background picture, I was working on a POC to generate UI based on XML file which resides in SharePoint document library. Now, that UI was ment to be dynamically generated in a User control, as this would ease the development effort.
When I paced DLL's (user control specific) in to bin directory, SharePoint flashed following error message in the screen:

Error: Request for the permission of type 'Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c' failed.

Then, I thought why not, put the dll's in c:\windows\assembly (GAC) and run it from there, doing so did not work as well. SharePoint flashed following error message:
Error: Could not load type 'NameSpace.ClassName'

After long struggle I found following solution :

1. Add assembly entry in safe control list in web.config

2. Add assembly in bin directory

3. Add assembly in GAC

This resolved the problem and things worked as they should. :)



Anonymous said...

The link in "how one can create "Custom Controls" in SharePoint" is not working.

Anonymous said...

I used the same method it does nt work for me .Can you put some sample code

Anonymous said...

I have a user control. It works for me as an adminstrator but it does not work for non-administrators.

I have added to in the GAC, etc.

What else is wrong?

Sandeep said...

This depends on the functionality that is implemented in that user control. Maybe your code is required to run with role having high privileges. Try using SPSecurity.RunWithElevatedPrivileges. If this is priveleges issue, this should take care of that. Also check if appropriate entry is made in safe controls list.