.NET Reflector
Latest version: 8.0
Notes & articles
Debugging a SharePoint customization
SharePoint has a large and complex code base, and some of the details aren't as transparent or well-documented as developers need. This is a short overview showing how bugs can arise when working with incomplete documentation, and how we can use .NET Reflector to fix those bugs.
In this scenario we're working on a web portal, and we want to add a set of controls to the ribbon. This is simple enough, but we run into an unexpected error. We use .NET Reflector to explore the SharePoint API that is throwing the exception, so we can understand the problem and troubleshoot the control.
Defining custom controls
We're looking at an issue in SharePoint 2010, where XML comments in definition files cause an exception. The issue can arise when creating custom fields, content types, and other custom features that require XML definition files. The XML schema for SharePoint Features is documented, but the documentation doesn't always give rich implementation information.
The custom action behind the control is defined in the XML file, and it's part of a group of controls being used in the ribbon. Because these files quickly become long and complex, we want to comment the code.
This is a simplified "hello world" example of a custom action definition file:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<CustomAction
Id="Ribbon.WikiPageTab.CustomGroup"
Location="CommandUI.Ribbon">
<CommandUIExtension>
<CommandUIDefinitions>
<CommandUIDefinition
Location="Ribbon.WikiPageTab.Groups._children">
<groups>
<!-- Group containing the new "hello world" controls -->
<Group
Id="Ribbon.WikiPageTab.CustomGroup"
Sequence="55"
Description="Custom Group"
Title="Custom"
Command="EnableCustomGroup"
Template="Ribbon.Templates.Flexible2">
<Controls Id="Ribbon.WikiPageTab.CustomGroup.Controls">
<Button
Id="Ribbon.WikiPageTab.CustomGroup.CustomGroupHello"
Command="CustomGroupHelloWorld"
LabelText="Hello, World"
TemplateAlias="o2"
Sequence="15" />
<Button
Id="Ribbon.WikiPageTab.CustomGroup.CustomGroupGoodbye"
Command="CustomGroupGoodbyeWorld"
LabelText="Good-bye, World"
TemplateAlias="o2"
Sequence="18" />
</Controls>
</Group>
</groups>
</CommandUIDefinition>
</CommandUIDefinitions>
<CommandUIHandlers>
<CommandUIHandler
Command="EnableCustomGroup"
CommandAction="javascript:return true;" />
<CommandUIHandler
Command="CustomGroupHelloWorld"
CommandAction="javascript:alert('Hello, world!');" />
<CommandUIHandler
Command="CustomGroupGoodbyeWorld"
CommandAction="javascript:alert('Good-bye, world!');" />
</CommandUIHandlers>
</CommandUIExtension>
</CustomAction>
</Elements>
(In practice, we could be dealing with hundreds of lines of XML)
When the portal page renders, the controls appear. But when the control is actually used, SharePoint displays an error.
Debugging the error
SharePoint error messages typically have a Correlation ID a GUID that lets us track the error through the logs. From these logs, we see that the error is a null reference exception.
This is surprising, because in building our control, we've followed the SharePoint documentation pretty thoroughly. At first glance, there appears to be nothing wrong with any of our own code, and the custom action definitions match the documented schema.
To solve the problem, we look into the code with .NET Reflector.
We see that the exception is thrown by Microsoft.Web.CommandUI.Ribbon.CreateRenderContext, so we search for that library using .NET Reflector desktop, and decompile it to view the underlying source code.
The code .NET Reflector shows us is:
}
DataNode node4 = uiproc.GetResultDocument().SelectSingleNode("/spui:CommandUI/spui:Ribbon/spui:Tabs/spui:Tab[@Id='" + this.InitialTabId + "']/spui:Groups");
if (node4 == null)
{
node4 = uiproc.GetResultDocument().SelectSingleNode("/spui:CommandUI/spui:Ribbon/spui:ContextualTabs/spui:ContextualGroup/spui:Tab[@Id='" + this.InitialTabId + "']/spui:Groups");
}
Hashtable hashtable = new Hashtable();
if (node4 != null)
{
foreach (DataNode node5 in node4.ChildNodes)
{
XmlAttribute attribute2 = node5.Attributes["Id"];
if (attribute2 != null)
{
hashtable[attribute2.Value] = node5;
}
}
}
}
If a node is a comment, rather than a conventional element, the value returned is null. This is becuase XmlNode.Attributes returns as null for all nodes that are not of the XmlNodeType.Element type. This null result is unexpected, so an exception is thrown.
Luckily, the solution is simple, and removing the comments prevents the exception. This may not be an ideal workaround, but because the limitation lies in a third-party assembly, it can't be fixed directly.
Improving on documentation
The XML comments issue is a small example of an undocumented limitation. It's simple to fix with decompilation tools, but would be a substantial debugging task without the ability to look inside the underlying code.
Unfortunately, incomplete (or entirely absent) documentation is quite common for 3rd party tools libraries, and frameworks. SharePoint itself is elaborate, complex, and difficult to debug and understand using only the published documentation. In practice, you can encounter unusual errors, or require customizations that depend on entirely undocumented behaviour.
In these cases .NET Reflector saves troubleshooting time, and lets you explore 3rd party libraries in context, to better understand how to integrate with them and build upon them.
Was this article helpful?
.NET Reflector
- Log files
- Methods showing no source code in the disassembly window
- Permissions error on starting Visual Studio
all products
- Some Red Gate products identified as containing a trojan by Anti-Virus software
- Activation may fail with Unknown Error -1
- Product uses web help although a CHM file is available locally
- Argument exception resulting from missing environment variable
- Check for updates may fail when used through proxies
- 'Unidentified Publisher' error when repairing or uninstalling
- Licensing activates product as standard edition
- Moving Red Gate software products to another machine
- Red Gate tools log locations
- The application UI opening slowly when there is no internet access
.NET Reflector
- Debugging a SharePoint customization
- Debugging into SharePoint and seeing the locals
- Downloading .NET Reflector as a zip file
- Introduction to building .NET Reflector add-ins
- .NET Reflector Tips: keyboard shortcuts
- Using the .NET Reflector Power Commands
- Release notes - .NET Reflector 7.x
- Release notes - .NET Reflector 8.x
- Using the .NET Reflector installer
- Using .NET Reflector with Visual Studio 2005 or 2008
- .NET Reflector and .NET Reflector Pro release notes - version 6.xx
- .NET Reflector, .NET Reflector VS and .NET Reflector VS Pro release notes - version 7.xx
- The XP Bug Workaround
- Log file for .NET Reflector Pro
all products
- Red Gate product acknowledgements
- Activating your products
- Activating your products
- Red Gate bundle history
- Check for updates
- Troubleshooting Check for Updates errors
- Current versions
- Deactivating your products
- Installing Red Gate products from the .msi file
- Requesting additional activations
- Serial numbers for bundles
- Reactivating using a different serial number
- Extending your trial
- Finding your serial numbers
- Moving a serial number from one computer to another
- No response received for manual activation
- Licensing and activation resources
- Licensing and activation resources
- Troubleshooting licensing and activation errors
- Licensing and activation FAQs
- Red Gate tools log file locations
- Download old versions of products
- Download product prerequisites & utilities
- Support & upgrades
- Upgrading your software
- Upgrading FAQs

