basquang™ on clouds

October 14, 2010

SharePoint 2010 Woes: Avoid comments in your CustomAction-XML for Ribbon customizations

Filed under: SharePoint — basquang @ 9:09 AM

For a customer project I had to add a custom tab to the Ribbon of SharePoint 2010 for a specific library. In this tab I wanted to have several groups of controls. In one group I needed to have a button that triggers the standard upload functionality of SharePoint (Command=”UploadDocument”). So far this is a pretty straight forward process.

If you’ve ever created a CustomAction to add a tab to the Ribbon, you’ll agree that you’ve to write a looot of XML. I personally believe it’s a best practice to comment the code one creates. If you have a XML-document with hundreds of lines of mark-up, usually it makes sense to add a comment here and there. In my case my CustomAction-XML was commented like this:


<Groups
Id=”Test.Ribbon.Tab.Groups”>
  <!–
    Group “New” with Button “Upload”
–>
  <Group
Id=”Test.Ribbon.Tab.NewGroup”

>
    <Controls
Id=”Test.Ribbon.Tab.NewGroup.Controls”>
  <Button
Id=”Test.Ribbon.Tab.NewGroup.Controls.Upload”
Command=”UploadDocument”

/>
    </Controls>
  </Group>

</Groups>

As you can see I’ve added a comment above the group “Test.Ribbon.Tab.NewGroup” and with this I’ve entered a world of pain. The Ribbon and the tab including all groups and controls were rendered without any issues. I also was able to click on the button “Test.Ribbon.Tab.NewGroup.Controls.Upload” and the “Upload Document”-dialog was displayed as expected, but after clicking on the “OK”-button in the dialog, I ran into this well-known error:

clip_image001[7]

In the SharePoint log you can find the following entry related to this error:

System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.Web.CommandUI.Ribbon.CreateRenderContext(CUIDataSource uiproc) at Microsoft.Web.CommandUI.Ribbon.Render(HtmlTextWriter writer) at Microsoft.SharePoint.WebControls.SPRibbon.Render(HtmlTextWriter writer) at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) at System.Web.UI.HtmlControls.HtmlForm.RenderChildren(HtmlTextWriter writer) at System.Web.UI.HtmlControls.HtmlForm.Render(HtmlTextWriter output) at System.Web.UI.HtmlControls.HtmlForm.RenderControl(HtmlTextWriter writer) at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) at System.Web.UI.HtmlControls.HtmlContainerControl.Render(HtmlTextWriter writer) at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) at System.Web.UI.Page.Render(HtmlTextWriter writer) at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

The method “Microsoft.Web.CommandUI.Ribbon.CreateRenderContext” throws a “System.NullReferenceException”. Whoa! To make a long story short, after digging around for several hours I found the reason for this issue: the comment above the group in the CustomAction-XML. Here is what Reflector tells you about the implementation of “Microsoft.Web.CommandUI.Ribbon.CreateRenderContext”:

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;

} } }

I will not comment on the quality of this implementation, but if you look at XmlAttribute attribute2 = node5.Attributes[“Id”]; it becomes clear: the Attributes-property is the reason why I get the NullReferenceException, because for a System.Xml.XmlNode-Object that is a System.Xml.XmlComment this property is null (http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.attributes.aspx). So if you put a comment above your group in your CustomAction-XML you’re doomed. Do yourself a favor and don’t do it.

I hope this blog-post will save you save some time and headaches. It took me quite some time to figure out the reason why my button in my custom Ribbon-tab wasn’t working.

Reference

Created by Sven Häfker

Advertisements

3 Comments »

  1. Exactly the same thing happened in my code. Spent a couple of hours troubleshooting until I found your post. New rule: not comments in the group element.

    Thanks for the post.

    Comment by Mike G — October 25, 2010 @ 6:27 AM | Reply

  2. Thanks for the post. I wasted about 6 hours trying to figure this one out. Makes one seriously consider a career change!

    I would get a NullReferenceException whenever commandui.ashx was called to retrieve the ribbon data.

    Comment by Garrett — May 30, 2012 @ 3:39 AM | Reply

  3. superb man

    Comment by Piyush55 — October 12, 2016 @ 7:00 PM | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: