Writing Custom Webparts for Sharepoint 2007

Posted on 7/31/2006 @ 6:38 AM in #SharePoint by | Feedback | 76573 views

As I have already indicated, and as Scott Guthrie also pointed out, Sharepoint 2007 is built upon ASP.NET 2.0. Well, so a Sharepoint 2007 WebPart is a decendant of an ASP.NET 2.0 WebPart, i.e. Your custom WebPart, inherits from Sharepoint WebPart, which inherits from an ASP.NET 2.0 WebPart.

Now, as already indicated by my good friend, Andrew Connell, it is highly recommended that you should write an ASP.NET 2.0 WebPart instead of one that inherits from the Sharepoint WebPart. As Andrew mentioned on his blog, it appropriate to build Web Parts derived from the SharePoint class only when you need -

Cross page connections
Connections between Web Parts that are outside of a Web Part zone
Client-side connections (Web Part Page Services Component)
Data caching infrastructure


So in this blogpost, we will see how to write the simplest possible Sharepoint 2007 WebPart and deploy it. Just for fun, we will inherit from the sharepoint webpart instead of the asp.net webpart.

Begin by creating a class library project, add references to System.Web, Microsoft.Sharepoint.dll (again only because this blogpost talks about Sharepoint Webpart).

Then add a class as below, which as you can tell is a hella simple WebPart.

using System;

using System.Collections.Generic;

using System.Text;

using System.Xml.Serialization;

using System.Web;

using System.Web.Security;

using System.Security;

using System.Security.Permissions;

 

using Microsoft.SharePoint;

using Microsoft.SharePoint.Security;

using Microsoft.SharePoint.WebPartPages;

 

namespace Sahil.Sharepoint.WebPartPages

{

    [System.Xml.Serialization.XmlRoot(Namespace = "http://blah.winsmarts.com/demospace")]
   
public class CustomWebPart : WebPart

    {

        private string toDisplayText = "Default Text";

        [WebPartStorage(Storage.Shared), System.Xml.Serialization.XmlElement(Namespace = "http://blah.winsmarts.com/demospace")]
        public string ToDisplayText
        {
            get { return toDisplayText; }
            set { toDisplayText = value; }
        } 

        protected override void RenderWebPart(System.Web.UI.HtmlTextWriter writer)

        {

            writer.Write(toDisplayText) ;

            base.Render(writer);

        }

    }

}

Great !! Now, strongly name it, Build the dll, and use sn-t or reflector to find the public key token. 

Then follow the following steps -

1. Locate the Sharepoint WebSite you wish to deploy this webpart in. This can be done via the IIS Manager under administrative tools. The default ones would be virtual directories that look like GUIDs under C:\INETPUB\WWROOT\WSS\<<GUID>>. In my case (yours may be different) the dir was - C:\Inetpub\wwwroot\wss\VirtualDirectories\7ee252c4-9e98-4258-a6ae-77e16a287bea\bin

2. Drop the dll in the bin directory in the virtual dir.

Important: By dropping the webpart in the bin directory, you are effectively giving it partial trust. If you were writing a plain vanilla ASP.NET 2.0 WebPart, you would need to decorate the Webpart with the AllowPartialTrustedCallersAttribute @ the assembly level. You could also create a new trust policy for your WebPart (recommended), or raise the trust level in the web.config file (default is WSS_Minimal), or you could just drop the Webpart in the GAC; which again requires strong naming.

3. Under the same virtual directory, find the web.config, and add the following to the SafeControls section -

<SafeControl Assembly="Sahil.Sharepoint.WebPartPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=84da1d46719d7853" Namespace="Sahil.Sharepoint.WebPartPages" TypeName="*" Safe="True" AllowRemoteDesigner="True" />

4. Then browse to the WebSite, and go to Site Actions -> Site Settings -> Modify All Site Settings. Under that, click on "Web Parts" under Galleries.

5. Click on "New" in the toolbar, and find the Sahil.Sharepoint.WebPartPages.CustomWebPart as shown below -

6. Check the checkbox, go to the top, click on "Populate Gallery".

That's it. Your WebPart is now ready to eat !! :)

How to use it?

Go to the site of your choice, Edit Page, Click on Add a WebPart, you should see it in the list that pops up.

Add the WebPart, and under Miscellaneos, go ahead and modify the text it shows, and VOILLA (See below) -

Purty nice eh? :).

But as you may have guessed, this is a hella simplistic webpart. In future blogposts we will see more complicated Sharepoint 2007 WebParts that use advanced features such as Custom Editors, Custom Views, and Connections to other WebParts.

Stay Tuned .. :-)

 

Sound off but keep it civil:

Older comments..


On 7/20/2006 9:35:41 AM Jason said ..
Just a quick note..."base.Render(writer);"


Shouldn't that be "base.RenderWebPart(writer);"?

Jason


On 7/20/2006 10:07:10 PM Sahil Malik said ..
Jason -

Render is simpler, which is why I used that instead. With RenderWebPart you have to check for additional stuff, such as if the webpart is minimized or not. Anyway - good point.

Sahil Malik


On 7/30/2006 5:19:26 AM David said ..
How do I load a user control written in ASP.NET 2.0 for WSS 3.0


I have an existing user control that I wrote in ASP.NET 1.1 and created a class and used the loadcontrol method but when i try to load the control based on the class name it can't find the class because I am assuming it is a partial class now and I am not sure how I make the class load my user control with control = (MyUserControl) Page.LoadControl("MyUserControl.ascx")


On 7/30/2006 8:02:20 PM Sahil Malik said ..
Whoaa David - that doesn't sound like a clean approach to begin with.


On 8/14/2006 9:32:57 AM bachir ben said ..
i need to write a simple webpart that contains a button and an event handler for this button , this web part should be deployed on sahrepoint 2007. i have read all your articles and think i know how to deploy it if only i can write this webpart so any suggestions please


On 8/19/2006 10:26:06 AM Christopher Simmons said ..
bachir, first you would need to render those controls, then create a delegate to an onclick event for the button, create a subroutine to handle logic for the delegate.


On 8/29/2006 4:08:15 AM Kooki said ..
Hi, is there any template for VS 2005 to create webparts as it was for VS2003 for sharepoint 2003. I would be very grateful if someone provide the answer in detail. Thanks


On 8/29/2006 2:16:39 PM Sahil Malik said ..
Kooki - AFAIK there is no such template, though creating such template shouldn't be hard. In fact, the concepts are so much like creating server controls that you don't really need a template.


On 8/31/2006 6:32:13 AM Mark Arend said ..
Sahil, did you have any problems getting the property to appear in the Modify Shared Web Part pane? I have not gotten my text property to appear in Miscellaneous or Appearance, as I was used to doing in SPS 2003.


On 8/31/2006 7:23:27 PM Sahil Malik said ..
Mark - I was using Sharepoint 2007, and no I had no issues having my property appear editable. Did you use the WebBrowsable(true) attribute?


On 9/5/2006 1:29:54 PM anabhra said ..
Never mind . i found them....


On 9/8/2006 9:42:57 AM anabhra said ..
Hi Sahil,

I am trying to build a custom web part that queries the pages collection of the current web in MOSS 12. I want to read the values in the fields that user has entered on the page.

So in my page layout this how I have defined/declared a control:


<SharePointWebControls:TextField FieldName="Location" runat="server" id="txtLocation"></SharePointWebControls:TextField>

Dim tf as textField


tf=Ctype(page.ListItems("Location"),TextField)

I now want to read the value as - tf.Text

This does not work. What am I doing wrong? Any ideas?

thanks,


anabhra


On 10/26/2006 8:14:13 AM John said ..
I noticed in an earlier that you had said that loading a UserControl was not very "clean". I was curious to hear your opinion on that subject. That is a technique that I have used quite often with great success when developing custom SharePoint solutions. Other than the fact that the control needs to be deployed with the assemblies, what don't you like about that scenario. I'm interested in you opinion.


On 10/26/2006 10:40:00 AM Sahil Malik said ..
John - it is the more difficult deployment that makes it unclean. Thats about it.


On 11/20/2006 9:59:03 AM Dave B said ..
Do you have any article or sample of a connectionable web part? Seems this is not well covered anywhere.


On 11/20/2006 11:56:42 AM Sahil Malik said ..
Dave -

Yes I have blogged about it numerous times. I have an article coming up in next month's code magazine issue on this as well. Just search for my name and connecting webparts - you should find it.

Sahil


On 11/20/2006 12:56:40 PM Dave B said ..
Sahil:

Have a custom web part that I am trying to connect to the Text Filter. But I have not been able to find the correct interface. This is WSS 2007.

Dave


On 11/20/2006 1:28:19 PM Sahil Malik said ..
Dave - You can define your own interface. Please read the articles I have written on this topic.


On 11/22/2006 10:53:00 PM deepak said ..
Hi sahil,


i need to add some data to an excel which is in a web part from another web part.


Can we do that? Please let me know if possible.


Thanks & Regards,


Deepak.


On 12/14/2006 5:16:53 AM Simon Thompson said ..
Wow this is hard work. Can you point me in the right direction please?


I am trying to write a web part for MOSS 2007, which will show the results of a stored procedure (SQL 2005). The results are images.

The stored procedure has a single parameter - EMPID, which is the employee ID, the employee table links to an images table (There are many related images for each employee) so i just want to be able to enter the EMPID (either by passing it from another webpart or entering it into the web part properties when i add the webpart to the page) and the webpart show all related images.

Thank you for your time.

Simon


On 12/14/2006 7:14:55 AM Sahil Malik said ..
Simon -

What is the specific issue you are getting stuck at? Were you able to do the above in a plain vanilla server control on an aspx page?

Sahil


On 12/14/2006 7:27:48 PM A.K said ..
Hi Sahil,

I am stuck up on a issue. Please let me know whether I can display a drop down box in the property pane of a Custom Webpart. I have created a Custom web part. The text to be displayed in the webpart has to be selected from a drop down list in property pane. This list will be dynamic,i.e., the contents will be populated from the site collection itself.

Any help will greatly appreciated


On 12/19/2006 4:56:34 AM isha jain said ..
i have made one user control for date control in asp.net 2005 and copy that from website to webpart where i want that ,in my user control i have one button textbox and calendar control ,i want on click of the button the calendar is made visible and whatever the date is selected by the user from the calendar control is selected in the textbox,so my problem is i m not able to handle the click event in the web part and i m not getting the desired oresult in my webpart so plz can u help me out


On 12/20/2006 2:50:05 PM Bob said ..
Nice article, Do you happen to have a VB.NET version else I can create one based on your example. My Question is: Do you see any problems doing this in VB.NET? My past experience with ASPX, ASMX, and ASCX with C# Codebehinds says NO, as I have inherited from each interchangably. But Sharepoint is a new playing field for me, and I see you are using C#, what do you think of VB.NET instead?


On 12/21/2006 11:10:47 AM Sahil Malik said ..
Bob -

There should be no problems doing this in VB.NET.

Sahil


On 12/22/2006 10:44:53 AM Bob said ..
OK, Problem solved: Resolution was I created an Empty VB Project and add items manually. VB-Webparts are now possible for me, objective achieved!


On 2/5/2007 9:05:14 AM Mason said ..
First of all, your help has been great and I can create my own webparts for MOSS 2007. However, I am having a problem getting my click events to work right. Any help would be appreciated:

<DefaultProperty("Text"), ToolboxData("<{0}:Test runat=server></{0}:WebCustomControl1>")> _


Public Class Test


Inherits WebPart


Dim lbl As New Label


Dim btn As New Button

<Bindable(True), Category("Appearance"), DefaultValue(""), Localizable(True)> Protected Overrides Sub CreateChildControls()


MyBase.CreateChildControls()


lbl.Text = "Hello Again"


lbl.ID = "Testlbl"


btn.Text = "Click Me"


btn.ID = "Testbtn"


AddHandler btn.Click, AddressOf btn_Click


Controls.Add(lbl)


Controls.Add(btn)


End Sub

Protected Sub btn_Click(ByVal s As Object, ByVal e As EventArgs)


lbl.Text = "Goodbye"


End Sub

Protected Overrides Sub RenderContents(ByVal output As HtmlTextWriter)


CreateChildControls()


lbl.RenderControl(output)


btn.RenderControl(output)


End Sub


End Class

Thanks!


On 2/20/2007 8:45:43 AM Aron said ..
Help me with System.Xml.Serialization.XmlRoot Namespace.


What is this namespace could be.


On 3/5/2007 7:22:45 AM JC said ..
hey, my webparts keeps on adding on the page whenever I refresh.. any ideas on whats causing this problem


On 3/12/2007 12:13:52 PM kumar said ..
I have followed the above instructions, created the dll and dropped it in GAC and edited the web.config file with the new safecontrol tag. But my problem is that i do not see that in the "New" web part list. I do not know what I am doing wrong. I am using WOSS.


On 3/19/2007 9:37:31 AM Dimi said ..
I'm new to SharePoint and Webparts, but I managed fine with this example. I can create the webpart and add it to the gallery... but when I try to add it on a page I get a "Unexpected error". It doesn't say anyting more... any suggestions ?


On 3/26/2007 12:53:57 PM utpal said ..
Sahil,

I am new in SharePoint. I am trying to write a usercontrol which will retrive lists data


and display. Any code example? I will appreciate your help.

Thanks,

Utpal


On 5/1/2007 11:29:22 AM Chris said ..
I personally prefer to load user control in the web part for better UI control. The web part is already done for SPS 2003. Besides recompiling it for .NET 2.0 and redeploy it to MOSS 2007, is there anything I have to do to make it work? Is there any difference from SPS 2003 in terms of web part deployment?


On 5/16/2007 12:34:34 PM sharepointdev said ..
I've gotten steps 1-6 working perfectly. However, when I try to use this trivial web part, the server just hangs.

DW20.exe hogs the CPU and I must kill it to continue using the computer. I've restarted the server and tried dozens of little changes, but I can't get this to work. This is extremely frustrating. Any help would be greatly appreciated.


On 5/30/2007 6:48:30 AM Koena said ..
I have successfully created a Webpart with controls like label, Textbox, and buttons. I was able to deploy the webpart as well. My problem is I am not able to handle the Click_Event of the Button. Please Help.


On 6/12/2007 2:26:14 AM LillaJag said ..
Koena, to get a simple button and eventhandler for it just use something like this:

...


HtmlButton fetchUsersButton;


...


protected override void CreateChildControls()


{


...


fetchUsersButton = new HtmlButton();


fetchUsersButton.ID = "fetchUsersButton";


fetchUsersButton.Visible = true;


fetchUsersButton.InnerHtml = "click here";


fetchUsersButton.ServerClick += new System.EventHandler(this.fetchUsersButton_click);


Controls.Add(fetchUsersButton);


...


}


...


public void fetchUsersButton_click(object sender, EventArgs e)


{


//button pressed, do something here.


}


...


On 6/13/2007 10:29:33 PM Bis said ..
The article looks very helpful.


I needto create a webpart which should looks like a matrix and each cell in matrix should be filled with some folder link.


Am really confused how can i do this webpart.


Any suggestion please?


Bis


On 6/25/2007 11:31:42 AM Kieran Toon said ..
Hello Sahil,


I've created a few simple webparts and they work fine. I have now created a customised TreeView webpart (it is populated by a xml file description of a directory on disk). It renders okay but when you click on a Node (dynamic populate = true) to view the contents of a folder, you get a Javascript error "object expected".


Having done some investigation and comparing it using the same custom control but created at compile time on the page, rather than run-time which is what the webpart is doing, it seems that one (or several) of the WebResource.axd files are not getting referenced. Any ideas?


Regards,


Kieran


On 6/27/2007 10:36:08 PM Sean Jackson said ..
Hi,

Is it possible to create a REST compliant MOSS web part. The idea being to syndicate


a MOSS web part in iGoogle and also vice versa which might be easier.

Sean


On 7/2/2007 7:31:13 AM Himadrish said ..
Hi Guys,

Having one question.

If I want to plugn on some new feature on an existing webparts (say survey), then how should I proceed to accomplish the task.

Thanks,


Himadrish


On 10/4/2007 5:33:20 AM Senthilkumar.G said ..
Can we merge multiple calender in Sharepoint server 2007


On 10/5/2007 7:15:49 AM swati said ..
Is there anything like smartlibrary in MOSS2007?


On 10/22/2007 2:56:14 PM Paulette said ..
Great Post! Thanks. I was wondering though, can I use a web part built on the asp.net web part class to communicate with a web part built on the sharepoint web part class?

Thanks!


On 12/19/2007 5:10:17 AM Chander said ..
Hi Sahil,

I have a javascript function that returns a value.I would like to assign this value to a local string variable in my webpart page.


Any ideas?

Thanks


On 1/10/2008 1:46:07 PM sharepointdev #2 said ..
I'm experiencing the exact behavior as "sharepointdev" mentions above:

"I've gotten steps 1-6 working perfectly. However, when I try to use this trivial web part, the server just hangs.

DW20.exe hogs the CPU and I must kill it to continue using the computer. I've restarted the server and tried dozens of little changes, but I can't get this to work. This is extremely frustrating. Any help would be greatly appreciated."


On 1/10/2008 2:31:29 PM sharepointdev #2 said ..
Regarding my last post regarding sharepointdev's earlier post...

I resolved the issue by inheriting from System.Web.UI.WebControls.WebParts.WebPart instead, and overriding RenderControl() instead of RenderWebPart().

Thanks!


On 2/1/2008 1:32:37 PM max said ..

On 2/8/2008 4:28:32 AM Diamond said ..
I would like to add a link button in the properties pane. How can I achieve that ?


On 2/18/2008 3:59:35 PM Andy said ..
Hi,


Great article, this makes it real easy!!


I've one issue though...i tried this on my own sharepoint server and was able to get it work.


However when i tried to load the webpart on our production server i can't see the web part in the "new" web parts list.

My guess is it's somehow related to sharepoint configuration (I have admin (Full Control) privileges on the the site).


I've already checked that i've deployed (the dll is in the correct bin folder) and the corresponding web.config has the safe controls section added to it.

Any tips what i could be missing??

TIA.


-andy


On 2/21/2008 7:46:10 AM smartkhilit said ..
to the best of my knowledge,


if you are going to build the webpart for sharepoint perticularly then you should use sharepoint desiger because the webpart developed in that gives you some readymade funcationalities when you deploy them in webzones, BUT if you wanna use those webparts in to the other ASP.NET applications then i would recommend to go for smartparts. go to www.codeplex.com and search for the word smartparts, you will get the idea behind the concept. thankz, khilit


On 2/27/2008 3:41:08 PM Brandon said ..
I'm very new to SharePoint. I have an application built in ASP.NET. Just a simple application with drop down menus that launch a window when you find what you want. I basically just want to create a web part that will pull in the .aspx file that I have already created for another application. Is this possible? Can I use a server side include reference within a .cs file to just display the code I want?


On 3/2/2008 10:40:20 AM Jason said ..
Great tutorial. I tried adding the web part using either the GAC or bin method and neither cause it to show up in the webpart gallery: new web parts admin page within Sharepoint. Any ideas? Do I have a strict setting somewhere?


On 3/12/2008 8:44:21 AM Majid said ..
Hi, I have done the same process 3 times but whenever i go to webpart gallery & say NEW; my webpart doesnot come in that list. can anyone help me in this? plsssssss


On 3/31/2008 5:12:35 PM BirdBuster said ..
I have webpart and the button click is not firing, does anybody know why ?

using System;


using System.Collections.Generic;


using System.Linq;


using System.Text;


using System.Web;


using System.Web.UI;


using System.Web.UI.WebControls;


using System.Web.UI.WebControls.WebParts;


using System.IO;

namespace CustomWebPart


{


public class BasicWebPart : WebPart


{


public TextBox txt;


public Label lbl;


public Button btn;

protected void btn_click(object sender, EventArgs e)


{


lbl.Text = txt.Text;


}

protected override void CreateChildControls()


{


base.CreateChildControls();


txt = new TextBox();


Controls.Add(txt);


lbl = new Label();


Controls.Add(lbl);


btn = new Button();


btn.Click += new EventHandler(btn_click);


Controls.Add(btn);


}

protected override void RenderContents(HtmlTextWriter writer)


{


this.EnsureChildControls();


txt.RenderControl(writer);


lbl.RenderControl(writer);


btn.RenderControl(writer);


}

}


}


On 4/1/2008 1:18:36 AM Sudha said ..
Hi Sahil,

I'm a newbiee to SPS 2003.i need to add a custom web part. how can i start with.


Do i need to start with Frontpage 2003 or .net...If with .net can i go for VS 2005 instead of VS 2003..is SPS 2003 compatible with VS 2005..i mean can i create a webpart in VS 2005 and use that in SPS 2003 site.

If i'm wrong anywhere please provide me some directions.


I'm getting confused from where to start.Creating the portal site without any customisation or custom control ..i'm done with it.

Please Help me in this regard.

Thanks,


Sudha.


On 4/8/2008 2:42:38 PM MIS Dude said ..
Do I have to use the SmartPart whenever I want to put a user control into a web part? Is it possible to take the xml from an .ascx


and then populate it as a new item in the WebPart library?


On 5/2/2008 9:37:56 AM pankaj sharma said ..
hey bird have you resolved the issue..


same is happenign with my code as well


Button click event not getting fired.


any help.


On 5/8/2008 10:55:31 AM Pete Naschke said ..
I’m trying to use VB.NET to work with some AutoCAD and Excel files located in SharePoint folders.

And not having any luck…I have spent days (literally) searching for some clue as to why I’m having this problem…

Could you help me find a solution or someone who might be able to help, or a forum that you personally find knowledgeable and effective?

Any assistance would be greatly appreciated!

Thank you for your help!

Pete


naschkeps@pella.com


On 5/21/2008 2:55:23 AM Elan said ..
Hi...


Im tryin to display the data from SQL database/table in the form of charts in MOSS 2007. created a .net application tat vl represent the data from the database as charts and tried to use the URL in the page viewer webpart. But it is not working when the site is accessed from other machines. Im stuck on this..for days..any better approach to draw charts in MOSS..??? Any help, pointers, links...regarding ths will be deeply appreciated.


Thanks in advance.


On 7/10/2008 10:25:54 PM Jason said ..
Great post, Sahil. Could you explain the differences between _app_bin and bin in MOSS 2007 and why and when you would put a custom assembly in either?

Thanks!

--jason


On 11/12/2008 10:09:47 AM Chetan said ..
Mason, BirdBuster, pankaj sharma..... Did it got resolved for you... M also facing the same issue here of button click events not getting fired up..... any help in this would be great


On 12/3/2008 5:08:39 PM Shamen said ..
Hi Sahil


I managed to get to the point of selecting the webpart to add to page, but after I hit OK, it asks for authentication, which does not accept my credentials, then proceeds to break the site somehow. I luckily kept a copy of web.config which I restored and got the site back up. Any idea why this happened?


On 12/17/2008 4:01:06 AM Steven said ..
@Bird


Replace protected void btn_click(object sender, EventArgs e) with PUBLIC void btn_click(object sender, EventArgs e)


Event will fire for sure!


On 12/18/2008 3:20:03 AM Syed Raheel Noor said ..
Button click is not firing Tip:-

Check the functionality of your button click after adding the WebPart on the page,


means not on the preview page.


Hope this works!


On 1/19/2009 11:54:04 PM nalaka said ..
Hi !


I have idea to develop web part of room plan. This is the requirement. User should enter location and item detail of room. Those data should be store in xml file. Then room plan graphic is automatically created.


Can any one know how to draw plan (image) using web part..??


Please give me some idea to start this web part .

thanX.

regards,


nalaka


On 5/28/2009 3:05:02 AM Vicky sharma said ..
hi...

i m new in moss 2007. so p[lz anyone help me and tell me that where the data stored in moss database. and how..?


On 6/15/2009 10:02:13 AM osama bader said ..
Hi i want to ask about a very annoying problem i found when trying to implement what is written in this tutorial and al the others i have found in the last couple of days,this problem is that i implement all the instructions listed in the tutorial but when i try to find the web part i have added in the Gac folder using site settings-->web parts-->new i do not find it in the list so i cant add it to the web part gallery.