WebPart Development in SharePoint 2003 (a.k.a. v2)

v1.1
by Walt Stoneburner
"How I long for PHP."


Synopsis

Resources
Understanding how to make the leap from web pages to web parts using Sharepoint Portal Server (SPS) is a bumpy transition. There's just not a lot of documentation out there about how to do it. This article captures the bits and pieces that have helped me make some headway.

Web Parts - What Are They?

The idea seems to be to make a component that can be placed on a web page. No, we're not talking Java Applets, we're talking about code that understands the Sharepoint framework.

You can drag multiple instances onto a page's zone (let's be real, this is just a table) and the Sharepoint server maintains the state and handles the rendering of the content you put out there.

The jist of how to make a web part is fairly well understood. The problem is in making the web part interact with the user in a meaningful fashion.

Getting Started

Visual Studio .NET doesn't come with the Sharepoint Web Part templates installed by default. You'll need to download the web part templates and install them in order to get the automatic code generation.

You will also need a public key pair, so that you can sign your web part facilitating part of the process required to empart trust to your code.   [See the Understanding PKI article.]

"C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\sn.exe" -k KeypairFile

This filename will go into the AssemblyInfo.cs file in your project:

[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("KeypairFile")]
[assembly: AssemblyKeyName("")]
Note that the KeypairFile will require escaped backslashed. For instance C:\MyKeys\WebPart.snk would become C:\\MyKeys\\WebPart.snk.

Anyone who has your KeypairFile will be able to distribute Webparts via your authority. Limit its distribution to only the necessary development staff.

Calling Sequence of a
Microsoft.SharePoint.WebPartPages.WebPart

Web Part Calling Sequence
Web Part
Calling Sequence
37.7K PDF
  1. Constructor
  2. Set WebPart Properties to Current SharepointValues
  3. AfterDeserialize()
  4. OnInit( System.EventArgs )
  5. Class_Init( NameSpace.Class, System.EventArgs )
  6. TrackViewState()
  7. EnsureChildControls()
  8. CreateChildControls()
  9. Controls_Init( Control, System.EventArgs )
  10. OnLoad( System.EventArgs )
  11. CreateWebPartMenu()
  12. Class_Load( NameSpace.Class, System.EventArgs )
  13. Controls_Load( Control, System.EventArgs )
  14. GetToolParts()
  15. Get WebPart Properties
  16. Controls_TextChanged( Control, System.EventArgs )
  17. Controls_Click( Control, System.EventArgs )
  18. Controls_Command( Control, System.EventArgs )
  19. OnBubbleEvent( Control, System.EventArgs )
  20. Set WebPart Properties to New User Specified Values
  21. Get WebPart Properties
  22. Get WebPart Properties
  23. Get WebPart Properties
  24. Get WebPart Properties
  25. EnsureInterfaces()
  26. GetRequiresData()
  27. EnsureChildControls()
  28. OnPreRender( System.EventArgs )
  29. Class_PreRender( NameSpace.Class, System.EventArgs )
  30. Controls_PreRender( Control, System.EventArgs )
  31. SaveViewState()
  32. RenderWebPart()
  33. RenderChildren( System.Web.UI.HtmlTextWriter )
  34. Controls_Unload( Control, System.EventArgs )
  35. OnUnload( System.EventArgs )
  36. Class_Unload( NameSpace.Class, System.EventArgs )
  37. Dispose()
  38. Dispose()
  39. Dispose()
See Also: System.Web.UI.WebControls, System.Web.UI.Page

Rendering Controls on the Web Part

Many of the coding examples will tell you to create a control and use the RenderWebPart() method to render it.

...
// Create a button object
Button b = new Button();
...
  protected override void RenderWebPart(HtmlTextWriter output)
{
  ...
  // Render the button
  b.RenderControl(output);
  ...
}

The problem with this method is that it requires that every control rendered be available by scope and that often means making the control a member of the web part. Not good when you either have a lot of controls or generate them dynamically.

The better solution is to register the controls with the web part and let it handle all the rendering.

{
  ...
  // Create a button object
  Button b = new Button();
  Controls.Add( b );
  ...
}
  protected override void RenderWebPart(HtmlTextWriter output)
{
  // Render all controls
  RenderChildren( output );
}

Well That Was Important To Know...

So, not only do you have to know about Sharepoint and how to write a Web Part, but there's a lot that goes on to install one.

Your Web Part is going to be an Assembly (.DLL) file, this contains the code. You want to put this in your web site's bin directory, which is usually C:\INetPub\wwwroot\bin.

At this point the web part isn't trusted, so you'll need to drag it from that location to the Global Assembly Cache (GAC), which is actually the C:\Windows\Assembly directory.

To obtain a PublicKeyToken, which is a portion of a hash value to uniquely identify the control that is needed for the config files, you can look at the Assembly's properties from the GAC, or you can use the Strong Name (sn.exe) utility to display it.

"C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\sn.exe" -t C:\Inetpub\wwwroot\bin\YourAssembly.dll

However, Sharepoint won't know about that file until you make an entry in web.config, which is normally located at C:\INetPub\wwwroot\bin\web.config. That entry often looks like:

</SafeControls>
  ...
  <SafeControl Assembly="AssemblyFileName, Version=1.0.0.0, Culture=neutral, PublicKeyToken="hex token" Namespace="YourNameSpace" TypeName="*" Safe="True" />
</SafeControls>

Luckily, all this can be accomplished with the 3rd Party utility called InstallAssemblies.zip, a free utility brought to you by Alan Smithee.

Finally, Sharepoint needs to reload from the web.config file if you changed it, or at least ditch whatever is stale in its webpart cache if you've been doing developing. To do this you need to kill the w3wp.exe process, which can be accomplished by running the iisreset command at the DOS prompt.

At this point, you beam up the .DSP file to Sharepoint, which has your web part description in it. From the virtual gallery, you then drag it onto your page.

Debugging In Sharepoint 2003

It is possible to debug webparts, but the trick involves attaching to the Sharepoint process.

With Sharepoint running, open up Visual Studio .NET and select the Debug menu, then select Processes..., turn on all processes and locate in the list w3wp.exe and select it. Click Attach..., then make sure Common Runtlime Langauge is selected, click OK, then Close.

You can now set breakpoints, etc. When you load a webpage with the webpart on it, your breakpoints will be triggered.

Be careful though, you know how web servers have timeouts? Well, if you exceed the page load timeout, your debugging thread will abruptly terminate and you'll have to start all over again by forcing a page reload.

What's This Message Mean?

Every once in a while, Sharepoint gives me some non-descript error that sends me off on a wild goose chase for hours. Here's stuff I've been bitten by and how I got around it.

A Web Part or Web Form Control on this Web Part Page cannot be displayed or imported because it is not registered on this site as safe.

  • The WebPart's class constructor did not have the word public explictly declared.

  • Forgot to use the fully qualified type name in the .DWP file.
    <TypeName>Namespace.ClassName</TypeName>

  • The WebPart's Assembly wasn't registered in the GAC.
    Make sure GAC is selected when you use the Install Assemblies utility.

  • Forgot to reset Sharepoint, it was using a cached version of an older assembly.
    Do a iisreset.

  • The PublicKeyToken in web.config didn't match that of the assembly's.
    Use the Strong Name (sn.exe) utility, which is burried deep in the Visual Studio .NET directory structure, to extract the PublicKeyToken from your assembly, which is most likely hiding in C:\Inetpub\wwwroot\bin.
    sn -t YourAssembly.dll

  • Forgot to generate a key and have the Web Part automatically sign with it.
    Inside AssemblyInfo.cs specify the AssemblyKeyFile, and remember to escape backslashes when doing so.
    [assembly: AssemblyKeyFile("C:\\SOMEDIR\\KeypairFile.snk")]
    .SNK means Strong Name Key

SlingCode Search Results About     Articles     Links     Search Tips  
SEARCH: