5

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?

  • did you try Web.Update() or AllowUnsafeUpdates = true? – Michael Colbs Apr 26 '17 at 18:53
  • No, but I'm not sure either one of them is relevant. Web.Update() will update the SPWeb object, and I need to update SPListItem objects. And AllowUnsafeUpdates is to allow updating of items in a GET request, but this is all getting triggered by calling SPFeature.Upgrade() from a Powershell script, so there is no HTTPContext involved. (Is there?) That all being said, I suppose it wouldn't hurt to try... – Dylan Cristy Apr 26 '17 at 19:11
  • can you iterate over listitemcollection ? Somewhat like SPListItemCollection items = list.Items; foreach(SPListItem in items) and check ? – Gautam Sheth Apr 27 '17 at 4:26
2

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.

  • Very strange. Your solution worked for me too. Anyone with extra time to elaborate why is this happening? – Slaven Semper Mar 20 '18 at 7:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.