Friday, July 11, 2008

Sharepoint Workflow to Make Items Context Aware

One of the things I have wanted since I first started working with Sharepoint 2007 is to have the documents and items in Sharepoint/MOSS be context aware. What I mean by that (and people may understand different things by "context aware") is that when an item is created or moved, the item itself knows where it now is. I want a custom column or metadata element that is automagically updated to reflect the context. For me, this mostly means having a custom column that keeps up to date with the folder a document or item is in.

I did the normal stuff people do to get this happening. I mucked around for ages with Microsoft Office Sharepoint Designer (MOSD), trying to get the workflow wizard to build a workflow to do this. No such luck. In the end I created a custom workflow in Visual Studio 2005 to do this for me, and thought I would share the code with my vast readership (yes, you know who you are, all 3 of you). This code may seem a bit cludgey to some of you. If you can see a better way to do this, let me know. Pre-empting one comment though, every time I tried to reference
WorkflowProperties.Item.File.ParentFolder, or any variation on this, VS kindly told me that this was null. I suspect that if I try this for a document it will work, but as I use this code to make tasks context aware, there is no file object?

This code is particularly useful, because if you copule this with my previous Sharepoint related post about displaying Sharepoint custom columns in Outlook, it means that you can show in Outlook the Sharepoint context of a task ... Handy!
private void logWorkflowStarted_MethodInvoking(object sender, EventArgs e)
{

SPSecurity.RunWithElevatedPrivileges(delegate()
{
//Default value
FolderName = "Unknown";
//Get the current item
SPListItem listItem = WorkflowProperties.Item;
//Get web reference
SPWeb web = listItem.Web;
//Get list reference
SPList list = web.Lists[listItem.ParentList.ID];
//Get URL for item
string FullURL = web.Url + listItem.Url;
//Get last slash
int index = FullURL.LastIndexOf("/");
//Set parent folder URL
string parentFolderUrl = string.Empty;
//If slash found
if (index > -1)
{
//Get url of parent
parentFolderUrl = FullURL.Substring(0, index);
//Get folder
SPFolder folder = list.RootFolder.SubFolders[parentFolderUrl];

if (folder.Exists)
{
FolderName = folder.Name;
}
}


//Update folder name
WorkflowProperties.Item["Project"] = FolderName;
//Update document meta data
try
{
WorkflowProperties.Item.SystemUpdate();
}
catch (SPException ex)
{
throw ex;
}

});
}

No comments: