Adding a lookup field to your SharePoint solution: declaratively or programmatically?

Big thanks to Chris Barbin on pointing me in the right direction for this one!

Including a lookup in your project can be tricky, and I find that most developers revert to doing it programmatically instead of declaratively. It’s easier to copy and paste some C# code than chase down issues around CAML. It can be incredibly aggravating and time consuming chasing down these little annoyances with SharePoint. Anywoo, I really wanted to make sure my project did it the right way, and with Chris’s help, I was successful!

Why bother trying declaratively?

Using SharePoint’s CAML/XML, the field is easier managed, SharePoint has to think a little less as it just reads and parses an XML file, which, if you explore the hive you’ll see virtually EVERYTHING is setup that way. Also, in SharePoint 2013, sandbox solutions only support declarative customizations, it’s true, no more codeSoooo I think SharePoint has made it rather clear, and creating it correctly now will get you in the right mindset as well as help when upgrading into SharePoint 2013.

As a quick disclaimer: obviously, if you’re not defining your list and you need to add a lookup to an existing list, it’s going to be easiest to add it to the existing list programatically. I don’t think it’s possible delcaratively.

For my scenario, let’s add 2 new lookup columns to a document library, so we can use SPServices for cascading some categories.

Doing this programmatically would look something like:


SPList SharedDocumentslist = web.Lists.TryGetList("Shared Documents");

SPList categoryList = web.Lists.TryGetList("Categories");
 SPFieldLookup categoryField = (SPFieldLookup)SharedDocumentslist
    .Fields.CreateNewField(SPFieldType.Lookup.ToString(), "Category");
 categoryField.LookupList = categoryList.ID.ToString("B");
 categoryField.LookupField = "Title";
 SharedDocumentslist.Fields.AddFieldAsXml(categoryField.SchemaXml,
    true, SPAddFieldOptions.AddToAllContentTypes);

SPList subCategoryList = web.Lists.TryGetList("Sub Categories");
 SPFieldLookup subCategoryField = (SPFieldLookup)SharedDocumentslist
    .Fields.CreateNewField(SPFieldType.Lookup.ToString(), "SubCategory");
 subCategoryField.LookupList = subCategoryList.ID.ToString("B");
 subCategoryField.LookupField = "Title";
 SharedDocumentslist.Fields.AddFieldAsXml(subCategoryField.SchemaXml,
    true, SPAddFieldOptions.AddToAllContentTypes);

SharedDocumentslist.Update();

Meh, 15+lines of code (you better have some error handling, and the trigger to run this code, so you’re probably looking at close to 40+ lines and a few different files). That’s a lot of overhead for something that can be done in a couple of lines declaratively. Check this out:

In my library’s list schema, I want to add two field tags, to the <Fields element:

&lt;Field ID=&quot;{dbd44429-8804-458d-b86f-122141fb1070}&quot;
Name=&quot;MyCategory&quot;
StaticName=&quot;MyCategory&quot;
DisplayName=&quot;Category&quot;
Type=&quot;Lookup&quot;
Required=&quot;TRUE&quot;
List=&quot;Lists/Categories&quot;
ShowField=&quot;Title&quot;/&gt;
&lt;Field ID=&quot;{8C8CD65E-F2BB-45B7-8835-CC2BF97C9D5E}&quot;
Type=&quot;Lookup&quot;
Name=&quot;MySubCategory&quot;
DisplayName=&quot;SubCategory&quot;
StaticName=&quot;MySubCategory&quot;
Required=&quot;TRUE&quot;
List=&quot;Lists/Sub Categories&quot;
ShowField=&quot;Title&quot; /&gt;

Easy enough right? 2 lines (I know above shows many more, but it can be formatted for 2 lines ;) of manageable XML vs 40+ lines of C# code… tell me which one is best.

Big Note: These field elements are added to the list’s schema, these are not site columns. Something goes terribly awry making these site columns first. I’ve read others making them site columns and then using some code to handle it at the list. If you require site columns for content aggregation go for it. If I’m missing something and you can get this to work with site columns, please share!

Til next time, Happy SharePointing!

Leave a Reply

Up ↑

%d bloggers like this: