Question

I have a custom content type, and a custom list definition based on that content type.

I am adding two new fields to the content type in a feature upgrade. Adding the new fields to the content type and pushing that down to existing lists works just fine. However, the new fields end up with null values on existing list items, so I am trying to update all existing list items of my custom content type with some default values.

Here is my code from my feature upgrade custom action:

SPSite site = properties.Feature.Parent as SPSite;

SPContentTypeId myCTypeID = new SPContentTypeId("0x01-content-type-id-here");
SPContentType myContentType = site.RootWeb.ContentTypes[myCTypeID];

Guid choiceFieldId = site.RootWeb.Fields.GetFieldByInternalName("FieldOne").Id; // a choice field
Guid booleanFieldId = site.RootWeb.Fields.GetFieldByInternalName("FieldTwo").Id; // a boolean field

IList<SPContentTypeUsage> usages = SPContentTypeUsage.GetUsages(myContentType);
foreach(var usage in usages)
{
    if (usage.IsUrlToList)
    {
        using (SPWeb web = site.OpenWeb(usage.Url, false))
        {
            SPList myList = web.GetList(usage.Url);
            // loop through items by index instead of foreach to avoid the "collection was modified" error
            for (var i = 0; i < myList.ItemCount; i++)
            {
                myList.Items[i][choiceFieldId] = "Default Choice Value";
                myList.Items[i][booleanFieldId] = true;
                // there is an "ItemUpdated" event receiver that I would like to avoid running
                using (DisabledEventFiringScope scope = new DisabledEventFiringScope())
                {
                    // use SystemUpdate(false) to keep existing Modified, ModifiedBy and version values
                    myList.Items[i].SystemUpdate(false);
                }
            }
        }
    }
}

If I step through the code during the upgrade process, it seems to work, the right lists are found, and the right number of items are looped through, and the code throws no errors.

However, the values for those fields don't stick. If I go back in and look at those list items, the fields still have null values.

Why won't my updates stick?

Was it helpful?

Solution

Interesting. It had to do with how I was accessing the SPListItem objects. I needed to explicitly get myList.Items[i] as an SPListItem.

Once I changed the inner part of the for loop to be

// loop through items by index instead of foreach to avoid the "collection was modified" error
for (var i = 0; i < myList.ItemCount; i++)
{
    SPListItem item = myList.Items[i];
    item[choiceFieldId] = "Default Choice Value";
    item[booleanFieldId] = true;
    // there is an "ItemUpdated" event receiver that I would like to avoid running
    using (DisabledEventFiringScope scope = new DisabledEventFiringScope())
    {
        // use SystemUpdate(false) to keep existing Modified, ModifiedBy and version values
        item.SystemUpdate(false);
    }
}

then the updates stuck as expected.

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top