Archive

Archive for November, 2013

Using SPListItemCollections indexer to get SPListItem returns different/reset item every time appearing to not save changes

While in a hurry to test some code I discovered that calling the following will not actually save your change:

spListItemCollection[0][“Title”] = “Hello World”;
spListItemCollection[0].Update();

Instead you need to store the SPListItem returned by the first indexer call and then use it to set and update.

var spListItem = spListItemCollection[0];
spListItem[“Title”] = “Hello World”;
spListItem.Update();

This indicates that even though its a property, the indexer is giving you a new or reset instance of the SPListItem everytime you ask for the same index.

Normally I would have refactored this and used a variable from the get go and so I would have never seen this. This just goes to show even the ones that build the framework don’t even follow their own best practices so always assume the worst and store objects in variables first before using them.

Advertisements
Categories: Uncategorized

Errors importing SharePoint web parts and Health Monitor alerts

This is a draft, but to get the notes down I am publishing it and will update it master with the details.

We had been receiving errors alerts in the Health Monitor after upgrading NeoStream’s P4E product line to SharePoint 2013. Although the error alerts were front and center in the monitor. It wasn’t breaking anything so we ignored them.

I recently started mucking around with importing sites from PowerShell and cane across some errors that had the same smell about them.

These errors seemed situational at first, occurring for a while and then disappearing. It turns out that the error “failed to import unknown web part”, which would last for a while in PowerShell then go away, would actually go away the moment I opened a specific SharePoint web part page in the browser. Something was amiss and sharepoint corrected it when the page opened.

I ran a couple scripts to diagnose the web parts in error and nailed it down to a custom web part in the product. This webpart was pretty benign itself, and after checking that it wasn’t the configuration of the web part I cracked open the code.

The answer was immediately apparent…

Something that alot of people don’t know is that sharepoint operates in a few different processes, including the IIS worker process, the SharePoint Timer service, and (when you use PowerShell) in PowerShell. Well of these processes and more, only one of them actually has a SPContext.Current, which is created in the ASP.Net pipeline based on the http request. This means that any code calling methods or properties on the SPContext.Current which is outside of ASP.Net, will fail with an object ref error.

So what’s that got to do with web parts since they are UI and wouldn’t need to be loaded outside of the website? Well SharePoint tries to validate the registered web parts (reporting the results in the monitor) and configure the web parts when importing via PowerShell. These processes require loading the data, which sharepoint uses the binary serializer for, which actually creates an instance of an object. Now it doesn’t raise any control lifecycle events which would make up most of the code but it does call the parameter less constructor and initialize any fields.

So if you have any code called from the constructor that calls SPContext.Current, that doesn’t check for it to be null then and exception will occur during deserializing. This exception will also occur if you initialize any fields from SPContext.Current, which was the cause in this case with:

private SPWeb spWeb = SPContext.Current.Web;

So making that a read only property, solved that as those aren’t touched by the serializer.