Jason Specland: An Occasionally Funny Software Guy

Making it up as I go along. Always.

Tag: sharepoint

Exporting XSLTListView Web Parts to Other Webs + In Place Records Management Enabled = Null Reference Exception

Here’s the scenario: In SharePoint, you want to view one or more lists from one web in a site collection in a different web on the same site collection. What do you do? That’s easy: You go to SharePoint Designer, go to the original list view, export the XSLTListView web part that represents that view, load it into your other web and place it in whatever web part page you’d like. Boom. Dashboard.

Unless, of course, you’ve got the In Place Records Management feature enabled. In that case, you’re screwed. Everything will look fine for a while. But eventually, all of the views of your original list will fail. You will see the dreaded:


Server Error in '/' Application.
________________________________________
Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[NullReferenceException: Object reference not set to an instance of an object.]
Microsoft.Office.RecordsManagement.RecordsRepository.Records.GetCachedAllowManualRecordDeclarationSetting(CachedList list, Hashtable siteProperties) +3
Microsoft.Office.RecordsManagement.Controls.<>c__DisplayClass1.b__0() +164
Microsoft.Office.Server.Utilities.MonitoredScopeWrapper.RunWithMonitoredScope(Action code) +39
Microsoft.Office.RecordsManagement.Controls.DeclareRecordAction.GetDeclareRecordInfo() +158
Microsoft.Office.RecordsManagement.Controls.InPlaceRecordsRibbon.Page_PreRenderComplete(Object sender, EventArgs e) +74
System.EventHandler.Invoke(Object sender, EventArgs e) +0
System.Web.UI.Page.OnPreRenderComplete(EventArgs e) +11058669
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3671

Why, SharePoint!? WHY!? (Seriously, if I had a nickel for every time I shouted that…)

Well, with the help of our good friend .NET Reflector, let’s take a closer look at that stack trace, shall we?

Microsoft.Office.RecordsManagement lives in Microsoft.Office.Policy.dll. I open it up and take a look at GetCachedAllowManualRecordDeclarationSetting(CachedList list, Hashtable siteProperties). Not much there…

[sourcecode language=”csharp”]
internal static bool GetCachedAllowManualRecordDeclarationSetting(CachedList list, Hashtable siteProperties)
{
if (list.RecordsUseListSetting)
{
return list.RecordsAllowManualDeclareSetting;
}
return GetCachedAllowManualDeclarationSiteSetting(siteProperties);
}
[/sourcecode]

Nothing that’s going to throw a NullReferenceException unless the cached list itself is null. So let’s travel up the stack a bit to Microsoft.Office.RecordsManagement.Controls.<>c__DisplayClass1.b__0().

[sourcecode language=”csharp”]
public void b__0()
{
SPList list = SPContext.Current.List;
if (list != null)
{
CachedArea rootArea = CacheManager.GetManagerForContextSite().ObjectFactory.RootArea;
CachedList cachedList = CommonUtilities.GetCachedList(SPContext.Current.Web, SPContext.Current.ListId);
if (list != null) // <- WTF!? (This comment added by me.) { this.declareRecord.iprList = Records.GetCachedAllowManualRecordDeclarationSetting(cachedList, rootArea.Properties); if (this.declareRecord.iprList) { this.declareRecord.userHasRights = Records.CachedDoesUserHavePermissionsToDeclare(list, rootArea.Properties); } } } } [/sourcecode] Ah HA! The cached list is null! The inner null check is clearly meant to check the null-ness of cachedList and not list! So, thanks to a clear, obvious bug in SharePoint, you can’t use XSLTListView Web Parts on other webs in your site collection if In Place Records Management is turned on. Unfortunately, the only solution is to turn it off.

Note: I upgraded my development SharePoint instance to the February 2012 CU. This bug still exists in assembly file version 14.0.6116.5000.

Hyper-V VM Not Starting Due to Insufficient RAM, Even Though You Have Enough? Kill googlecrashhandler.exe

So this morning I start up my computer, and start up my SharePoint Development VM. I get a message saying that my VM won’t start. It says “Unable to allocate 6144 MB of RAM: Insufficient resources exist to complete the requested service. (0x800705AA).”

Well naturally I like to give my SharePoint VM lots of RAM, but 6144 is right around the amount that is actually free. So I lower it to 4096 MB. Task Manager tells me I have more than enough free RAM to do that. But I try to start it up… No dice. I lower it to 2048 MB. It starts all right, but running SharePoint + SQL Server + Visual Studio on 2 GB of RAM is not something I relish.

Finally, my Google-Fu was powerful enough to show me newly-posted answer on TechNet.

googlecrashhandler.exe? Really!? Well, seems silly, but anything’s worth a try. I kill the 2 processes and boom. My VM starts with 6 GB of RAM, just like always.

I’m writing this up for two reasons: Primarily, I’m putting this out there so Google can grab it and save my fellow devs from frustration. But secondarily, as a SharePoint developer, it’s not often that I have cause to direct WTF’s at a party other than Microsoft.

Hey, Google: WTF!?

Hey, SharePoint: Why Do You Screw Up My Content Type When I Deploy It Through Visual Studio?

So, we all love the way Visual Studio 2010 allows us to debug our SharePoint code with a single bounce on the F5 button, right? Isn’t it nice the way we can deploy with confidence, knowing that we debugged our code in the dev environment? Surely, our code and configurations will act exactly the same way when we deploy them with Add-SPSolution as they do when we deploy them with F5. Right?

Well then what the hell is up with this:

I’m doing something that I think is pretty typical. I’ve created a content type, descended from Document, to go into a document library, like so:

[sourcecode language=”xml”]












[/sourcecode]

And I’ve created a document library to hold documents of this content type, like so:

[sourcecode language=”xml”]







(blah blah blah)

(blah blah blah blah blah)


[/sourcecode]

So can you tell me why I see the following when I hit my F5 key?

A SharePoint List Configuration Screen

Hm, that’s odd. I called my content type “Project Document” not “Project Documents.” Project Documents is the name of the document library itself. Let’s take a closer look at that content type, shall we?

A SharePoint Content Type Configuration Screen

What the WHAT? That’s no content type, that’s a list instance! I wondered what I’d done wrong. It’s certainly not out of the question for me to screw up a SharePoint XML configuration somewhere. Hell, screwing that up is most of what I do all day. So I went to my test server, where I’d deployed a slightly different earlier version. The document library and content type appeared normal. Could there possibly be some difference in the way I deployed the project? I deployed the .wsp manually on the dev box… the very same .wsp I’d just debugged with F5.

A SharePoint List Configuration Screen, from a manually deployed project.

But that looks perfectly normal. What about the content type itself?

A SharePoint Content Type configuration Screen.

So… I guess this means I can’t trust content deployed through Visual Studio anymore. Hey, it’s not like I needed a streamlined workflow or anything.

My Upgrade Actions Can’t Have a Comment? Really, SharePoint?

So I’m doing new work on a SharePoint feature that’s already deployed, so naturally, I have to do some upgrade actions to deploy some new fields to a content type. There are a few fields to add, and since the AddContentType field doesn’t have any naming elements, I decide to throw in some comments before each entry, so I know which field is which and I make sure I haven’t forgotten any. Everything compiles fine and Update-SPSolution works fine. Then, I try to run my upgrade and I get the following error:

Really, SharePoint? You can clearly see that it’s a comment, and yet you still just barf on it rather than just ignoring it. WHY!?

Adventures in Uninformative SharePoint Messages, or The Sandbox is Too Damn Busy for Your List Receiver

Still here? Great. So, here’s the situation. Tell me if it seems crazy. There are things that, to me as a programmer, don’t seem crazy at all, while more seasoned SharePoint developers would look at what I was doing and scream, “Are you mad?” Like iterating through SPList.Items() in a foreach loop without first putting them into an SPListItemCollection, for example.

Anyway, I have the following situation: A project tracking list, which has a “Primary Technical Lead” field and a “Secondary Technical Lead” field, both of which are single User-type. I need to create a “Team Members” field, which is a multi-User type. Upon creation of that field, I need to populate it with both the value from the Primary and Secondary tech lead fields. Naturally, I chose to implement this one-time setup in the FeatureActivated event receiver.

Additionally, I want to make sure that whenever a tech lead is changed, that that change is reflected in the Team Members field. I also want to make sure that you can’t delete someone from Team Members if they’re still a tech lead. Naturally, I chose to implement this as an ItemUpdating event receiver.

Every time I tried to activate the solution, however, I always got the following error:

Unhandled exception was thrown by the sandboxed code wrapper’s Execute method in the partial trust app domain: The sandboxed code execution request was refused because the Sandboxed Code Host Service was too busy to handle the request.

Well, excuuuuuuuuse me!

Now, I wasn’t entirely un-clever about this. Of course my ItemUpdating event was firing when I was trying to populate the TeamMembers field. (Okay, I’m kind of lying. There was a lot of blank “WTF?” going on in my head before I realized that the ItemUpdating event was firing. Then I went through the feature activation in the debugger, and noticed that the exception was thrown when I called SPListItem.Update() or SPListItem.SystemUpdate(), which I tried in desperation.) But my ItemUpdating method should have just quickly exited upon not seeing the fields that it was worried about in the AfterProperties. Still, worried about my logic, I commented out my routine line by line. Until finally, my entire ItemUpdating receiver looked like:

[sourcecode language=’c#’]
public override void ItemUpdating(SPItemEventProperties properties) {
// Lots of commented-out lines
base.ItemUpdating(properties);
}
[/sourcecode]

And still, Sandbox is Too Damn Busy.

Then I went to the List Receiver’s Elements.xml file, and commented out the <Receiver…><Type>ItemUpdating</Type>…</Receiver> part. And lo and behold, the Sandbox would suddenly take my calls again.

I then created the simplest test case. One list. One ItemUpdating event receiver which does nothing. One FeatureActivated event receiver that updates a list item. Activation == game over.

Now I understand why updating a ListItem that has an ItemUpdating receiver from a FeatureActivated receiver might be a problem. But, once again, SharePoint has vomited forth one of the least useful error messages possible.

Sharepoint: Updating Workflow Task Causes NullReferenceException (a fix)

I’ve got a workflow where a project manager approves a project (that’s one kind of task), or can send it out for technical review (another kind of task), or can request more information from the user (yet another task). Each of these tasks have their own Content Type, and their own custom task edit form in ASP.NET. (Because I hate InfoPath with a burning white hot hate.)

Whenever someone uses one of these custom edit forms, however, I get a NullReferenceException. The stack trace always puts it in the non-public SPListItem.PrepeareItemForUpdate method. It doesn’t matter how I change the task list item. Using SPWorkflowTask.AlterTask, or just SPContext.Current.ListItem followed by Update all threw the NullReferenceException.

To Google I go! However, most of the results said that it had to do with not having a definition in the Content Types. That wasn’t my problem, however, since not only did my Content Types have FieldRef’s, but they were very much full.

At my wits end, I broke out the .NET Reflector and decompiled the Microsoft.SharePoint assembly. Here’s what I found:

As you can see (well, kind of see… click on it to see more clearly), this would only happen in a WorkflowTask. If the list item’s “Completed” field is null, the cast to bool throws a NullReferenceException. This is probably the kind of thing that can’t happen in SharePoint Designer, but only would occur when someone is mucking about in Visual Studio.

To fix it, make sure you set the “Completed” field. I do this:

[sourcecode language=’c#’]
private void SetTaskStatus(string status, bool taskIsComplete) {
SPListItem taskItem = SPContext.Current.ListItem;

Hashtable taskData = new Hashtable();
taskData[SPBuiltInFieldId.TaskStatus] = status;
taskData[SPBuiltInFieldId.Completed] = taskIsComplete;
if (taskIsComplete) {
taskData[SPBuiltInFieldId.PercentComplete] = 1;
}

SPWorkflowTask.AlterTask(taskItem, taskData, true);
}
[/sourcecode]

Or, if you work for Microsoft, you could do us a favor and make sure that you null check that line and default to false. (It’s entirely possible that this has been fixed by SP1, but my production server doesn’t run that yet, so I can’t either.)