Declaratively provisioning a lookup column

In SharePoint development, developers are often stymied be seemingly simple tasks. Provisioning a lookup field using the declarative model in a solution package is one such task. The most common symptom of an improperly-provisioned lookup is that no error will occur on deployment, but the lookup field will have an empty reference to its parent list when viewed in List Settings. Developers will usually, and correctly, assume that the field is broken because the parent list did not exist yet when the field is provisioned. The most common way I have seen developers address this is to use a Feature Receiver to provision their lookups after declaratively provisioning everything else because they cannot figure out a way to make the declarative approach work.

Today on Stack Exchange I saw another question on this topic, and I felt compelled to write this post to clarify the issue.

The trick to doing this right is understanding that the order in which the package deploys the artifacts is important. Look at the image below, which shows a fairly representative simple data model for a SharePoint solution. The screen shot is from VS2102/SP2013, but it works exactly the same in 2010.

package

It shows fields, content types, and lists, deployed in that order. Now, the Projects list has a lookup to the Clients list. If I put that lookup in the SiteColumns element, it will fail, because it will have been provisioned in the wrong order. The practice I have developed to make this work is to put the Field element for the lookup directly under the ListInstance element it depends on. By doing this there is no possibility the lookup will be provisioned out of order, because SharePoint will deploy the stuff in an individual elements file in the order it appears in the file:

elements

Now, when I provision my related lists, everything is properly hooked up, and I didn’t have to write any code to do it.

…and by the way, I discovered this trick by taking a saved site template and opening it up using the “Import a Solution Package” project type in Visual Studio 2010 (you can learn a LOT about SharePoint’s provisioning process by doing this, by the way). And this approach works exactly the same in 2010 and 2013 (and, I would suspect, in 2007 as well).

11 thoughts on “Declaratively provisioning a lookup column

  1. hmm, while I agree that you can learn “how” on many things by examining exported .wsp’s, it also becomes apparent that exported .wps’s have a lot junk and do not follow standard best practices — and this is case in point: It is certainly not best practice to provision two disparate items in the same elements file, and even if that were acceptable, I don’t think any solution architect would ever recommend provisioning a ListInstance in a site-scoped feature or provisioning a SiteColumn (Field) in a web-scoped feature, and at least one of those rules would have to be broken for this to be successful.

    Like

    • I agree with you on all the points you made. One should certainly never just copy the stuff in the WSP due to all the just that gets exported into it. You also make a very good point about site columns and List Instances in the same elements file. I am willing to break that rule, however, for lookup columns, since they are intrinsically tied to a list instance in a web.

      Like

      • I should also point out that in the time since I wrote this article I’ve completely soured on declarative provisioning altogether. The non-trivial aspects of the process (like lookup columns, for example) are poorly documented and sometimes impossible to debug. With code or PowerShell you have complete control and visibility over the provisioning process, and that’s how I deploy site structure nowadays.

        Like

    • @bogdan, are by any chance deploying this to a subsite? What is the scope of your feature? As noted in Eric’s comments above there may be some cases where this approach doesn’t work.

      Like

  2. It was in a site collection feature. My situation was a little bit different and in the end I got it working with a little bit of moving items around between features.

    Anyway, It’s working now and all’s good. Thanks for taking time to reply :)

    Like

  3. Q) Problem with redeployment of List Definitions/Instances after creating new lookup field in visual studio 2013 —

    I created list definition in Visual studio 2013, once after the deployment and succcessful creation of the list, I have updated the listdefintion by creating new field “Lookup”, and redeployed. But surprisingly after the redeployment lookup is not displaying and tried with the remaining fields like, choice, calender etc..they are working. But problem is with only the new field “lookup”. Anyhelp would be greatly appreciated.

    Like

    • You need to provision the element after the parent list is created. Look in your package file to see the order in which your elements are deployed. You might want to put the field in a separate elements file to ensure the deployment order. Think about it: at the time the lookup field is created, does the parent list exist? If not, the field will not work properly.

      Also, when doing subsequent deployments of declarative solutions, you are going to have stuff from old deployments messing with your new stuff. You are better off completely deleting and recreating your development site between deployments.

      Like

      • Thank you Derek for response, the parent list for the lookup has been already created before the redeployment and I will make sure the deployment order of the elements as you mentioned and if any problem persists will get back.

        Like

Leave a comment