Archive

Archive for January, 2015

Refreshing SPWeb object during enumeration

This arose for me during a PowerShell script, when I had to enumerate each web, add a field to the content types used by a particular SharePoint List in each web, and then query the list items to set the values for that newly added column.

Updating the content types (including child types) was fine, however since I had already accessed the List’s content types to find the root types, the changes made weren’t reflected in memory within the List object. Attempts to update the list items for the newly added field failed with an error that they don’t exist or may have been deleted, even if I queried the new field specifically.

Getting the List again didn’t seem to help, and calling Update on the List threw a save conflict (possibly because the List’s instance of the content types had just been updated by the hierarchical save from the parent content type).

I didn’t want to just reopen the web since I was enumerating them and that would have required alot of messy code to track where I was and use more memory doubling up the references to the web (every little bit matters).

Unfortunately SharePoint doesn’t provide a way to “refresh” the in memory objects, I guess since they usually have very short life spans.

It does however provide a Close method, but no open method. Well after a bit of decompiling I found that there are a handful of properties that will trigger the same internal initialization as opening the web the first time. I decided to try the one with the smallest footprint, Exists.

So with the code (PowerShell, but would be same in C#, etc):

$spWeb.Close()
$exists = $spWeb.Exists

I was able to make some heavy changes, then Close and reopen the web (via Exists), and run some queries and updates, all without mucking up the web enumeration (for each loop in this case).

Essentially, a SPWeb re-open procedure maintaining the same SPWeb object referenced in memory.