Thursday, November 4, 2010

SharePoint custom field definition considerations

When defining custom fields in XML for SharePoint, the element has numerous attributes and most of them are optional. It's important to think through.

I recently came across some fields defined with Sealed="TRUE". This attribute prevents the deletion of the column from a list once it's added (either added directly or by adding a content type that has this field). It's a good idea to enforce metadata consistency this way. However, what if a user mistakenly add a content type that has this field to a list, and then want to remove it? Well, there's no way unless writing a utility to delete it from the list using the API:

int fieldCount = l.Fields.Count;
for (int i = fieldCount - 1; i > -1; i--)
{
SPField f = l.Fields[i];
if (f.Group == "MyGroup") //or other criteria
{
Console.WriteLine(f.StaticName + " " + f.AllowDeletion.ToString());
f.AllowDeletion = true;
f.Sealed = true;
f.Delete();
}
}
l.Update();


There is also the attribute of AllowDeletion. Interestingly, If AllowDeletion="TRUE" and Sealed="TRUE", the column can be deleted. AllowDeletion appears to have precedence. Need to do some research to figure out the exact differences between the two.

SharePoint 2010 Custom Content Types and Fields Gotchas

If you have existing custom fields and custom content types that were created and deployed to MOSS 2007 successfully, and now you want to deploy them into SharePoint 2010, there may be a few things that'll surprise you. I went through a lot of pains to get it done successfully and the following is maybe a subset of all the gotchas out there.

Custom fields and content types are typically deployed in a wsp package and then activated via feature. Theoretically there should not be a problem to take such a wsp and deploy directly into SP 2010. However, there are some small changes (and bugs also?) in how SP 2010 handles fields and content types. The following were experienced on SP 2010 with August 2010 CU.
  1. Your content type xml definition contains comments between the tag, which you often do, as it's a good practice to explain what the fields included are and where they comes from. Then after a successful deployment, the Manage Content Type page shows none of the fields included in for the content type (Site Actions -> Site Settings -> Site Content types -> (select the content type, _layouts/ManageContentType.aspx). Looks to me like the code that reads the xml definition doesn't exclude comments node. Huh, Microsoft?

  2. Overwrite attribute. This behaves differently now, as detailed in this blog. Bottomline is, set this to try in development. Otherwise you can't deploy and then activate the feature with updated XMLs if a previous deployment failed and left phantom pieces in the farm.

  3. Inherits attribute. By default in SP 2010 a custom content type only has the fields defined in its node, unless Inherits="TRUE". This is a change of the default behavior from WSS 3.0.

  4. SourceID attribute. This specifies the schema http://schemas.microsoft.com/sharepoint/v3. Not sure what I was thinking, maybe just wanted to be cool, I changed this to http://schemas.microsoft.com/sharepoint/v4. And it caused some weird errors logged (Can't find the XML schema definition or something?). I definitely need to read up on what the differences between the two schemas. It appears that the majority of the schema definitions that SP 2010 uses is still in v3. So leave the SourceID value as v3.
I still have not quite figured out how to completely clean up a failed deployment or retraction, which may leave behind field defs or content type defs that are nowhere to be found in the UI, database tables, and API (SPWeb.Fields, SPWeb.ContentTypes), but nontheless lurks around and prevent activating the updated feature (Log shows exception that the ID already exists, or can't overwrite etc). People suggests to change the GUIDs of the feature, fields, or content types to get around the issue but it's not always practical.