Using GetContentTypes with the Webs Web Service
I’ve been working on updating our SharePoint Utilities with support for Site Columns and Content Types in SharePoint 2007. Ideally, I would like the tool to have the ability to create site columns and content types on the fly it it sees them in the list structure and they don’t already exist on the site.
Because these utilities run as WinForms apps, I use the SharePoint web services to access the list objects, get their properties, then do the creation tasks. While updating the code, I noticed a discrepancy in the functionality of the GetContentTypes method of the Webs web service with what is described in the SDK. The SDK says this method should return XML in the following format:
<ContentTypes xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<ContentType
ID="0x010100C78DE4D7C0C57C43AF878D28256599CA"
Name="NewContentType"
Group="Custom Content Types"
Description="Create a new document."
Version="1"
xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<Folder TargetName="Forms/NewContentType" />
<Fields>
…
<DocumentTemplate TargetName="Forms/NewContentType/template.doc" />
<XmlDocuments>
…
</XmlDocuments>
</ContentType>
<ContentType
…
</ContentType>
</ContentTypes>
<ContentType
ID="0x010100C78DE4D7C0C57C43AF878D28256599CA"
Name="NewContentType"
Group="Custom Content Types"
Description="Create a new document."
Version="1"
xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<Folder TargetName="Forms/NewContentType" />
<Fields>
…
<DocumentTemplate TargetName="Forms/NewContentType/template.doc" />
<XmlDocuments>
…
</XmlDocuments>
</ContentType>
<ContentType
…
</ContentType>
</ContentTypes>
The important thing in this XML is the <Fields> element, which would could be used to fetch the site columns and automatically create the content types. Trouble is, this is what you actually get from the GetContentTypes() method:
<ContentTypes xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<ContentType Name="System" ID="0x" Description="" Group="_Hidden" NewDocumentControl="" Scope="http://test.binarywave.com" Version="0" RequireClientRenderingOnNew="TRUE" />
<ContentType Name="Common Indicator Columns" ID="0x00A7470EADF4194E2E9ED1031B61DA0884" Description="" Group="_Hidden" NewDocumentControl="" Scope="http://test.binarywave.com" Version="0" RequireClientRenderingOnNew="TRUE" />
…
</ContentTypes>
…
</ContentTypes>
.
Um, ok, where did all the rest of the data go? What happened to <Folder />, <Fields />, and <DocumentTemplate />? Something ain’t right here – lots of stuff missing from what the SDK says should be there. Consequently, the code just got WAY more complex as now I have to loop through the returned types, fetch each one individually, get it’s properties using GetContentType() (which requires the content type ID), then pass each content type to a helper method to check if it already exists and create it.
Grrr…some days you just can’t win…
Just read your post and wanted to mention my webs web service follies. I’ve been doing similar work adding Content Types and Site Columns using the Webs web service and learned a hard lesson: It’s possible to submit an invalid field definition via Webs.UpdateColumns and cripple your site (you can no longer access the Site Columns page, create a new site based on the Publishing template, modify properties on a Content Query web part, or add, modify, or delete any site columns). What happened was I submitted a definition that did not contain a Type attribute. I haven’t found a solution yet, but am working with Microsoft to do so.
Just read your post and wanted to mention my webs web service follies. I’ve been doing similar work adding Content Types and Site Columns using the Webs web service and learned a hard lesson: It’s possible to submit an invalid field definition via Webs.UpdateColumns and cripple your site (you can no longer access the Site Columns page, create a new site based on the Publishing template, modify properties on a Content Query web part, or add, modify, or delete any site columns). What happened was I submitted a definition that did not contain a Type attribute. I haven’t found a solution yet, but am working with Microsoft to do so.