In this article I am going to show you how you can utilize the flexible nature of WSPBuilder, ASP.Net Web Applications and post build scripts in order to utilize WSPBuilder as your deployment project for your UI.
Solution Overview
SharePoint is a dynamically generated website that pulls information out of a database. It also utilizes files on the server and uses those files as templates or actionable files. The combination of these static files on the server and the information in the database creates the web page we see. This architecture is what allows us to create pages, add webparts, modify navigation, etc… all within the SharePoint site itself.So, when developing against SharePoint, we need to deploy files to this static place on the server and register the files in the database. This static place on the server is called the 12 hive. It is usually found at: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12. A lot of stuff goes on in the 12 hive. You have the templates for the website, images, themes, etc… You also have very special items called Features. Features allow us to deploy custom functions to SharePoint and then activate/deactivate them at our leisure.
WSPBuilder allows us to “mimic” the 12 hive, within a Visual Studio project. As long as you have the same 12 hive structure setup, it can create the SharePoint deployment file (i.e.: the wsp). You do not need WSPBuilder to create wsp files; you can do the same thing by building extra files in your solution called manifest.xml and ddf files. However, for rapid application development, it is easier to use a third party solution like WSPBuilder because it creates those extra deployment files for you.
While WSPBuilder is a great tool to help us build the deployment files, it is not a web application project in Visual Studio. Web application projects help us build code behind and designer files for our server side controls.
Thus, the ideal solution for building UI elements in SharePoint consists of:
- ASP.Net Web Application project to build the UI elements
- WSPBuilder project to create our deployable wsp file
The key to this solution is seperation of concerns. You should build all UI related functionality in the ASP.Net Web Application project. All SharePoint specific functionality (ex: features), should be built in the WSPBuilder project.
Create the WSPBuilder deployment project
- Create your project in Visual Studio (File – New – Project)
- Choose the WSPBuilder project. I am utilizing the one under c# for this example.
- Give it a good name. I am using DemoProject for this example.
- Make sure it creates a new solution when creating the project.
- Add a folder under the 12 folder called “Template”.
- Add a folder under the Template folder called “LAYOUTS”.
- Add a folder under the Template folder called “FEATURES”.
- Add a folder under the Template folder called “CONTROLTEMPLATES”.
- Add a folder under the project called “GAC”.
Create the UI project
As I mentioned in the beginning of this article, the point is to create our UI elements in an ASP.Net Web Application project. So, we need to create another project, in the same solution, so that we can develop our UI elements.- Create the UI project (File – Add – New Project)
- Choose the ASP.NET Web Application Template. I am utilizing the one under c# for this example.
- Give it a good name. I am using DemoProjectUI for this example.
- Delete the Default.aspx
- Sign the project (this is because we are going to deploy to the GAC)
- Go to the properties (right-click the project and choose properties).
- Go to the Signing tab.
- Choose “Sign the assembly”.
- Under the “Choose a strong name key file” – choose <New>
- Give it a strong name – I usually use the name of my project (for example: DemoProjectUI).
- Uncheck “Protect my key with a password”.
- Add in the post build commands
- Go to the properties (right-click the project and choose properties).
- Go to the Build Events tab.
- Add the following into the post build section:
xcopy "$(TargetPath)" "$(SolutionDir)DemoProject\GAC\" /Y /s
xcopy "$(ProjectDir)*.ascx" "$(SolutionDir)DemoProject\12\TEMPLATE\CONTROLTEMPLATES\" /s /Y /R
Create a Web Part
Our next step is to create a Web Part. As anyone who has developed in SharePoint before knows, Web Parts are complete code files. They are not the html with code behind files we are used to when developing in ASP.Net. Some people are fine with developing Web Parts completely programmatically. However, it is much easier to create UI elements when you have WYSIWYG editors, html and code behind.One way to get the normal ASP.Net web development experience, when developing Web Parts, is to use the SmartPart. The SmartPart is a very clever Web Part, developed by Jan Tielens, which can render .Net user controls in Web Parts. I really like the SmartPart, especially for people learning to build SharePoint Web Parts as user controls. However, I like more control over what I do and there are some limitations to the SmartPart. It is not my intent to go over those limitations in this article, but you can read them here: http://weblogs.asp.net/erobillard/archive/2008/03/04/what-to-know-about-smartpart-and-loadcontrol.aspx
In the end, you can accomplish the same thing as the SmartPart using the “LoadControl” method in .Net. Thus, this article will show how to create a Web Part, which will load the user control from our UI project.
- Create the Web Part using WSPBuilder
- Right-click on the DemoProject project
- Go to Add – New Item
- Choose WSPBuilder – Web Part Feature
- Give it a good name. For this example I am going to use DemoFeature
- A popup will come up with Title, Description and Scope. Since we are developing a Web Part, you must choose “Site” for the scope. This is because we need the Web Part to deploy to the Web Part gallery of our Site Collection.
- It created the feature in the features folder
- It created the Web Part code in a folder called WebPartCode - Modify the Web Part code to use “LoadControl”
- Open up the DemoFeature.cs file in the WebPartCode folder
- Remove the MyProperty property and attribute for now. This is just WSPBuilder showing you how you can use properties. We aren’t going to use them for this demo.
- Find the CreateChildControls method and find the comment that says “Your code here…”
- Remove the line under it.
- Replace it with this:
this.Controls.Add(Page.LoadControl("~/_controltemplates/DemoControl.ascx"));
protected override void CreateChildControls()
{
if (!_error)
{
try
{
base.CreateChildControls();
this.Controls.Add(Page.LoadControl("~/_controltemplates/DemoControl.ascx"));
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
- Add the control to the UI project
- Right-click on the DemoProjectUI project
- Go to Add – New Item
- Choose Web – Web User Control
- Give it a good name. For this example I am going to use DemoControl.ascx
Note: SharePoint can find any control in the ControlTemplates folder by using the _controltemplates path because of a mapping it creates in IIS. SharePoint maps the _controltemplates path to the servers 12 hive at 12/Template/ControlTemplates.
Utilizing the Code Behind
We now have our basic solution setup. We have our UI project and can build our user control there. We have our WSPBuilder deployment project that will create our SharePoint install file. But, we aren’t ready to deploy just yet. We still need to tell our user control how to talk to its code behind. Because we are utilizing the GAC for our assemblies, we need to put a fully qualified domain in our ascx file. There are a couple of techniques for figuring out this fully qualified domain. What I like to do is deploy the project and go to the GAC to get the properties.- Deploy the WSP, so that the assembly gets added to the GAC, so that we can pull out the assembly information.
- Right-click on the DemoProject project
- Click WSPBuilder – Build WSP (wait for it to finish)
- Right-click on the DemoProject project
- Click WSPBuilder – Deploy WSP (wait for it to finish)
- Get the assembly information from the GAC
- Usually found at C:\Windows\assembly
- Right-click on the DemoProjectUI assembly and click properties
- Note the public key token and version ( I suggest copying the public key token at this point because we are going to use this information in the next step).
- Add the assembly information to the ascx
- Go to the DemoControl.ascx file in the DemoProjectUI project
- Add an Assembly reference as the first line in this file. Below is an example. However, you cannot copy this example. Your assembly reference must have the correct information about your assembly (including your public key information).
<%@ Assembly Name="DemoProjectUI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=772ab5f02712b819"%>Now we are ready to test our solution!
Deploy the Solution
Now that we are finished setting everything up, we can deploy the solution. This is real easy with the use of WSPBuilder as long as we are developing on a SharePoint server.Note: Please make sure you have a web application and site collection setup in SharePoint before doing the following steps. When you deploy the WSP solution, it will deploy to all web applications on your development server. Thus, the web application must exist before you deploy.
- Right-click the DemoProject project
- Click WSPBuilder – Build WSP (wait for it to finish)
- Right-click on the DemoProject project
- Click WSPBuilder – Deploy WSP (wait for it to finish)
- Open up your SharePoint site. Note: if you go to the SharePoint site at this point and it says “Server Not Available”, then just keep refreshing the page until it shows up. The WSP install recycled the application pools because it needs to every time a dll in the GAC is added or modified. It sometimes takes a few seconds for this process to finish.
- Go to Site Actions – Site Settings
- Go to Site Collection Features
- Activate the DemoFeature
- Go back to the site
- Go to Site Actions – Edit Page
- Click “Add a Web Part” in one of your web zones
- Find your WebPart. It should be under “MyGroup” unless you changed the group name in your feature. The elements.xml file in the feature folder of the DemoProject lets you configure this information. I
- Add your Web Part to the page
- Go to the DemoProjectUI project
- Open the DemoControl.ascx
- Put a label tag on the control
- Go to the code behind (i.e.: DemoControl.ascx.cs)
- In the Page_Load type the following
protected void Page_Load(object sender, EventArgs e)
{
test.Text = "Hello World";
} - Right-click the DemoProject project
- Click WSPBuilder – Build WSP (wait for it to finish)
- Right-click on the DemoProject project
- Click WSPBuilder – Deploy WSP (wait for it to finish)
- Open your SharePoint site and see your Web Part. It should say “Hello World”.
<asp:Label runat="server" ID="test" />
Wow, that was a lot of setup just to create a user control that can render in a Web Part. But, the great thing is, you only have to do the setup once. As a SharePoint Architect, I set this up for my team and they can just concentrate on building the user controls. It runs very smooth!
Per popular demand, here is the demo solution from the walkthrough. I used Visual Studio 2008, WSPBuilder Extenstions 1.0.5 and .net 2.0 for this solution (I used 2.0 so it can work for a client of mine, it can be upgraded to 3.5 easily)
DemoProject
Hi,
ReplyDeleteThis is really a fantastic post..... thank u
But I have having a casing (multi-lingual appliaction) in which I have many user controls and all of them are accessing global resource files (in both ascx and cs files).
So, how can I manage these resource keys? Will I move for local resources but I have many keys which are sharing in different controls.
Also, there is a limitation I cannot copy resource files.
Any suggestion in this regard will really be appreciated.
Thanks Once again
~Ahmed