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.

Tuesday, October 26, 2010

SP 2010 SPSite FileNotFoundException

SPSite site = new SPSite("http://domainname/sites/sc");

is a frequently used statement to open a site collection on a SP server, particularly from a separate application (Console App, ASP.NET app) to look inside the SharePoint. A frequently encountered problem is that it throws a FileNotFoundException:

"The Web application at http://domainname/sites/sc could not be found. Verify that you have typed the URL correctly. "

Of course the URL is correct. In a SP 2010 dev environment, you'll almost inevitably run into this the first time. What the problem is, SP 2010 is 64 bit only. And by default, Visual Studio compiles your Console, WinForm, Asp.Net projects in 32 bit. So you need to change it: Go to the project Properties -> Build -> Platform target, change to either either x64 or Any CPU. Build again, and the error goes away.

MOSS 2007 64 bit would cause this problem too but since developers often install 32 bit for dev purpose, it's encountered less frequently.

Monday, October 25, 2010

Failed to create field: Field type myfield is not installed properly

You have seen this error in MOSS 2007 and it's the same in SP 2010:

"Failed to create field: Field type is not installed properly. Go to the list settings page to delete this field."

This can happen when you activate or deactivate a feature that includes this field. The message is not helpful. There are plenty of discussions about this and apparently a gazillion scenarios that this could occur. In my case, it's because myfield is a custom field inherited from SPFieldMultiColumn. And I didn't include the class (and the assembly) in the deployment. Hence when it goes to create or delete the field, there's nothing other than the metadata in the XML field definition.

So at least one scenario cleared up.