Debug Web Parts

This topic is close particularly close to my heart, since my job is filled with debugging web parts. The first thing you should note is that in ASP.NET, there’s a customErrors section in the web.config files. However hard you set it to false in every imaginable level SharePoint will override it, and shows its useless “Oops, exception, I won’t tell you anything about it” form. Unless you set callStack attribute of the SharePoint element in the very same web.config file to true.

But of course serving error messages with call stack is not the most user friendly way of showing that something went wrong. SharePoint provides a nice logging infrastructure. The key player is the ULS (Unified Logging System) log. You can find it in the 14/ folder of your SharePoint installation, under the log folder. Although you’ll be much better using the free ULS Viewer tool.

SharePoint logs a great deal of information to this log by default. For example, unhandled exceptions which bubble up to the UI are all logged here. But you can use this log programmatically, too. You can use the SPDiagnosticsService class to write your events to the ULS logs, or roll out your custom logging implementation by subclassing the SPDiagnosticsServiceBase class.

SharePoint 2010 has a component called the Developer Dashboard which is very similar to ASP.NET tracing. By default, it’s turned off, so you have to use stsadm or PowerShell to make it appear. There are two modes of operation: On displays the dashboard icon on every page, so anyone with rights to the page can view its output on every page. There’s another mode called OnDemand, which displays an icon on every page, on which you can access the dashboard information. By default the dashboard records a variety of instrumental information, but of course you can add your own informations to it. You have to wrap your all your custom components you’d like to display in SPMonitoredScopes. Here’s a quick code:

using (var scope = new SPMonitoredScope(“My long running method”))
{
//Your code here.
}

Now run time information will be available on the dashboard for you.

Implement a dialog by using the Dialog Framework


Dialogs are a conventional way of notifying a user or prompting for input. Like them or not, SharePoint uses them a lot, so users are accustomed to them, thus there’s a high chance that you have to develop custom ones.

Fortunately there’s a simple entry point when you construct dialogs: the SP.UI.ModalDialog class. You can construct a dialog many ways, and show it using the showModalDialog function. There are a bunch of options you can pass in, such as the title of the dialog, the url of the content, callback function, etc. Here’s a brief list:

  • Title: the title of the dialog. If not specified, the target page’s title will be used. If used with custom html content, then the term ‘Dialog’ will be used.
  • x, y, width, height: the position and size of the dialog.
  • allowMaximize, showClose: show or hide these buttons, respectively.
  • showMaximized, autoSize: note the fantastic naming convention. Showmaximized indicates whether or not to show the dialog “full screen”, autoSize needs no comment.

The remaining properties are more important, so let’s review them here. If you want to use your custom HTML content, then you can pass a DOM element as the html parameter. Now since I mostly use jQuery to generate my HTML markup when it comes to dialogs, here’s a little trick to convert a jQuery object to make it usable for showModalDialog:

var html = “<div>My markup</div>”;
var htmlAsDomElement = $(html).get(0);

More interesting is the dialogReturnValueCallback parameter. You can pass in a function to be called when the user finishes with the dialog. Two parameters will be needed, one for the result (eg. closed, canceled, ok’d) and one for the return value (if any) of the dialog.

For a real hardcore in-depth introduction of SharePoint dialogs, check out this blog post.

Manage SPSite and SPWeb programmatically by using Visual Studio 2010

The SharePoint terminology of sites, webs and site collections is a bit confusing at first. An IIS website can contain one SharePoint web application, which can be represented as an instance of the SPWebApplication class. This web application can contain numerous site collections. Programmatically a site collection is an instance of the SPSite class. And finally, each site collection can contain numerous websites (represented as SPWebs), which themselves can contain multiple websites, too.

The hierarchy can be represented as follows:

  • SPWebApplication
    • SPSite
      • SPWeb
        • SPWeb
        • SPWeb
          • SPWeb
        • SPWeb
      • SPWeb
    • SPSite
      • SPWeb

The entry point is usually an SPSite object. You can construct an SPSite from an URL or if your program runs in a SharePoint context, you can leverage the SPContext class to get a reference of the current SPSite. But typically you won’t stop at the SPSite. Most likely you’ll want to work with a website, namely an SPWeb object. It’s fairly easy to acquire an SPWeb once you have an SPSite. SPSite has a method called OpenWeb with multiple overloads. The most noteworthy of these is the parameterless one, which opens the website based on the url you used to open the SPSite. A typical usage looks like this:

using (SPSite site = new SPSite(“http://myspsite.com/myWeb”))
{
using (SPWeb web = site.OpenWeb())
{
//do some stuff here
}
}

Note the using blocks. Both SPSite and SPWeb implements the IDisposable interface, and you should definitely release them to avoid memory leaking. However, if you acquired your SPSite (or SPWeb) instance from a shared resource (e.g. from the SPContext class) then you should not dispose them, since SharePoint will definitely want to use them afterwards, and that will raise an exception.
Subweb creation is not a typical task, but it’s fairly easy using an SPWeb. You just need to call the Add method of the Webs property. It has three overloads, but they are very self explanatory.

Property bag access is very simple, too. Use the AllProperties property of your SPWeb. It’s a simple HashTable, so you can use an object as a key and value, too. There’s one big catch, however. There’s a property on the SPWeb called Properties. This also works with the property bag service, but you should use it only in legacy situations. The main reason is that the Properties collection is case-insensitive (which was good as SharePoint 2007 was concerned) and in SharePoint 2010 property bag access (and the keys) are case-sensitive. Imagine you put a custom property with the key “MyKey”, using the Properties collection. SharePoint will happily create a new property with the key in lowercase, so it’ll be “mykey”. But when you’ll try to access it (using the Properties, or the AllProperties collection) it’ll look for the “MyKey”, and will not found that. So always use the AllProperties collection.

Whenever you make changes to an SPWeb you should call its update method. This will take care of persisting the changes in the database backing up SharePoint. You can use batching too, so it’s not important to call the Update method after every operation (on the contrary, it would decrease performance).

Last but not least: feature activation. You can activate a feature on a site or a web by adding or removing its guid to the Features collection. I don’t think this needs further explanation.