Most Annoying Thing About SharePoint 2010?

I’ve been bashing my head against a SharePoint 2010 solution package for almost 10 hours now across two days.  I mean god forbid Microsoft provides us poor developers with some useful error messages or even a hint of what’s going on inside that crazy contraption.

It seems that other’s have also encountered this problem, but I’ll summarize here: in SharePoint 2007, when you create a custom list template and list definition, you could associated a custom content type with the list quite easily (or so I thought…more on this in a sec).  Here’s an example from my schema.xml file:

I can then use the content type fields in the views without having add the fields or field references separately:

In SharePoint 2010, this doesn’t work. Let me rephrase this: it doesn’t work 100% correctly.  The default behavior seems to be that the content type will be copied over, but the fields aren’t copied over

Well in fact, Microsoft’s documentation states that this is as designed:

When SharePoint Foundation creates a list instance, it includes only those columns that are declared in the base type schema of the list or in the list schema. If you reference a site content type in the list schema, and that content type references site columns that are not included in the base type schema of the list or in the list schema, those columns are not included. You must declare those columns in the list schema for SharePoint Foundation to include them on the list.

What you’ll get is the content type will indeed be on the list, but the fields won’t be copied over and any views that use those fields will be borked.  This is a really annoying problem.  Really, it is.

The solution is to either build some tool that does an XSL transform on my content types and produces the views (thereby avoiding the necessity of copying the fields over manually) or write some code to fix it after the list has deployed.  But it’s problematic because I want to deploy data with my list instance using markup like so:

I need to be able to deploy the content type to the list automatically.  (If you’re not deploying default data with your list, the ContentTypeBinding element may do the trick.)

So I fumbled around with this for a day and a half while bitching and moaning about it to anyone who would listen to me.  Did I screw up the content type somehow?  Did I screw up the list template somehow?  Did I mess up an ID somewhere?  I mean, I’ve done this a million times in the past in a million different solution packages and even in SharePoint 2010…what the heck was different about this package?

Finally (in fact, just moments ago!) it dawned on me that I’ve always “primed” my content types when deploying them in my previous solutions based on some findings from Martin Hatch!

You do not have to declare custom fields in the schema.xml, as long as you manually update your content type before creating any libraries.

Bingo!

Martin links to a code sample, but the gist of it is pretty simple.

  1. Wire up a feature receiver for your content type feature.
  2. On feature activation, “prime” the content types that have a specific group name
  3. ???
  4. Profit!

Okay, the profiting part is questionable, the the rest of it isn’t!

The first part is to wire up the feature for a feature receiver.

Note that I’ve added a feature property here: a key called “prime.if.contains”.  This allows me to specify the group names of the content types that I want to prime.  That way, I don’t have to prime all of the content types.

I create a base class for my feature receivers:

And then I add the primer class:

(Note: remove or replace the usages of ExceptionFactory — this is just a custom exception helper that I use)

You can see, the gist of it is that the code will iterate all of the content types at the site, find ones that belong in the given groups, and them prime the content type by calling SPContentType.Update(bool, bool).

So there you have it; it didn’t work in 2007 either, but I had completely forgotten that I had written the primer for this express purpose.  With this simple bit of code, you can save yourself the hassle of having to copy fields from your content type to your schema.xml definition file when creating custom list definitions for SharePoint and all of the fields are nicely copied over from your site level content type to your list instance without having to manually modify the schema.xml file for your list.

You may also like...