Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

There is a big piece of the puzzle i am missing here.

I have a list with content types enabled. I am programatically trying to add an option to some choice fields in the featureupgrading method. The fields in the field collection are updating, but the fields in list's content types are not.

Code below:

EventReciever.cs

public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, System.Collections.Generic.IDictionary<string, string> parameters)
{
    SPWeb web = (SPWeb)properties.Feature.Parent;

    switch ( upgradeActionName ) {
        case "AddChoice":
            AddChoice(web.Fields[new Guid(parameters["FieldID"])] as SPFieldMultiChoice, parameters["Choice"]);
            break;
    }
}

protected static void AddChoice(SPFieldMultiChoice field, string choice) {
    if ( field == null ) {
        throw new ArgumentNullException("field");
    }

    field.Choices.Add(choice);
    field.Update(true);
}

Template.xml

<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/">
    <UpgradeActions>
        <VersionRange BeginVersion="0.0.0.0" EndVersion="1.0.1.0">
            <CustomUpgradeAction Name="AddChoice">
                <Parameters>
                    <Parameter Name="FieldID">{82E08EC3-0C5C-4565-B0D1-740BDBE4FA93}</Parameter>
                    <Parameter Name="Choice">METT</Parameter>
                </Parameters>
            </CustomUpgradeAction>
            <CustomUpgradeAction Name="AddChoice">
                <Parameters>
                    <Parameter Name="FieldID">{1C2947AF-86EB-4DD0-95AF-D27FBA8EE3BC}</Parameter>
                    <Parameter Name="Choice">METT</Parameter>
                </Parameters>
            </CustomUpgradeAction>
            <CustomUpgradeAction Name="AddChoice">
                <Parameters>
                    <Parameter Name="FieldID">{EBA64EAA-000E-46EE-B1DE-C9761899A31B}</Parameter>
                    <Parameter Name="Choice">METT</Parameter>
                </Parameters>
            </CustomUpgradeAction>
        </VersionRange>
    </UpgradeActions>
</Feature>

Thanks for your time.

Update:

According to Derek Gusoff's comment below, i have changed my AddChoice method to the following code below. Still not working. I'm still very lost on how you are supposed to do this.

protected static void AddChoice(SPWeb web, SPFieldMultiChoice field, string choice) {
    if ( field == null ) {
        throw new ArgumentNullException("field");
    }

    field.Choices.Add(choice);
    field.Update(true);

    SPFieldLink fieldLink = new SPFieldLink(field);

    foreach ( SPList list in web.Lists ) {
        if ( !list.ContentTypesEnabled ) continue;

        bool update = false;

        foreach ( SPContentType contentType in list.ContentTypes ) {
            if ( contentType.FieldLinks[field.Id] == null ) continue;

            update = true;

            string[] order = ( from SPFieldLink f in contentType.FieldLinks select f.Name ).ToArray();

            contentType.FieldLinks.Delete(field.Id);
            contentType.FieldLinks.Add(fieldLink);
            contentType.FieldLinks.Reorder(order);

            contentType.Update(true);
        }

        if ( update ) {
            list.Update(true);
        }
    }
}
share|improve this question
add comment

2 Answers

EDIT: Last time I tried to give you an answer from memory without verifying it, and it was wrong. Sorry about that. I will not fire off a poorly-thought-out answer again. This time I created a list with two content types, both of which had a choice field named 'region'. Then in a console app I ran this code:

 SPList list = web.Lists.TryGetList("blah");
 if (list != null)
 {                   
     SPFieldChoice fld = list.Fields["region"] as SPFieldChoice;
     fld.Choices.Add("southwest");
     fld.Update();
 }

This updated the choice field in both content types on the list. I hope this is what you're after. It should run with no modifications in a feature receiver.

Also, note that this will NOT work in the sandbox. It will appear to work when stepping through the code, but the field will not update. By all accounts it should work but it does not.

share|improve this answer
    
The SPFieldLink class does not appear to have a Choices property or anything similar. How can i do this with an SPFieldLink? –  Markus May 18 '12 at 13:48
    
I guess you can't update an SPFieldLink, but you can replace it? I've tried to do that, but it doesn't look like it is working. Code posted above. –  Markus May 18 '12 at 21:02
add comment
up vote 0 down vote accepted

I figured it out. I have to manually upgrade the feature to trigger feature upgrading. Upgrading the solution by itself does not do this. The laziest way to do this is at http://spfeatureupgrade.codeplex.com/.

Once i figured this out, all i need to do to push my change to the list is call SPContentType.Update(true) on my content type. My code is as follows:

EventReciever.cs

public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, System.Collections.Generic.IDictionary<string, string> parameters)
{
    SPWeb web = (SPWeb)properties.Feature.Parent;

    switch ( upgradeActionName ) {
        case "PushFieldUpdatesToList":
            PushFieldUpdatesToList(web.Fields[new Guid(parameters["FieldID"])]);
            break;
    }
}

protected static void PushFieldUpdatesToList(SPField field) {
    if ( field == null ) {
        throw new ArgumentNullException("field");
    }

    field.Update(true);
}

Template.xml

<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/">
    <UpgradeActions>
        <VersionRange BeginVersion="0.0.0.0" EndVersion="1.0.1.0">
            <CustomUpgradeAction Name="PushFieldUpdatesToList">
                <Parameters>
                    <Parameter Name="FieldID">{82E08EC3-0C5C-4565-B0D1-740BDBE4FA93}</Parameter>
                </Parameters>
            </CustomUpgradeAction>
        </VersionRange>
    </UpgradeActions>
</Feature>

Hope this helps someone else out. It isn't exactly the most intuitive process. Thanks again for your time.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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