1. In Visual Studio 2005, File -> New -> Project -> SharePoint -> SharePoint Server State Machine, call it AgendaItemPeerReview
In Visual Studio 2008, File -> New -> Project -> Visual Basic -> Office -> 2007 -> SharePoint 2007 State Machine Workflow,
call it AgendaItemPeerReview
set location to d:\asp or whatever you want
Rename Workflow1.vb to PeerReviewWorkflow.vb and doubleclick it to open the design surface.
It will start out with a state called Workflow1InitialState. Rename Workflow1InitialState to InitialState.
Note: The workflow MUST have a different name than the solution/project. Do NOT rename file workflow1.cs (and thus the
workflow1 class) to the same name you chose as the solution/project.
2. add three more states and name them InitiatorApproval, PeerReviewerApproval and FinalState
3. right click workflow and set CompletedStateFinish property to the new state you created called FinalState
be sure InitialStateName is InitialState
We will build the workflow by adding activities to the various states.
Afterwards, we will come back and add the necessary code. I do it this way because some code is autogenerated while
other code must be written by us, and by building the whole workflow first, all the generated code will be together,
then all our code will be together below the generated code. Also, this provides more of a top-down approach to
designing (and understanding) the workflow.
4. in state InitialState, click eventDrivenActivity1 and rename it to InitialStateActivities
5. double-click this activity to drill down into it; in here we will create a sequential workflow; notice there is
already an onWorkflowActivated1 event
a. Rename onWorkflowActivated1 to onWorkflowActivated.
b. Drill down into CorrelationToken and change OwnerActivityName to PeerReviewWorkflow.
c. Drill down into WorkflowProperties and change Name to PeerReviewWorkflow.
6. in the Toolbox, find the Windows Workflow section and drag and drop a SetState event below onWorkflowActivated
a. rename setState activity to setStatePeerReviewerApproval
b. set TargetStateName property to PeerReviewerApproval
c. click on PeerReviewWorkflow to go back to workflow view; notice the line drawn from InitialState to
state PeerReviewerApproval
For the two approval states, we are going to add the same stuff, ie initialization code for when a state is entered,
code to execute while in the state, and code to execute when the state is completed.
7. for each of the two states, drag and drop into them:
a. a StateInitialization activity
b. an EventDriven activity
c. a StateFinalization activity
8. in stateInitiatorApproval, rename the activities to:
InitiatorApprovalInitialization
InitiatorApprovalActivities
InitiatorApprovalFinalization
9. in statePeerReviewerApproval, rename the activities to:
PeerReviewerApprovalInitialization
PeerReviewerApprovalActivities
PeerReviewerApprovalFinalization
We will now add the specific tasks within each of these three activities (initialization, activities, finalization) for each state.
Essentially, we will be creating sequential workflows within each of these activities.
10. in InitiatorApproval, double-click InitiatorApprovalInitialization to drill down into it
11. drag and drop a CreateTask activity and set the following properties:
a. rename it createInitiatorApprovalTask
b. set CorrelationToken to InitiatorApprovalToken; click the + next to it to set the OwnerActivityName to
InitiatorApproval
c. for TaskId, click the ellipses, click the "Bind to a new member" tab, remove the 1 from the end of the "New member name"
and click OK
d. follow the same step for TaskProperties
e. exit this sequential workflow view by clicking on PeerReviewWorkflow on the design surface
12. double-click InitiatorApprovalFinalization to drill down into it
13. drag and drop a CompleteTask activity and set the following properties:
a. rename it completeInitiatorApprovalTask
b. set CorrelationToken to InitiatorApprovalToken; click the + next to it to set the OwnerActivityName to
InitiatorApproval
c. for TaskId, click the ellipses, on the "Bind to an existing member" tab, click createInitiatorApprovalTask_TaskId
d. exit this sequential workflow view by clicking on PeerReviewWorkflow on the design surface
14. double-click InitiatorApprovalActivities to drill down into it
15. drag and drop an OnTaskChanged activity and set the following properties:
a. rename it onInitiatorApprovalChanged
b. set CorrelationToken to InitiatorApprovalToken; click the + next to it to set the OwnerActivityName to
InitiatorApproval
c. for TaskId, click the ellipses, on the "Bind to an existing member" tab, click createInitiatorApprovalTask_TaskId
d. for AfterProperties and BeforeProperties, click the ellipses, click the "Bind to a new member" tab,
remove the 1 from the end of the "New member name" and click OK
16. drag and drop an IfElse activity and rename it InitiatorApprovalStatus
17. click on the left branch and set the following properties:
a. rename it ifInitiatorApproved
b. for Condition, click Code Condition
18. drag and drop a setState activity under ifInitiatorApproved
a. rename it setStatePeerReviewerApproval
b. set the TargetStateName to PeerReviewerApproval
19. click PeerReviewWorkflow to go back to higher-level view of workflow
20. in PeerReviewerApproval, double-click PeerReviewerApprovalInitialization to drill down into it
21. drag and drop a CreateTask activity and set the following properties:
a. rename it createPeerReviewerApprovalTask
b. set CorrelationToken to PeerReviewerApprovalToken; click the + next to it to set the OwnerActivityName to
PeerReviewerApproval
c. for TaskId, click the ellipses, click the "Bind to a new member" tab, remove the 1 from the end of the "New member name"
and click OK
d. follow the same step for TaskProperties
e. exit this sequential workflow view by clicking on PeerReviewWorkflow on the design surface
22. double-click PeerReviewerApprovalFinalization to drill down into it
23. drag and drop a CompleteTask activity and set the following properties:
a. rename it completePeerReviewerApprovalTask
b. set CorrelationToken to PeerReviewerApprovalToken; click the + next to it to set the OwnerActivityName to
PeerReviewerApproval
c. for TaskId, click the ellipses, on the "Bind to an existing member" tab, click createPeerReviewerApprovalTask_TaskId
d. exit this sequential workflow view by clicking on PeerReviewWorkflow on the design surface
24. double-click PeerReviewerApprovalActivities to drill down into it
25. drag and drop an OnTaskChanged activity and set the following properties:
a. rename it onPeerReviewerApprovalChanged
b. set CorrelationToken to PeerReviewerApprovalToken; click the + next to it to set the OwnerActivityName to
InitiatorApproval
c. for TaskId, click the ellipses, on the "Bind to an existing member" tab, click createPeerReviewerApprovalTask_TaskId
d. for AfterProperties and BeforeProperties, click the ellipses, click the "Bind to a new member" tab,
remove the 1 from the end of the "New member name" and click OK
26. drag and drop an IfElse activity and rename it PeerReviewerApprovalStatus
27. click on the left branch and set the following properties:
a. rename it ifPeerReviewerApproved
b. for Condition, click Code Condition
28. drag and drop a setState activity under ifPeerReviewerApproved
a. rename it setStateFinalState
b. set the TargetStateName to FinalState
29. click on the right branch and set the following properties:
a. rename it ifPeerReviewerRejected
b. for Condition, click Code Condition
30. drag and drop a setState activity under ifPeerReviewerRejected
a. rename it setStateInitiatorApproval
b. set the TargetStateName to InitiatorApproval
Now we are ready to start adding code. First we will add code in InitialState, for when the workflow starts.
31. Go to the code-behind and find the following line (this is the VB version, but the C# version looks almost identical):
Public workflowProperties As SPWorkflowActivationProperties = New Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties
Above it, type:
VISUAL BASIC
------------
Public workflowId As System.Guid
VISUAL C#
---------
public Guid workflowId = default(System.Guid);
Below the workflowProperties line, type:
VISUAL BASIC
------------
Dim PeerReviewer As String
Dim CC As String
Dim Instructions As String
VISUAL C#
---------
private String PeerReviewer = default(String);
private String CC = default(String);
private String Instructions = default(String);
32. back on design surface, double-click InitialStateActivitites to drill down into it
33. double-click onWorkflowActivated. This will take you to the code behind and show the generated code stub
onWorkflowActivated_Invoked. Copy and paste the following code into it:
VISUAL BASIC
------------
workflowId = workflowProperties.WorkflowId
Dim serializer As XmlSerializer = New XmlSerializer(GetType(InitForm))
Dim reader As XmlTextReader = New XmlTextReader(New System.IO.StringReader(workflowProperties.InitiationData))
Dim initform As InitForm = CType(serializer.Deserialize(reader), InitForm)
Dim prPeerReviewer() As Person
prPeerReviewer = initform.gpPeerReviewer
PeerReviewer = prPeerReviewer(0).AccountId
Dim prCC() As Person
prCC = initform.gpCC
CC = prCC(0).AccountId
Instructions = initform.txtInstructions
VISUAL C#
---------
workflowId = workflowProperties.WorkflowId;
XmlSerializer serializer = new XmlSerializer(typeof(InitForm));
XmlTextReader reader = new XmlTextReader(new System.IO.StringReader(workflowProperties.InitiationData));
InitForm initform = (InitForm)serializer.Deserialize(reader);
Person prPeerReviewer = new Person();
prPeerReviewer = (Person)initform.gpPeerReviewer[0];
//PeerReviewer = prPeerReviewer.AccountId.GetValue(0).ToString();
PeerReviewer = prPeerReviewer.AccountId;
Person prCC = new Person();
prCC = (Person)initform.gpCC[0];
//CC = prCC.AccountId.GetValue(0).ToString();
CC = prCC.AccountId;
Instructions = initform.txtInstructions;
34. go to the top of PeerReviewWorkflow.vb and add the following code:
VISUAL BASIC
------------
imports System.Xml.Serialization
imports System.Xml
VISUAL C#
---------
using System.Xml.Serialization;
using System.Xml;
Next, we will add code to the InitiatorApproval state.
35. go back to the design surface and double-click InitiatorApprovalInitialization to drill down into it
36. double-click createInitiatorApprovalTask to be taken to its MethodInvoking code stub. Copy and paste
the following code in it.
VISUAL BASIC
------------
createInitiatorApprovalTask_TaskId = Guid.NewGuid
createInitiatorApprovalTask_TaskProperties = new SPWorkflowTaskProperties
createInitiatorApprovalTask_TaskProperties.Title = "Initiator Approval of " & workflowProperties.Item.File.Name
createInitiatorApprovalTask_TaskProperties.AssignedTo = workflowProperties.Originator
createInitiatorApprovalTask_TaskProperties.Description = ""
createInitiatorApprovalTask_TaskProperties.TaskType = 0
createInitiatorApprovalTask_TaskProperties.ExtendedProperties("txtInstructions") = Instructions
VISUAL C#
---------
createInitiatorApprovalTask_TaskId = Guid.NewGuid();
createInitiatorApprovalTask_TaskProperties = new SPWorkflowTaskProperties();
createInitiatorApprovalTask_TaskProperties.Title = "Initiator Approval of " + workflowProperties.Item.File.Name;
createInitiatorApprovalTask_TaskProperties.AssignedTo = workflowProperties.Originator;
createInitiatorApprovalTask_TaskProperties.Description = "";
createInitiatorApprovalTask_TaskProperties.TaskType = 0;
createInitiatorApprovalTask_TaskProperties.ExtendedProperties["txtInstructions"] = Instructions;
37. go back to the design surface and double-click InitiatorApprovalActivities to drill down into it
38. double-click onInitiatorApprovalChanged to be taken to its Invoked code stub. Copy and paste
the following code in it.
VISUAL BASIC
------------
onInitiatorApprovalChanged_AfterProperties = onInitiatorApprovalChanged.AfterProperties
onInitiatorApprovalChanged_BeforeProperties = onInitiatorApprovalChanged.BeforeProperties
VISUAL C#
---------
onInitiatorApprovalChanged_AfterProperties = onInitiatorApprovalChanged.AfterProperties;
onInitiatorApprovalChanged_BeforeProperties = onInitiatorApprovalChanged.BeforeProperties;
39. go back to the design surface and click ifInitiatorApproved and set the following properties:
a. drill down into the Condition property (already set to Code Condition), and next to the second
Condition property, type InitiatorApproved and hit enter
b. you will be taken to the code stub for InitiatorApproved routine; copy and paste the following
code into it:
VISUAL BASIC
------------
If onInitiatorApprovalChanged_AfterProperties.ExtendedProperties("status").ToString = "accepted" Then
e.Result = True
End If
VISUAL C#
---------
if (onInitiatorApprovalChanged_AfterProperties.ExtendedProperties["status"].ToString() == "accepted")
{
e.Result = true;
}
Next, we will add code to the PeerReviewerApproval state.
40. go back to the design surface and double-click PeerReviewerApprovalInitialization to drill down into it
41. double-click createPeerReviewerApprovalTask to be taken to its MethodInvoking code stub. Copy and paste
the following code in it.
VISUAL BASIC
------------
createPeerReviewerApprovalTask_TaskId = Guid.NewGuid
createPeerReviewerApprovalTask_TaskProperties = new SPWorkflowTaskProperties
createPeerReviewerApprovalTask_TaskProperties.Title = "Peer Reviewer Approval of " & workflowProperties.Item.File.Name
createPeerReviewerApprovalTask_TaskProperties.AssignedTo = PeerReviewer
createPeerReviewerApprovalTask_TaskProperties.Description = ""
createPeerReviewerApprovalTask_TaskProperties.TaskType = 0
createPeerReviewerApprovalTask_TaskProperties.ExtendedProperties("txtInstructions") = Instructions
VISUAL C#
---------
createPeerReviewerApprovalTask_TaskId = Guid.NewGuid();
createPeerReviewerApprovalTask_TaskProperties = new SPWorkflowTaskProperties();
createPeerReviewerApprovalTask_TaskProperties.Title = "Peer Reviewer Approval of " + workflowProperties.Item.File.Name;
createPeerReviewerApprovalTask_TaskProperties.AssignedTo = PeerReviewer;
createPeerReviewerApprovalTask_TaskProperties.Description = "";
createPeerReviewerApprovalTask_TaskProperties.TaskType = 0;
createInitiatorApprovalTask_TaskProperties.ExtendedProperties["txtInstructions"] = Instructions;
42. go back to the design surface and double-click PeerReviewerApprovalActivities to drill down into it
43. double-click onPeerReviewerApprovalChanged to be taken to its Invoked code stub. Copy and paste
the following code in it.
VISUAL BASIC
------------
onPeerReviewerApprovalChanged_AfterProperties = onPeerReviewerApprovalChanged.AfterProperties
onPeerReviewerApprovalChanged_BeforeProperties = onPeerReviewerApprovalChanged.BeforeProperties
VISUAL C#
---------
onPeerReviewerApprovalChanged_AfterProperties = onPeerReviewerApprovalChanged.AfterProperties;
onPeerReviewerApprovalChanged_BeforeProperties = onPeerReviewerApprovalChanged.BeforeProperties;
44. go back to the design surface and click ifPeerReviewerApproved and set the following properties:
a. drill down into the Condition property (already set to Code Condition), and next to the second
Condition property, type PeerReviewerApproved and hit enter
b. you will be taken to the code stub for PeerReviewerApproved routine; copy and paste the following
code into it:
VISUAL BASIC
------------
If onPeerReviewerApprovalChanged_AfterProperties.ExtendedProperties("status").ToString = "accepted" Then
e.Result = True
End If
VISUAL C#
---------
if (onPeerReviewerApprovalChanged_AfterProperties.ExtendedProperties["status"].ToString() == "accepted")
{
e.Result = true;
}
45. go back to the design surface and click ifPeerReviewerRejected and set the following properties:
a. drill down into the Condition property (already set to Code Condition), and next to the second
Condition property, type PeerReviewerRejected and hit enter
b. you will be taken to the code stub for PeerReviewerApproved routine; copy and paste the following
code into it:
VISUAL BASIC
------------
If onPeerReviewerApprovalChanged_AfterProperties.ExtendedProperties("status").ToString = "rejected" Then
e.Result = True
End If
VISUAL C#
---------
if (onPeerReviewerApprovalChanged_AfterProperties.ExtendedProperties["status"].ToString() == "rejected")
{
e.Result = true;
}
46. sign the assembly
a. right-click the project, then click properties
b. click Signing
c. if Sign the assembly is not already checked...
d. check Sign the assembly
e. choose <new> from the dropdown
f. enter MyKeyFile for the key file name
g. uncheck Protect my key file with a password
h. click OK
47. follow instructions above for creating the workflow's Initiation and Task forms using Microsoft Office InfoPath
48. If developing in Visual Studio 2005: copy PeerReviewInit.xsn and PeerReviewTask.xsn to DeploymentFiles\FeatureFiles folder
49. be sure feature.xml is set up correctly
a. title: Agenda Item Peer Review feature
b. description: This feature installs the Agenda Item Peer Review workflow
c. if deploying via Visual Studio 2008:
under the <ElementManifests> tag, add:
<ElementFile Location="PeerReviewInit.xsn" />
<ElementFile Location="PeerReviewTask.xsn" />
50. be sure workflow.xml is set up correctly
a. name: AgendaItemPeerReview
b. description: This is the Agenda Item Peer Review workflow
c. CodeBesideClass: AgendaItemPeerReview.PeerReviewWorkflow
d. after CodeBesideAssembly, you must have the following:
TaskListContentTypeId="0x01080100C9C9515DE4E24001905074F980F93160"
e. after TaskListContentTypeId, you must have the following:
AssociationUrl="_layouts/CstWrkflIP.aspx"
InstantiationUrl="_layouts/IniWrkflIP.aspx"
ModificationUrl="_layouts/ModWrkflIP.aspx"
f. copy initiation form's urn into the <Association_FormURN> and <Instantiation_FormURN> tags
g. copy task form's urn into the <Task0_FormURN> tag
51. deploy solution
a. Visual Studio 2005: right click project, click Properties, click Build Events, change NODEPLOY to
DEPLOY at the end of the Post-build event command line, click Build, click Rebuild Solution
b. Visual Studio 2008: click Build, then click Deploy Solution
52. The first time you deploy it, the AgendaItemPeerReview assembly is added to the GAC. The workflow.xml
file needs the assembly's public key token.
a. Start, Settings, Control Panel, Administrative Tools, Microsoft .NET Framework 2.0 Configuration
b. click Manage the Assembly Cache
c. click View List of Assemblies in the Assembly Cache
d. right-click on AgendaItemPeerReview and click Properties
e. copy the public key token and click OK
f. paste the public key token in workflow.xml where you find PublicKeyToken
g. redeploy solution (step 51)
Another method for retrieving the assembly's public key token
-------------------------------------------------------------
If you want to skip step 52, retrieve the public key token using the sn.exe utility then
update workflow.xml (step 50) with it
1. copy sn.exe from c:\program files\microsoft visual studio 8\sdk\v2.0\bin to d:\
2. change directory to d:\asp\agendaitempeerreview\agendaitempeerreview\bin\debug
3. d:\sn -T agendaitempeerreview.dll
4. copy (or type) the resulting public key token into the workflow.xml
Posts in this series:
Part 1: Introduction
Part 2: Create the initiation form
Part 3: Create the task form
Part 4: Create the state machine workflow
Part 5: Add workflow history logging
Part 6: Add task notification emails
In step 25b when I try to set the OwnerActivityName, InitiatorApproval is not available as an option for me to select. Did I miss (or screw up) a step?
ReplyDeleteIn step 34 when I type "using system.xml" intellisense doesn't pick it up and capitalize as usual, and I get errors with XmlTextReader that say I am missing an assembly or directive.
ReplyDeletehi,
ReplyDeleteif i use FullTrust For TaskForm or Initiation Form ,the Status of the Form Under 'Manage Form Template' is always "Installing".
i would slove this by giving the Trust Level to Domain.
But my Problem is i am want to call a WebService From Task Form Which i Can't able do even in Infopath Client with Domain Trust.
Pls Help me to do this,
and my boubts are can we use Full Trust Forms as Task Forms if so what are the additional steps to do this,and secound one is can we call a webservice from infopath form with out FullTrust
hi, i have solved it by storing the data connection in SharePoint DataConnection Library but give me a idea that can we use FullTrust Froms as either of the TaskForm ,Initiation
ReplyDeleteRajendra,
ReplyDeleteI am not sure I understand. Are you saying you want to make the form Full Trust? If so, Part 2, Step 16c tells you how to make the form Full Trust. To use the forms, steps 48 - 50 in this article tell you where to deploy them and how to properly configure the feature.xml and workflow.xml.