Thursday, May 22, 2008

Problems Uploading Documents with Workflow in WSS

I've been working on my first Sharepoint 2007 site. Actually, it's a WSS site as I am not using Sharepoint. The site I have created has very limited functionality, and is intended to allow the company I am working for centrally maintain a register of a certain type of action they are qualified to perform and provide a link to all of the documents related to this action, and WSS is sufficient for this.

So what I have is the Sharepoint equivalent of an Excel spreadsheet (a custom list), which lists the actions and all the associated attributes, and I have a Document Repository, broken into folders. Each document in the Document Repository has two custom attributes - a action type flag and a business unit flag. Each action in the custom list has an action type attribute and a business unit attribute, and when a user selects "Related Documents" from the customised Actions drop down for a list item, Sharepoint does a search in the Document Repository for documents where the business unit and action type flags match the data in the selected action in the custom list.

So far so good. However, to make the experience within Sharepoint similar to what the users are used to and easier, I have made a custom workflow that fires when a new document is created and works out what folder within the Document Repository the new document is being uploaded to. In other words, I am trying to make the document itself explicitly aware of its location, and specifically the folder it is in. Each of the folders in the document repository are named for one of the business units. So the idea is that the document metadata will automatically contain the business unit name that owns the document.

This is where the problem emerges. A user enters the Document Repository, and begins to upload a document. At this point, the workflow fires off. Before the workflow has completed, the screen refreshes to allow the user to edit the metadata for the document, in this case the title, name, action type flag and business unit flag. The metadata displayed is the metadata that the document was uploaded with, but meanwhile, in the background, the workflow has updated the document's business unit flag attribute. The user clicks the check in button, and because the metadata that the document had when the page was rendered and the metadata it has now the workflow is finished is different (irrespective of whether the user entered any changes for these fields), the process errors.

Server Error in '/' Application.
--------------------------------------------------------------------------------

The file Document Repository/
BusinessUnit/Document.JPG has been modified by SHAREPOINT\system on 22 May 2008 11:36:50 +0800.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Runtime.InteropServices.COMException: The file
Document Repository/BusinessUnit/Document.JPG has been modified by SHAREPOINT\system on 22 May 2008 11:36:50 +0800.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:


[COMException (0x81020037): The file
Document Repository/BusinessUnit/Document.JPG has been modified by SHAREPOINT\system on 22 May 2008 11:36:50 +0800.]
Microsoft.SharePoint.Library.SPRequestInternalClass.AddOrUpdateItem(String bstrUrl, String bstrListName, Boolean bAdd, Boolean bSystemUpdate, Boolean bPreserveItemVersion, Boolean bUpdateNoVersion, Int32& plID, String& pbstrGuid, Guid pbstrNewDocId, Boolean bHasNewDocId, String bstrVersion, Object& pvarAttachmentNames, Object& pvarAttachmentContents, Object& pvarProperties, Boolean bCheckOut, Boolean bCheckin, Boolean bMigration, Boolean bPublish) +0
Microsoft.SharePoint.Library.SPRequest.AddOrUpdateItem(String bstrUrl, String bstrListName, Boolean bAdd, Boolean bSystemUpdate, Boolean bPreserveItemVersion, Boolean bUpdateNoVersion, Int32& plID, String& pbstrGuid, Guid pbstrNewDocId, Boolean bHasNewDocId, String bstrVersion, Object& pvarAttachmentNames, Object& pvarAttachmentContents, Object& pvarProperties, Boolean bCheckOut, Boolean bCheckin, Boolean bMigration, Boolean bPublish) +199

[SPException: The file
Document Repository/BusinessUnit/Document.JPG has been modified by SHAREPOINT\system on 22 May 2008 11:36:50 +0800.]
Microsoft.SharePoint.Library.SPRequest.AddOrUpdateItem(String bstrUrl, String bstrListName, Boolean bAdd, Boolean bSystemUpdate, Boolean bPreserveItemVersion, Boolean bUpdateNoVersion, Int32& plID, String& pbstrGuid, Guid pbstrNewDocId, Boolean bHasNewDocId, String bstrVersion, Object& pvarAttachmentNames, Object& pvarAttachmentContents, Object& pvarProperties, Boolean bCheckOut, Boolean bCheckin, Boolean bMigration, Boolean bPublish) +240
Microsoft.SharePoint.SPListItem.AddOrUpdateItem(Boolean bAdd, Boolean bSystem, Boolean bPreserveItemVersion, Boolean bNoVersion, Boolean bMigration, Boolean bPublish, Boolean bCheckOut, Boolean bCheckin, Guid newGuidOnAdd, Int32& ulID, Object& objAttachmentNames, Object& objAttachmentContents, Boolean suppressAfterEvents) +933
Microsoft.SharePoint.SPListItem.UpdateInternal(Boolean bSystem, Boolean bPreserveItemVersion, Guid newGuidOnAdd, Boolean bMigration, Boolean bPublish, Boolean bNoVersion, Boolean bCheckOut, Boolean bCheckin, Boolean suppressAfterEvents) +182
Microsoft.SharePoint.SPListItem.UpdateOverwriteVersion() +88
Microsoft.SharePoint.WebControls.SaveButton.SaveItem(SPContext itemContext, Boolean uploadMode, String checkInComment) +178
Microsoft.SharePoint.WebControls.SaveButton.SaveItem() +58
Microsoft.SharePoint.WebControls.SaveButton.OnBubbleEvent(Object source, EventArgs e) +249
System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +35
System.Web.UI.WebControls.Button.OnCommand(CommandEventArgs e) +115
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +163
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +7
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +11
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +177
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1746
Not good, huh!

Anyway, it turns out this is a fairly well known problem (even though Googling the error doesn't come up with much). Two good posts that started to lead me in the right direction are here and here. It turns out, that for me, the solution was as easy as making sure I had a mandatory or required field/column with no default value entered for the uploaded documents. The workflow would then have to wait until the user entered the requisite information and checked the document in, before firing. Problem solved.

No comments: