This post focuses on how I was able to use the out of the box InfoPath approval approve/reject task forms forms in my custom Visual Studio SharePoint workflow.If you’re looking for a general how-to post on creating SharePoint workflows with Visual Studio, this is not the post for you. I would instead point you to Serge Luca’s excellent 20-part series on creating SharePoint workflows with Visual Studio.
Creating the task
Here’s the skinny on what you need to do in order to use the default Microsoft Office SharePoint Server 2007 (MOSS) approve/reject InfoPath form in a custom Visual Studio workflow.1. Create a SharePoint workflow project
There are many ways to do this, so I won’t go into details here. My personal favorite way is by using the WSP Builder Visual Studio workflow template project. Just make sure that your workflow class inherits from System.Workflow.Activities.SequentialWorkflowActivity or from System.Workflow.Activities.StateMachineWorkflowActivity.2. Set the TaskListContentTypeId attribute
Edit the elements.xml file in your workflow feature definition. Set the TaskListContentTypeId attribute value to use the MOSS workflow task content type id:<Elements> <Workflow Name="MyWorkflow" Description="This is my custom workflow." … TaskListContentTypeId="0x01080100C9C9515DE4E24001905074F980F93160" > … </Workflow> … </Elements>
3. Add the Task_FormURN and ExtendedStatusColumnValues elements
Continue to edit the elements.xml file in your workflow feature definition. Add the following MetaData element under the Workflow element:<Elements> <Workflow …> <MetaData> <Task0_FormURN>urn:schemas-microsoft-com:office:infopath:workflow:ReviewRouting-Review:$Subst:LCID;</Task0_FormURN> <Task1_FormURN>urn:schemas-microsoft-com:office:infopath:workflow:ReviewRouting-Review:$Subst:LCID;</Task1_FormURN> <Task2_FormURN>urn:schemas-microsoft-com:office:infopath:workflow:ReviewRouting-Review:$Subst:LCID;</Task2_FormURN> <ExtendedStatusColumnValues> <StatusColumnValue>$Resources:ReviewFeedback_CanceledStatus</StatusColumnValue> <StatusColumnValue>$Resources:ReviewFeedback_ApprovedStatus</StatusColumnValue> <StatusColumnValue>$Resources:ReviewFeedback_RejectedStatus</StatusColumnValue> </ExtendedStatusColumnValues> </MetaData> … </Workflow> … </Elements>
4. Add a CreateTask activity to your workflow
Add a CreateTask activity to your workflow. Make sure to set the TaskType property on the TaskProperties of the CreateTask activity to 1. This will tell the workflow runtime to create the task using the Form Urn corresponding to the inner text in the Task1_FormURN element. The CreateTask activity’s MethodInvoking event is a good place to set the property.private void createTask1_MethodInvoking(object sender, EventArgs e) { //initialize task infrastructure data this.createTask1_TaskId1 = Guid.NewGuid(); this.createTask1_TaskProperties1 = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties(); this.createTask1_TaskProperties1.TaskType = 1; //set task remaining properties //... }
Processing a workflow task
Now that you’ve created a workflow task that uses the default approval form, you will want to your workflow to do something useful when a user approves or rejects the task. Here is how to detect when a user approves or rejects the workflow task.5. Detect task change with OnTaskChanged
This is fairly straight forward: add an OnTaskChanged activity to your workflow. Set the task ID and correlation token to correspond to the ones used when creating the task in the previous section. See Serge Luca’s SharePoint workflow series for details.6. Task approved or rejected
Here’s the interesting part. Whether a user approves, rejects, reassigns, or requests a change in the task form, the task is always marked as Complete. The actual value that corresponds to what the user selected is stored in the TaskStatus in the ExtendedProperties collection of the SPWorkflowTaskProperties class. The following is a table that correlates the user’s approval action to the value of the TaskStatus extended property:| User Action | TaskStatus Value |
| Approve | “#” |
| Reject | “@” |
| Cancel | [no change] |
Here’s a sample helper method that checks whether a particular workflow task was approved:
public static bool IsTaskApproved(SPWorkflowTaskProperties TaskProperties) { return TaskProperties.ExtendedProperties["TaskStatus"] != null && TaskProperties.ExtendedProperties["TaskStatus"] as string == "#"; }
Anything else?
That’s it. There is surprisingly little work involved in using the default MOSS approvals forms in your own custom SharePoint Visual Studio workflows, once you know what to look for that is. I’d like to wrap us this post with the benefits to this approach and a few things you should keep in mind when working with the default workflow forms.Some benefits to this approach
Here are just some of the benefits you get when you reuse the existing MOSS approval task forms rather than creating your own customs InfoPath task forms:- No InfoPath forms development
- No InfoPath forms deployment
- Out of the box user interface for:
- Approve
- Reject
- Cancel
- Reassign Task
- Request a change
- Instructions to approver
- Capture approver comments
- Out of the box multi-language user interface with appropriate MOSS language packs. Notice the references to “$Resources:”.
A few things you should know
- Any action in default task forms except Cancel marks the task “Complete”. Your workflow must then create a new task with the desired action from the completed task. For example: If a user re-assigns the task to a new user, the task for the user is marked complete. Your workflow must create a new task and assign it to the new user.
- The MOSS task forms derive most of their data from fields in the ExtendedProperties of the task, not the main task properties.
Hello Eugene, thats a Great post. But I'd want to ask you a question. When I do as the posts says, when I test in place of Appear the button Approve/Reject, appears the buttons Send Feecback/Cancel, do you know why is it?? Thanks!
ReplyDeleteOriol, I would check to make sure that your Task_FormURN registrations are correct and that you are using the correct TaskType index before you create your task.
ReplyDeletehello ,
ReplyDeletecan u tell me from where can i get the TaskListContentTypeId ?!! please
It is defined in "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\FEATURES\OffWFCommon\CTypes.xml"
ReplyDeleteThis comment has been removed by the author.
ReplyDeletethank u very mutch ^^ !
ReplyDeletei have another problem, i deployed the workflow in my website ,when i create an item , its create a TASK ,it's fine !
BUT when i want to edit the task , so to display the approval form , sharepoint give me that message in the middle of the screen :
Can not display this form because session state is not available
This comment has been removed by the author.
ReplyDeleteThe session state error message sounds like it might be a generic InfoPath Forms Services error message. I would try to run an out-of-the-box Approval workflow to ensure that it operates normally before going through your code.
ReplyDeleteit's Ok ^^ , i should activate System.Web.SessionState.SessionStateModule in the Web.config !
ReplyDeleteplease , the workflow is activated in a list named "biblio" , i want to edit a column value in the concerned item of this list when the workflow is finishied !
ReplyDeleteAny idea ?!!
workflowProperties.Item will give you access to the list item on which the workflow is currently running.
ReplyDeletethaank youuu , it's donne (Y)
ReplyDeletehello eugene ,
ReplyDelete( Sorry 4 disturbin ) but i have a litte question :
I have a library of document and i added a column named "test"
and i have a webpart that browse files in the library , so i would like to get the value of the column "test" from the SPFile Object
My Code :
....
foreach (SPFile file in folder.Files)
{
fileinfo = new FileInfo();
fileinfo.Name = file.Name;
fileinfo.Size = file.Length / 1024;
fileinfo.URL = file.Url;
fileinfo.IconURL = file.IconUrl;
fileinfo.File = file;
result.Add(fileinfo);
}
Thank's ^^
You should post questions that don't relate to this post on the appropriate Microsoft SharePoint forum. These forums are moderated, so you'll get a response pretty quickly.
ReplyDeletehttp://social.technet.microsoft.com/Forums/en/category/sharepoint
Ok , thanks ^^
ReplyDeleteHi Eugene,
ReplyDeleteIs it possible to make the comments field mandatory conditionally on the OOB task forms.
I want my approvers to provide a comment for sure when they are rejecting the task.
Request your support.
Thanks,
Bhargav
Hi Oru,
DeleteI haven't tried it myself, but it should definitely be possible. The fields in the out of the box forms are controlled using the InfoPath forms that ship with SharePoint Server. So, you could at least open up the form in InfoPath designer, and set the Comments field in the data source to be required.
This isn't really best practices as far as customizing SharePoint goes, since you are modifying a file that might get reset in a future service pack or patch. I'm sure we can find a better way given some thought. Let me know what you come up with.
-Eugene
Hello Eugene,
DeleteI am having problem in capturing the comment. Also i want to remove the due by field which is appering on the task form. Can u help me how to do.
Also where will the form be stored to edit it.
Awesome! Thank you so much!
ReplyDeleteHello Eugene,
ReplyDeleteThank you for the post!
Could you please describe me the metadata entries for "2010 Approval task form". Basically I need to replace following entries:
urn:schemas-microsoft-com:office:infopath:workflow:ReviewRouting-Review:$Subst:LCID;
urn:schemas-microsoft-com:office:infopath:workflow:ReviewRouting-Review:$Subst:LCID;
urn:schemas-microsoft-com:office:infopath:workflow:ReviewRouting-Review:$Subst:LCID;
Thank you,
Sam
sams177@gmail.com
Sorry Sam, haven't updated this for 2010 or 2013.
Delete