Geeks With Blogs
Adrian Hara Working through the .NET maze
The following gotcha was a pretty nasty one for me (I'd say about 2 hours of lost time worth). Supposing you have some content types deployed at the site collection level and you want to add them to a document library of a sub-site (web) plus configure them a little bit, like so:

            foreach (string contentTypeName in ToAttachToListContentTypeNames)
            {
                // Get site collection content type
                SPContentType siteContentType = web.AvailableContentTypes[contentTypeName];

                // Add to library and configure
                SPContentType libraryContentType = library.ContentTypes.Add(siteContentType);
                libraryContentType.DocumentTemplate = string.Empty;
                libraryContentType.Update(false);

               // Maybe some more work, like adding some linked fields here?...
            }

This turned out to result in some weird behavior: supposing I had 3 content types to add to the document library, the first one of them (which would also be the first one added) always got some of its properties wrong. For example, even though the code sets the DocumentTemplate explicitly to string.Empty, the resulting document library content type (the first one added) would always get the "template.doc" template instead. Weird stuff happened also to some linked fields I was adding, like the first content type would always get one linked field less than the others

Now, unfortunately (or fortunately?) I didn't have the time to Reflect over the sharepoint code to see why this happens, but after some trial-and-errors I found that it seems the call to "library.ContentTypes" somehow merges the "web.AvailableContentTypes" with the library's content types. Since this call is done in the foreach loop, it means that, for each subsequent loop step, some settings for the content types added in prior steps are "merged" (read overwritten) with the ones of the site collection content types. What's weird is that:
1. It only seemed to happen for the first added content type (so the first step in the loop). The other two were fine.
2. It only "merged" some of its properties, like DocumentTemplate and *some* field links, not all

Anyway, the fix is to take the call to "library.ContentTypes" out of the loop and assign to a variable. Then you can just iterate over that "local" collection and do stuff:

            SPContentTypeCollection availableContentTypes = web.AvailableContentTypes;
            foreach (string contentTypeName in ToAttachContentTypeNames)
            {
                // Get site collection content type
                SPContentType siteContentType = availableContentTypes[contentTypeName];

                // Add to library and configure
                SPContentType libraryContentType = library.ContentTypes.Add(siteContentType);
                libraryContentType.DocumentTemplate = string.Empty;
                libraryContentType.Update(false);
            }
            library.Update();

            // Add some fieldlinks to the library content types
            SPContentTypeCollection libraryContentTypes = library.ContentTypes;
            foreach (string contentTypeName in ToExtendWithFieldLinksContentTypes)
            {
                SPContentType libraryContentType = libraryContentTypes[contentTypeName];

                SPFieldLink someFieldLink = new SPFieldLink(web.Fields["some field"]);
                libraryContentType.FieldLinks.Add(someFieldLink );

                // Maybe add some more...
              
                libraryContentType.Update(false);
            }

This seems to work, but granted, is strange enough to do... Posted on Wednesday, July 16, 2008 5:16 PM Sharepoint Gotchas | Back to top


Comments on this post: Sharepoint 2007 - List vs. inherited content types gotcha

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © Adrian Hara | Powered by: GeeksWithBlogs.net