Navigation

Thursday, 9 October 2008

SDK and Microsoft Press Both Wrong?? Custom Fields in the schema.xml

Ok, so I think I've found something here. It relates specifically to Site Columns and Content Types, and how they can be applied to Custom List Definitions.

According to the latest release of the WSS 3.0 SDK (August 2008?) and one of the "bible" textbooks for WSS 3.0 development (Inside WSS 3.0 - Ted Pattison & Daniel Larson - Microsoft Press) there are a couple of questionable "best practice" methods that I wanted some insight on.

Personally, I think I've found quite a big oversight, which could be causing problems all over the shop.

The Big Issue (not the magazine!)
The question is around building a custom List Definition, in which you want to implement a custom Content Type (with custom Site Columns).

Now, both the SDK and the Inside WSS 3.0 book (along with many many other references I've seen, including people) state that if you have custom fields in your content type, then you have to add them to the Schema XML.

This has always struck me as very odd. I mean, you have to add all of that information already to your Site Columns (fields) feature .. right? So aren't you just copy-pasting the same info?

Also, if you try to do this through the user interface, SharePoint will automatically add all of the columns from the content type when you add it to the list ... so why can't it do that through CAML too ??

Well, I wasn't happy about this, and decided to try things a different way.

The Big Experiment (not the Discovery Channel)
I wanted to try and make a set of features that proved these statements wrong:
  • Site Column Feature (which declares a single, custom text field)
  • Content Type Feature (which declares a single Content Type, inheriting from Document, and includes my site column as a Field Reference)
  • Document Library Feature (declares a new custom document library definition. The only change is the Content Type and switching on "management of content types". The custom field is NOT added to the Fields section in the schema.xml)

TAKE 1 - As expected
I finished my CAML, installed my features and activated them in a completely new vanilla Site Collection.
My site column and content type both appeared on activation (as expected) and my new library definition popped up in the create menu (also as expected).

I then created my Document Library ... and ... <anti><climax>my columns did not appear in the library</climax></anti>.

This was, for the cynics among you, entirely expected. Microsoft themselves (through the holy scriptures of the SDK) have stated that this would happen.

But then things got interesting ...

TAKE 2 - The interesting result
Ok I thought ... what is going on behind the scenes? Somehow I need my Content Type to take preference over the schema...

I had a bit of a think (and probably scratched my chin a few times).. eventually I hit upon an idea (don't ask me how .. one of those late night coffee moments!)

I reset my environment (brand new, clean site collection) and re-installed and re-activated my features.

BUT .. this time, BEFORE I created any libraries I went to the Content Type Gallery and looked at my Content Type.
I clicked on my custom field (in the content type itself) and changed one of the values (I actually changed it into a required field) and hit the OK Button (note - the "push changes down to child content types" WAS selected).

I then backed out of those screens, and created my Document Library... and ... <surprise>my custom columns DID APPEAR!!</surprise>!

This was quite a shock .. I mean .. the Fields section in my custom document library schema is empty (apart from the fields that come out of the box).

I checked the library settings, tried uploading a file, and even checked the Document Information Panel in Word 2007. My custom field was there, with all the correct metadata.

Conclusion - (the important bit .. for those who bothered to scroll down)

My conclusion:

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.

But that's not practical ... I have <insert huge number>'s of content types!
Well .. I hear ya.

I have just finished off a custom Feature Receiver which can be attached to any Content Type Feature as a Receiver Assembly / Receiver Class.

The code will (when the feature is activated) locate all of the Content Type elements in the feature, and do an initial "Update - push down changes" when the content types are first activated. (UPDATE code as been published to my Blog. See this article for details).

This is effectively the "magic bullet" I was looking for, and with this:

  • Custom Fields do not have to be declared in the schema.xml
  • Custom Fields can still be referenced in views, even though they are not referenced as Fields.
  • All column and meta data management can be developed in the Content Types and Site Columns

Comments / Discussions / <not>Flames</not> ...

all are welcome :)



4 comments:

  1. The only flames are the ones coming out my ears at the weeks of frustration I've spent doing this the 'right' way.

    Thank you, thank you, thank you (for the receiver code especially!). You are legend.

    ReplyDelete
  2. I found this very helpful. I have been search for over two weeks for a way to group using newly created custom fields (in particular check box fields). Although this hasnt provided me with an exact answer it has me towards a better path. Thanks for posting your finds . . .

    Maria

    ReplyDelete
  3. Wow, this is excellent. Have you tried this method with calculated site columns? I'm not having any luck with those.

    Thanks again.

    ReplyDelete
  4. Calculated Site Columns are always going to be a problem, because column calculation relies on relative columns to the current list.

    Theoretically this should work, but you will need to very closely manage the content types that those columns are used in to make sure that one of the fields used in the calculation isn't removed or modified.

    ReplyDelete

This blog has been moved to www.martinhatch.com

Note: only a member of this blog may post a comment.