Thursday, July 26, 2007

Web User Controls in Sharepoint

As a Sharepoint 2007 / WSS developer you sometimes need to achieve some sort of design constrained functionality which just cannot be solved by using web parts or anything else but user controls.

User controls are perfect because you can put them anywhere and not have to worry about sharepoint server controls and the like.

Let me guide you through the process of creating a simple "hello world" user control and then implementing it into your sharepoint site's home page.

1. Create a web project
For the sake of convenience, i strongly suggest that you create your web project in the following directory:
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\WebSite1\
(You can replace "WebSite1" with whatever you prefer to call the folder)

The reason for this is that you're gonna have to copy and paste your user controls from this directory to the CONTROLTEMPLATES directory at the following location:
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\CONTROLTEMPLATES



The two folders are geographically close, if you open up the layouts folder in windows explorer and enable your folder view, you will be able to see the CONTROLTEMPLATES folder a couple of folders up.
















2. Develop the User Control
I assume that you've created Web User Controls before and know what i'm talking about when i say "Develop the User Control".
I write all my code in C# and i use code-behind files.

I usually leave the Page_Load method blank and create a new one to the effect of
protected void RenderWhateverImDoing() ~ and put all my code in there. That way i have exact control of where in my user control the code gets executed because my .ascx file looks like this:
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="WhateverImDoing.ascx.cs" Inherits="WhateverImDoing" %>
<%RenderWhateverImDoing(); %>


So in your RenderWhateverImDoing() method, add the code: Response.Write("Hello Sharepoint World!"); or something similar and save all files.

3. Copy the User Control to the CONTROLTEMPLATES folder
After saving the files, go to the project folder in windows explorer and copy the WhateverImDoing.ascx file and the WhateverImDoing.ascx.cs files to the CONTROLTEMPLATES folder.

4. Register the control.
I assume you are familiar with the master page and layout page concepts and that you know how to create both and utilise them in the Sharepoint environment.

The beauty of this is that you can place your user control in either the master page or the layout page. Place it in the master page if you want your user-control to be available and active as part of the template or put it into a layout page if you wish to only make it available on one specific page. If you put it in a layout page you'll have to apply that layout to the page you want to affect in sharepoint via the "edit page settings" option in the "Actions" menu or via the "Manage content" section of sharepoint.

The control register page directive goes at the top of the page, just below all other page directives you already have. Note that page directives all start with "<%@".
Now go ahead and add the registration page directive for your new user control:
<%@ Register Src="~/_controltemplates/WhateverImDoing.ascx" TagName="WhateverImDoing" TagPrefix="MyControls" %>

5. Add the Server tag to the HTML
Now that you've registered the control, you need to reference it in the appropriate place by using it as a server control in HTML. Whatever HTML gets generated by your user control will replace your user control server tag at runtime. So in other words, wherever you put your Tag, thats where "Hello Sharepoint World!" will get inserted.

Your server tag will look like this:
<MyControls:WhateverImDoing id="WhateverImDoingControl" runat="server">


And thats it! There is one last step to this if you've added your user control to a page layout file and that is to go and apply the specified layout to the page you want to display the user control on. Other than that all you need to do is go and test by navigating to the page (any page that has the customised master page applied to it if you used it in a master page).

IMPORTANT NOTE:
Whenever you make changes to the code-behind of your user control, you need to "tap" the .ascx file. This entail modifying the .asxc page by either adding a space or making some other kind of negligible change to the file so that the modified date on the file changes. You need to do this in order to avoid caching problems in sharepoint. So when you've made code changes to your user control and the changes arent reflecting on the portal, it might just be that you forgot to "tap" the .ascx file and sharepoint is still showing you the old version.

-Fin

25 comments:

cephusj said...

Nice technique. I like this because a lot of time I like to add functionality in an easy and efficient way without going through the whole Web Part drama. Thanks!

Anonymous said...

Nice Post. But.. I have a question!Is that true that we don't have to sign and deploy the .dll containing the .ascx.cs to the GAC before being able to run the UC?
Just dragging and dropping the ascx and .ascx.cs to the controltemplate is enough? cause I've tried it without any success!
Thanks

Stark Botha said...

Yes, thats correct, no signing or DLL's required.
You must have been doing something wrong, try following the process step-by-step. It definately works.

Trial Blazer said...

thanks dear. I've been developing some components for our new client and being new to sharepoint it was really giving me problem.

Anonymous said...

I have followed the instruction. The Visual Studio is on a separate server called Server1 and MOSS2007 is on Server2. I created the project on Server1 and copied the folder including the \Bin folder to sever2 and follwed your instruction. This gives me error. How should the Page directive line read in your example?

Unknown said...

hello StarkBotha

While registering the control in master page or layout page...what will i mention for "SRC"........

< Register TagPrefix="mindfire" TagName="NetIQ" Src="?" >

please help me...........

Thanks,
Samarendra

Stark Botha said...

Src="~/_controltemplates/WhateverImDoing.ascx"

Remember, you have to copy your .asxc and ascx.cs files to the _CONTROLTEMPLATES folder.

Anonymous said...

We are using this technique for our site and it is working great. THe only problem is that my event log is filling up with the following items.

Load control template file /_controltemplates/SeeAlso.ascx failed: Could not load type 'Merrimack.UserControls.SeeAlso'

At first I thought it was because the .cs files were also in the controlstemplates directory so I removed them and restarted iis. No dice.

The controls work fine but the application event log is filling up.

Anonymous said...

I am trying to get this to work, but am having a problem with the user control not being found.
I assume the register control at the top of the page is the problem.

I used something like this, but said that there was an invalid character in the name.

Src="~/_controltemplates/WhateverImDoing.ascx"

Is it really that easy to just create the user control - copy to the templates directory and register on the webpage?

Any ideas on why this is specified wrong??

Thanks

Stark Botha said...

What is your exact error?

Anonymous said...

I have to go back to re-do it, but am busy on another project.

But it acted like it couldn't find the ascx control.

My first question is the SRC command correct - since I copied the ascx to the exact directory in this example.

I will get back to you later this week on the exact error

Anonymous said...

I have the exact error message - in sharepoint designer, I placed the following in the default.aspx page:

( I had to remove the normal tags - as it couldn't get into this post)

Register Src=""~/_controltemplates/UWDisplayPrograms.ascx" TagName="UWDisplayPrograms" TagPrefix="uc1"

Than in the table - placed this tag:
( I had to remove "<",etc the normal tags - as it couldn't get into this post)

uc1:UWDisplayPrograms id="UWDisplayPrograms1" runat="server"
uc1:UWDisplayPrograms


The error - "The control cannot be displayed because it tagprefix is not registered in this web form.

Hope that helps to see what I did wrong.

Thanks

Anonymous said...

I had an extra quote in the top register line - removed it, and when the page came up in Sharepoint - it was this error below:

An error occurred during the processing of /_controltemplates/UWDisplayPrograms.ascx. Could not load type 'uwtoolkitUserControls.UWDisplayPrograms'


Is there something I need to do to register this control into the sharepoint server/database??

Stark Botha said...

It sounds like you're using an external library in your user control. That .dll needs to be loaded into your bin folder.

I'm not exactly sure what the path details are because im not at the server but its something like c:\inetpub\wwwroot\wsssites\(portal name)

Portal name will be the name of your portal, usually associated with the port number your portal uses (like port 80 or 81). Just browse that folder to find the right one. Then in there you'll see the bin folder where your external .dll's need to go. That should sort it out for you.

Anonymous said...

Hello,

I was able to copy the dll and the source code shows that the user control does work - in that it retrieves the data, but it can't be seen on the aspx page.

I tried to put the control in different places on the form and still is does not appear.

No errors and the user control code does execute correctly.

Does it have to be placed in a webpart? should I create a webpart and select the user control??

any ideas..

thanks

Anonymous said...

Nice example thanks for doing this

yellowlabrat said...

Thank you very much for this concise tutorial!

Pritesh said...

Nice post But I have diffrent problem
I want to add custom control into dataformview Webpart of dispform.aspx using Sharepoint Designer

I have created custom web control and tried to include that control into dataformview web part.
I have installed successfully and working fine If I will kept in outside of dataformview webpart of dispform.aspx.
I registered custom control with @Register directive at the top of the page. When I try to keep in the body of the DataformView Webpart xslt gives me error like "Error: Reference to undeclared namespace prefix: 'UCD'" otherwise it is working fine.

Can you give me your expert comments on this problem?

Thanks,
Pritesh

Anonymous said...

Nice !!!!!!!!

Create Custom SharePoint WebParts, it is simple.
Try this too,
Custom SharePoint WebParts

Unknown said...

for those having issues with the user control loading because you have it in a .dll installed in the gac

replace your Inherits with the full name not just the namespace.objectname

eg
WebApplication1.UserControl1
to
WebApplication1.UserControl1, WebApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5

(you might have to get the PKT from the GAC by right clicking on it and viewing the properties)

Thanks,
R. Kozar

Akshaya Mashankar said...

hi
I have followed all the steps as mentioned.
however getting this error message"
The resource cannot be found.

Asmaa said...

nice, but when i tried ,it works in administrator mode and is not dispalyed in the published site but no error rasied ?

Ali Abbas said...

@Asmaa

Same Problem with me that its available for administrator but not shown or even render in published mode.

Solution:-

Master Page is not "Checked In". Make sure Master Page major version is published and approved other wise changes not available to users.

Rgds/Ali Abbas

Inheritx Solutions said...

really its nice and informative post with unique content so thanks for sharing such a useful information.


Asp.net Development | Sharepoint Development

Unknown said...

Hi,The technology in Web Design Cochin allows web designers to make fascinating and dynamic web sites. Thanks.....