Wednesday, February 21, 2007

Delete a contenttype from a document library

You can find a lot of information about how to add a contenttype (SPContentType) to a list or document library (SPDocumentLibrary). But how do you delete a contenttype from a document library?

From the administration UI you can remove a contenttype by selecting "Delete this content type" as outlined here:

But how do you do it programmatically?`

If you take a look at SPDocumentLibrary it has a reference to ContentTypes. The collection has a delete operation which takes a GUID of the content type as parameter, as outlined by Microsoft here.

dim oDocLib as SPDocumentLibrary
dim oCT as SPContentType
oCT = oDocLib.ContentTypes("Documents")
oDocLib.ContentTypes.Delete(oCT.Id)

Trying out this code raises an exception:

System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: id
at Microsoft.SharePoint.SPContentTypeCollection.Delete(SPContentTypeId id)

Inputs very much appreciated.

I got the idea to try using the Lists.asmx web service as described here by Microsoft. No luck so far.

You can get around the issue as described here. Set the content type programmatically before you add the items - but that is not really the answer long term :-(

Conclusion: Now it works!!!
I tried to delete the Documents content type found in the web collection AvailableContentType i.e. executing the code:

dim oWeb as SPWeb
dim oDocLib as SPDocumentLibrary
dim oCT as SPContentType
oCT = oWeb.AvailableContentTypes("Documents")
oDocLib.ContentTypes.Delete(oCT.Id)

this fails as described above.

The above code works.

Tuesday, February 20, 2007

Changing default content type in a Document Library

When adding several content types to a document library (SPDocumentLibrary) I would like to decide which content type is the default type, and also in which sequence they occur, i.e. in the New Document interface.

I have searched but couldn't find any information about how to modify the default content type and the sequence of content types in a document library. I found this blog saying it cannot be done.

Conclusion: It is possible - just read this blog.

Sunday, February 18, 2007

SPItemEventReceiver - Mapping end-user events to SharePoint events

How do you map the end-user events with the various SharePoint events you can capture and modify?




  • ItemAdding - i.e. adding a new item - ok
  • ItemAdded - the new item has been added - ok
  • ItemUpdating - updating an existing item
  • ItemUpdated - an existing item has been updated
  • ItemCheckingIn - about to checkin an item
  • ItemCheckedIn - item checked in
  • ItemCheckingOut - about to checkout an item
  • ItemCheckedOut - item checked out
  • ItemDeleting - about to delete an existing item
  • ItemDeleted - an existing item is deleted
  • ItemUncheckingOut -what does this really mean?
  • ItemUncheckedOut - well

If you look at the SharePoint menu for an approved item it'll show the following menu items:



What puzzles me is the "Unpublish this version" menu item? Which event is linked with this operation?

When you check-in an item you can also choose to check-in and overwrite the existing version - thereby damaging the version control.

Conclusion: The ItemUpdating event is the answer! If you inspect the ModerationInformation field of the listitem you can find out the state - and block the Unpublish This Version event.

Saturday, February 17, 2007

List SPEventReceiver Before- and AfterProperties

Inspecting properties in SPEventReceivers, i.e. the Before Properties and AfterProperties, enables you to modify the standard functionality of SharePoint. But how do you access all the propeties.

I found this great posting which explains how.

Friday, February 16, 2007

Custom field type definition in SharePoint

During implementation of a FDA CFR 21 Part 11 extension to SharePoint 2007 I came across the need to extend SharePoint types with some custom types.

Rather than reinventing the wheel I found this excellent post about the subject.

Tuesday, February 13, 2007

Replace MOSS 2007 built-in Approval Workflow

Using the SharePoint ECM SDK I have managed to setup the Custom Approval Workflow sample - it works as expected.

However, co-existing with SharePoint default content approval seems to be quite confusing - especially to end-users. Both approval workflows appears in the end-user interface as outlined below:



In the example above I have approved the content using the Sample Appoval Workflow from ECM. Notice that the status is Approved for Sample Approval Workflow - whereas it is still pending for the built-in approval workflow.

If approving using the built-in approval buttons the system will notify me during the approval with the following message:






resulting in the following screen:



Now my content has been approved by the built-in approval workflow - whereas it is cancelled in my custom workflow.

Ideas very much appreciated.

Monday, February 12, 2007

Filtering a view based on workflow status

I have tried to create a view to display items that are pending various workflow status. So far without any luck - but luckily I found this article. It's even better explained (graphical) here. So simply use the integer number rather than the text value.

Sunday, February 11, 2007

Replace MOSS 2007 built-in Approval Workflow

SharePoint 2007 (MOSS) comes with a built-in workflow for content approval.

In some situations you might wish to replace this approval with you own custom workflow.

The tricky thing is how to accomplish this. While you can easily add new workflows to a list or a content type, I cannot figure out how the existing built-in workflow is replaced automatically.

The DefaultContentApprovalWorkflowId property seems to be solution - the only issue is that it doesn't work as the built-in workflow is not replaced.

Any ideas?

Thursday, February 08, 2007

Linking SPContentType with an Microsoft.Office.RecordsManagement.InformationPolicy

Based on the article by Ton Stegeman and the DocIntegrityPolicyFeature example found in the ECM toolkit I have managed to build my own policy feature for regulatory document management. It works perfect - when deployed from the end-user interface, i.e. similar to .

But how do you associate a content class with an Information Policy in code?

The Microsoft.Office.RecordsManagement.InformationPolicy object contains the Microsoft.Office.RecordsManagement.InformationPolicy.PolicyCatalog.FeatureList which is a PolicyFeatureCollection of all available PolicyFeatures installed.

It contains the following features:
  • Barcode
  • Label
  • Expiration
  • Audit

as well as my custom feature, RegulatoryDocumentManagement.

Linking a contenttype with an information policy is done through the CreatePolicy interface described at MSDN.

Monday, February 05, 2007

MOSS ItemAdded event - problem

Conclusion: The reason for this behavior is due to the fact that within my custom event handler I invoke a web service - bad idea. This unexpectedly changes the user profile of Internet Information Server - resulting in the error described. For now - don't invoke web services from within event handlers :-(

I'm testing the DocIntegrityPolicy example found in ECM toolkit. It provides an example of implementing a custom information management policy. When new items are added to a document library, the ItemAdded event set the value of a certain property to a MH5 hash value of the file in order to ensure integrity of the file. So far so good.

Unfortunately, this behavior introduces a problem in SharePoint. Modifying the content during the upload process results in an error: "The file has been modified by on ". This message is somehow understandable - as the item truely has been modified. But it raises the issue how to add fields such as barcodes and labels to a document in a library.

Please also refer to this blog for a similar example.

The sequence of events is outlined below:







1. Pick the document for upload


2. Enter document properties

3. Error reported


The good news is the the document is uploaded just fine - with all properties (including the ones added in ItemAdded) set as expected. But why the error?


To make things even more compliacated it turns out that the modification of the list itself during event registration (i.e. adding the new field to the list) raises another issue with the error: "The object has been updated by another user since it was last fetched".


Friday, February 02, 2007

Modifying barcodes in Word - uniqueness

SharePoint 2007 features supporting records management are very promising. Reading various MSFT whitepapers have convinced us that SharePoint can certainly be the core platform for Regulatory Document Management.

My experience with SharePoint has proved this as we have had a solution for regulatory document management based on SharePoint since 2001.

However, in SharePoint 2007 things are not as easy as we expected. As an example SharePoint build in barcodes - which I have assumed to be unique - can easily be modified by the end-user as sketched below.

First - take a look at the SharePoint document library:


Then we open the file in Word, and access the properties. Note that the barcode value has been synchronized with a Word property - which can be edited manually as sketched below:


When I finish editing my Word document and return to SharePoint document library the barcode has been modified:



The result is fairly disappointing as uniqueness of barcodes cannot be guaranteed by SharePoint.

Thursday, February 01, 2007

MOSS calculated field cannot point to a hidden field

I've tried to create a standard site set of columns, but of of the columns give me a very hard time.

I define a calculated field that points to a hidden field that I have also defined. When I try to add the new field to a site I get the error: "One or more column references are not allowed, because the columns are defined as a data type that is not supported in formulas".

If I remove the
Hidden="TRUE"
from the Field definition in the feature it works just fine.

Any ideas? If I add the field initially with HIDDEN="FALSE" everything works just fine. Afterwards I can change HIDDEN=TRUE without any issues - except from the fact that I cannot use the end-user interface to add a content type with that field in to a document library. But doing it programmatically works just fine - if I remember to toggle hidden in the operation. Strange.

Refer to this news-posting for similar experience.