Monthly Archives: February 2010

Cannot change the lookup list of the lookup field.

Ever get this error message

SPException “Cannot change the lookup list of the lookup field.”

Once a lookup field (SPFieldLookup) has had it’s LookupList and LookupWebId set you can’t change them.

There is a good reason for this if your lookup field is used in multiple lists or already has data entered, you would effectively break the referential integrity of the data. So what I’m showing here as a work-around to this error message should only be used if you are *sure* no lists reference the lookup column or no lists have any data using this column

Okay with the health warning out of the way the work-around is simply to update the Schema property to overwrite the intervalues for List & WebId

I created a handy extension method for dealing with the string manipulation:

Usage:

SPFieldLookup field = (SPFieldLookup)site.RootWeb.Fields[MyId];
field.UpdateLookupReferences(newWeb, newList);

Implementation:

public static class SPFieldLookupExtensions
{
    public static void UpdateLookupReferences(this SPFieldLookup lookupField, SPWeb web, SPList list)
    {
        if (string.IsNullOrEmpty(lookupField.LookupList))
        {
            lookupField.LookupWebId = web.ID;
            lookupField.LookupList = list.ID.ToString();
        }
        else
        {
            lookupField.SchemaXml =
                lookupField.SchemaXml
                    .ReplaceXmlAttributeValue("List", list.ID.ToString())
                    .ReplaceXmlAttributeValue("WebId", web.ID.ToString());
        }

        lookupField.Update(true);
    }
}

public static string ReplaceXmlAttributeValue(this string xml, string attributeName, string value)
{
    if (string.IsNullOrEmpty(xml))
    {
        throw new ArgumentNullException("xml");
    }

    if (string.IsNullOrEmpty(value))
    {
        throw new ArgumentNullException("value");
    }


    int indexOfAttributeName = xml.IndexOf(attributeName, StringComparison.CurrentCultureIgnoreCase);
    if (indexOfAttributeName == -1)
    {
        throw new ArgumentOutOfRangeException("attributeName", string.Format("Attribute {0} not found in source xml", attributeName));
    }

    int indexOfAttibuteValueBegin = xml.IndexOf('"', indexOfAttributeName);
    int indexOfAttributeValueEnd = xml.IndexOf('"', indexOfAttibuteValueBegin + 1);

    return xml.Substring(0, indexOfAttibuteValueBegin + 1) + value + xml.Substring(indexOfAttributeValueEnd);
}
Tagged ,