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

I add lookup columns with a elements.xml file and like everyone else I had issues with them once deployed, i.e. "Get information from:" was empty for the lookup list. I found www.n8d.at/blog/lookup-fields-as-site-column-declarative-deployed/ which solved the issue for the root site. A content type contains my custom site columns and when I create a subsite, add this content type to a library and check the lookup columns on this library they are empty. If I go to library settings and add "from existing columns" and add one of the lookup columns and give it a different name it's empty. If I go to the root site and create a new lookup column through the GUI, go to the subsite and add it to the library the column works fine.

So what am I missing here when it comes to subsites?

In a feature receiver I have the following code:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{ 
    SPSite targetSite = properties.Feature.Parent as SPSite;
        using (SPSite site = new SPSite(targetSite.ID))
        {
            using (SPWeb web = site.OpenWeb())
                {
                SPField invoiceStatusField = web.Fields.TryGetFieldByStaticName("InvoiceStatus");

                    if (invoiceStatusField != null)
                        Utility.SetLookupColumnList(invoiceStatusField, web);
                }
        }
}

public static void SetLookupColumnList(SPField field, SPWeb web)
{
    XDocument fieldSchema = XDocument.Parse(field.SchemaXml);
    XElement root = fieldSchema.Root;

    if (root.Attribute("List") != null)
    {
        string listurl = root.Attribute("List").Value;
        SPFolder listFolder = web.GetFolder(listurl);

        if (listFolder != null && listFolder.Exists == true)
        {
            XAttribute attrList = root.Attribute("List");
            if (attrList != null)
            {
                attrList.Value = listFolder.ParentListId.ToString();
            }

            XAttribute attrWeb = root.Attribute("SourceID");
            if (attrWeb != null)
            {
                attrWeb.Value = web.ID.ToString();
            }

            field.SchemaXml = fieldSchema.ToString();
        }
    }
}

When I add an item to a list in the root site I create a new library (event receiver) in a subsite and assign it the invoice content type

SPContentType invoiceCt = rootWeb.AvailableContentTypes["Invoice"];

if (invoiceCt != null)
 pagesLibrary.ContentTypes.Add(invoiceCt);

The content type gets added but as I previously mentioned the lookup columns have "Get information from:" empty.

Any ideas?

Thanks in advance.

To repeat steps. Deploy site columns, content type, in root site lookup columns works. Create subsite, assign content type to new library - lookup columns doesn't work.

Edit: after I created a new site column and added it to the list and checked the xml schema for the list I saw that the new column has a web id but the one in my content type doesn't. Also my column doesn't have list GUID wrapped in {} but the new column does (the GUID is however the same). SourceID is also different.

share|improve this question
    
Have you tried to use my code in a web scoped feature and changed the feature activate? –  Stefan Bauer Feb 19 '13 at 23:17
    
Yeah I had no luck, for some reason if (listFolder != null && listFolder.Exists == true) is always false –  Peter Mar 19 '13 at 1:08
add comment

1 Answer 1

up vote 1 down vote accepted

I had this problem as well, and I'd also used Stephen's code to fix up the lookup site columns at the root web level. I figured that it must be something to do with not referencing the web correctly, so I created a site lookup column manually and checked that that worked in a sub-site - which it did. So I looked at the schema for the column that worked and found a couple of differences.

  1. There is an attribute "WebId" which isn't included in Stephen's code
  2. The "SourceID" attribute was surrounded by braces
  3. The "List" attribute was surrounded by braces

Curiously, the missing "WebId" attribute wasn't surrounded by braces. The modified code looks like this (which seems to work in sub-sites by the way):

    private static void FixSPLookupField(SPWeb web, SPField lookupField)
    {
        // Getting Schema of field
        XDocument fieldSchema = XDocument.Parse(lookupField.SchemaXml);

        // Get the root element of the field definition
        XElement root = fieldSchema.Root;

        // Check if list definition exits exists
        if (root.Attribute("List") != null)
        {
            // Getting value of list url
            string listurl = root.Attribute("List").Value;

            Guid myGuid = new Guid();
            // Get the correct folder for the list
            SPFolder listFolder = web.GetFolder(listurl);
            if (listFolder.Exists)
            {
                myGuid = listFolder.ParentListId;
            }


            if (listFolder != null)
            {
                // Setting the list id of the schema
                XAttribute attrList = root.Attribute("List");
                if (attrList != null)
                {
                    // Replace the url with the id
                    attrList.Value = "{" + myGuid.ToString().TrimStart('{').TrimEnd('}') + "}";
                }

                // Setting the source id of the schema
                XAttribute attrWeb = root.Attribute("SourceID");
                if (attrWeb != null)
                {
                    // Replace the sourceid with the correct webid
                    attrWeb.Value = "{" + web.ID.ToString().TrimStart('{').TrimEnd('}') + "}";
                }

                //Add the "WebId" attribute if not already present
                XAttribute attrWebId = root.Attribute("WebId");
                if (attrWebId == null)
                {
                    attrWebId = new XAttribute("WebId", web.ID.ToString().TrimStart('{').TrimEnd('}'));
                    root.Add(attrWebId);
                }
                else
                {
                    attrWebId.Value = web.ID.ToString().TrimStart('{').TrimEnd('}');
                }

                // Update field with new schema
                lookupField.SchemaXml = fieldSchema.ToString();
            }
        }
    }

Hope this helps.

share|improve this answer
1  
Thanks, I was going down this path myself but now I don't have to as your code solves the issue –  Peter Mar 21 '13 at 1:29
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.