I have been playing around with an event handler that moves files after they have been uploaded to a document library. This is useful in scenarios where you want people to upload files (or post infopath forms) to a library, then analyze the meta data and move it to another library automatically based on what the user chose in the meta data.
A cool example of how we may use this is an infopath form where the user's details are getting pulled from a database, including his "state" attribute. The event handler, when seeing the user is from a specific state, moves the document to a document library where it will be accessabile only by the people in the same state. This way alerts can be set be state and a seperate workflow can be developed for each state and so on.
The code is actually easy. I don't use the SPFile.MoveTo() function since it doesn't support moving to other sites, and that may be required. So I wrote a function that gets the source file (SPFile) and the target folder (SPFolder), copies the file by reading it's stream and then deletes the source file. This ofcourse can be improved in the future.
private static void MoveFile(SPFile fileToMove, SPFolder targetFolder)
Stream s = fileToMove.OpenBinaryStream();
The problem I discovered that even though I was running the code in the ItemAdded event, the code would run when the file is uploaded. This causes a big problem, since sharepoint 2007, after uploading the file checks if there are any properties (meta data) it needs to ask the user for, and redirects him to the meta data entry screen. But my event handler already deleted the file!
So every time the user uploads a file, he will see:
"No item exists at http://site/web/library/Forms/EditForm.aspx?Mode=Upload&CheckInComment=&ID=23&RootFolder=/web/library&Source=http://site/library/Forms/view.aspx. It may have been deleted or renamed by another user."
I have tried using the "ItemCheckedIn" event instead, with no luck - it is not called when a file is uploaded. It looks like the sequence of events is:
- ItemUpdating (this is after the user enters the metadata)
So from this we can conclude (and I tested to confirm) that if you want to move a file on upload, do it in the ItemUpdated event, or the ItemUpdating event.
The problem is, if the user presses "Cancel" in the metadata window, the file will remain in the library, since the "Updating" events didn't trigger.
What to do? I honestly don't know. It seems we cannot develop an event handler that moves files automatically and will trap all documents uploaded, without causing errors on the screen for the user.