If you're building a workflow solution using Windows Workflow Foundation and Windows SharePoint Services 3.0, you have to implement aspx forms. What's more, you also have to design your own task (or other) notification forms.
I guess everyone would want to have the convenience of having links back to the task, the task item and the workflow status. Even the ability to "Connect Outlook" to the Workflow Tasklist would be nice, so that all tasks are not only available on the web, but also within Outlook.
Of course these links need to be constructed at runtime, as IDs and names depend on the specific lists and task items being used.
The Html Template
The resource that is used to dynamically build these links is rather simple:
<DIV>
<P style="MARGIN-BOTTOM: 8px; BACKGROUND: blue">
<B><SPAN style="COLOR: white"> Workflow Links:</SPAN></B>
</P>
<DIV style="MARGIN-LEFT: 8px">
1. <A href="{ListItemUrl}"> Link to the List Item the workflow was started on</A> <BR>
2. <A href="{TaskUrl}"> Link to the Task</A> <BR>
3. <A href="{WorkflowStatusUrl}"> Link to the Workflow Status</A> <BR>
4. <A href="{ConnectOutlookUrl}"> Connect Outlook to Workflow Task List</A> <BR>
</DIV>
</DIV>
The essential parts are marked in red. These are the placeholders we have to change at runtime.
ListItemUrl & TaskUrl
The code to exchange the ListItemUrl and the TaskUrl is quite simple too. As you can see the "workflowProperties" and the "activity" have all the data we need to concatenate the pieces for the links:
String webUrl = workflowProperties.WebUrl;
bodyStr = bodyStr.Replace("{ListItemUrl}", webUrl
+ workflowProperties.ListUrl + "/DispForm.aspx?ID="
+ workflowProperties.ItemId.ToString());
bodyStr = bodyStr.Replace("{TaskUrl}", webUrl + workflowProperties.TaskListUrl
+ "/DispForm.aspx?ID=" + activity.ListItemId.ToString());
WorkflowStatusUrl
For the WorkflowStatusUrl we need to get the GUIDs for the List that holds the item the workflow was started on, as well as the Workflow Instance and then add the curly braces and escape the "-". The following code section has the little helper method that does that, as well as the code to concatenate the link:
private String formatGuidString(String s)
{
s = "%7b" + s;
s = s + "%7d";
s = s.Replace("-", "%2d");
return s;
}
...
String strListID = formatGuidString(workflowProperties.Workflow.ParentList.ID.ToString());
String strInstanceID = formatGuidString(workflowProperties.Workflow.InstanceId.ToString());
bodyStr = bodyStr.Replace("{WorkflowStatusUrl}", webUrl + "/_layouts/WrkStat.aspx?List="
+ strListID + "&WorkflowInstanceID=" + strInstanceID);
ConnectOutlookUrl
Last not least, the link that I like the most. The Connect to Outlook menu command in SharePoint is already a great value, but with Workflows I find it quite cumbersome to send users to the Workflow Tasklist to have them manually connect to Outlook from there, especially when this list is usually hidden from the users.
The connection to Outlook is achieved by calling a custom protocol (stssync). The following string (called "strConnectTo" in the following code) is a generalized version, for which we again will have to substitute the placeholders:
stssync://sts/?ver=1.1&type=tasks&cmd=add-folder&base-url={serverUrl}&list-url={taskListUrlPlusSlash}&guid=%7b{taskListGuid}%7d&site-name={siteName}&list-name={listName}
The 5 placeholders are actually also easily replaced:
strConnectTo = strConnectTo.Replace("{serverUrl}", workflowProperties.WebUrl);
strConnectTo = strConnectTo.Replace("{taskListUrlPlusSlash}", workflowProperties.TaskListUrl + "/");
strConnectTo = strConnectTo.Replace("{taskListGuid}", workflowProperties.TaskListId.ToString());
strConnectTo = strConnectTo.Replace("{siteName}", workflowProperties.Web.Title);
strConnectTo = strConnectTo.Replace("{listName}", workflowProperties.TaskList.Title);
bodyStr = bodyStr.Replace("{ConnectOutlookUrl}", strConnectTo);
And that's it!