share point 2010 custom workflows - post

24
SharePoint 2010 State Machine Workflows using Visual Studio 2010 Authored By – Rupesh Tarwade Part 1 – Building a State Machine Workflow using Visual Studio 2010 INTRODUCTION Workflows are systems that manage the execution of a business process. They are primarily described as a process that manages the flow of work among various individuals, or divisions, or multiple organizations. As compared to Sequential Workflows which always progresses forward and never goes back (although using a while loop you can reiterate through same steps multiple times), the State Machine Workflows moves from one state to another, until the workflow concludes by reaching the completed state. In this example we will simulate the hiring process for an organization. Our workflow will have following steps. 1. Interview Application Received. 2. Initial Clearance. 3. Technical Clearance. 4. HR Clearance. 5. Accepted. 6. Rejected. 7. Completed. Before starting with workflow we must have a list (or a library) named Candidates on in our SharePoint Application. Metadata related to the list will have following columns. 1. Title 2. Technology 3. Experience (in months) 4. Status

Upload: rupeshtarwade

Post on 21-Apr-2015

59 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Share Point 2010 Custom Workflows - Post

SharePoint 2010 State Machine Workflows using Visual Studio 2010Authored By – Rupesh Tarwade

Part 1 – Building a State Machine Workflow using Visual Studio 2010

INTRODUCTION

Workflows are systems that manage the execution of a business process. They are primarily described as a process that manages the flow of work among various individuals, or divisions, or multiple organizations.

As compared to Sequential Workflows which always progresses forward and never goes back (although using a while loop you can reiterate through same steps multiple times), the State Machine Workflows moves from one state to another, until the workflow concludes by reaching the completed state.

In this example we will simulate the hiring process for an organization. Our workflow will have following steps.

1. Interview Application Received.2. Initial Clearance.3. Technical Clearance.4. HR Clearance.5. Accepted.6. Rejected.7. Completed.

Before starting with workflow we must have a list (or a library) named Candidates on in our SharePoint Application. Metadata related to the list will have following columns.

1. Title2. Technology3. Experience (in months)4. Status

You can add columns as required.

State Machine Workflows are essentially event driven workflows. We create a task and attach an event handler to it. We then wait till the task is performed, and after the task is completed; we make a decision based on the user input.

Page 2: Share Point 2010 Custom Workflows - Post

PREREQUISITES

1. .Net (implementation is in C#)2. SharePoint Object Model

IMPLEMENTATION

Step 1

In Visual Studio, select a SharePoint 2010 State Machine Workflow template. Fill in the details related to Name and Solution etc., and click Ok. Refer Fig 1.1.

Fig 1.1

In next window enter the URL of the site we want our workflow to run on, and click on “Next” button. Workflows can only be deployed as a Farm solution, so we do not have an option to deploy it as a Sandbox Solution.

In the next Window give the name for the workflow, and select a type of workflow we want to create. We will select a List Workflow for this example.

The next window gives us an option of associating our workflow to a list or a document library. We can choose not to associate our workflow by unchecking the association check box. However, we will have

Page 3: Share Point 2010 Custom Workflows - Post

to associate the workflow to a list or library manually later on in that case. In our example we will associate the workflow with the Candidates list.

The next window allows us to set a trigger for our workflow. In our example we want our workflow to automatically start when an item is created in the Candidates list. So we will choose that as an option and click on “Finish” button.

Step 2

Let us have closer look at the Solution Explorer.

The references required for the workflow are automatically added into the solution by the IDE. We may manually add references as and when required.

Feature1 is a feature In which our workflow will be deployed. This feature can be activated and deactivated from Site Settings

Elements .xml will be used to configure various properties of our workflow. We will have a detailed look at this file later on in the tutorial.

Workflow1.cs is the code behind file of our workflow. All the server side code goes into this file.

Refer Fig 1.2Fig 1.2

Before we go any further we need to configure the Feature Receiver of our workflow. To do that click on the Workflow Design file and press ‘F4’. This opens up the properties window of workflow. In the properties window we can see Feature Receiver Property. Open the tree node of the property and it has two properties viz. Assembly and Class Name.

Type in the following values for these properties. Please make sure that you look up the latest version of the assembly available for Microsoft.Office.Workflow.Feature and the Public Key Token related to it.

For Assembly: Microsoft.Office.Workflow.Feature, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c

For Class Name: Microsoft.Office.Workflow.Feature.WorkflowFeatureReceiver

Page 4: Share Point 2010 Custom Workflows - Post

Step 3

We will design our workflow now. On the designer surface of the workflow, drag drop “State” activity. As discusses earlier, we have 9 activities in our workflow, drop in total of 9 “State” activities from the toolbox and give them appropriate names. Refer Fig 1.3.

Fig 1.3

We need to set an initial state and a completed state for our workflow. As we want “InterviewApplicationReceived” state to be our initial state, right click on it and choose “Set as Initial State” option in context menu. Similarly right click “Completed” state and choose “Set as completed state”. This is makes “Completed” state as the final state of our workflow.

Step 4

We need to initiate our workflow. For initiating the workflow we drop an “EventDrivenActivity” in the initial state of the workflow, i.e. “InterviewApplicationReceived” state. There are two ways of add the event driven activity to our state. Either you can drag-drop the activity from the toolbox or simply right click the state and click “Add EventDriven” in the context menu.

After adding the activity, double click on the activity to go to the details of activity, give it an appropriate name from properties window. We name it as “eventDrivenActivityInitial” in our workflow.

Page 5: Share Point 2010 Custom Workflows - Post

Next step is to drop “OnWorkflowActivated” Event handler to our event driven activity. Drag and drop the “OnWorkflowActivated” event handler from the toolbox onto the activity canvas. The properties window shows properties associated with the event handler.

Fig 1.4

Let us go through the properties of the OnWorkflowActivated event handler. Most of these properties are common to all the event handler activities. Refer Fig 1.4.

A workflow instance interacts with several SharePoint objects (task lists, and documents or items) during its lifetime. In SharePoint you can have many workflow instances running at the same time and interacting with several objects at the same time. To be able to identify which workflow instance is interacting with which object, you must use an identifier that links one particular workflow instance to one particular SharePoint object. Each workflow instance must be bound to its own items. Such an identifier is called a Correlation Token. A correlation token links a workflow instance to its documents, items, and tasks. It prevents confusion between different workflow instances. We need have one correlation token for the workflow and one for each task we create during the workflow, so that when a user completes a task we have a unique identifier with which to receive any input from the user into the workflow. Make sure correlation token names are not repeated in different task. Type “InitialToken” (though the name of token can be anything you want, we generally prefer nomenclature of Task name suffixed by Token). Choose the Owner Activity as “InterviewApplicationReceived” State.

Invoked event of the OnWorkflowActivated will be fired when the workflow is activated. We can write the logic related to workflow activation in this event. In this example we use “onWorkflowActivatedInitial_Invoked” as the method name. The Visual Studio IDE will create write an event handler block in the code behind file once you press tab key after typing in the method name.

Next, click on the ellipsis in WorkflowProperties property. This opens a pop-up, choose workflowProperties from “Bind to an existing member” tab. If workflowProperties cannot be found in

Page 6: Share Point 2010 Custom Workflows - Post

this tab, move to the next tab i.e. “Bind to a new member”, select “Create Field” radio button and type “workflowProperties” in new member name textbox, and press Ok.

Next drop “SetState” Activity (choose from 3.0 tab of toolbox, there is SetState under SharePoint tab as well) just below the event handler. Set the target state name as “Initial Clearance” State. This completes the configuration of our initial state.

Step 5

Now let us configure the Initial Clearance State. Here we are going to add the “StateInitialization” activity. In StateInitialization activity, we will create the task, and configure the details like participants, due date, etc.

So drag a “StateInitialization” activity (from 3.0 tab of the toolbox) and drop it inside the Initial Clearance State. We will name this activity as “stateInitializationInitialClearanceActivity”. Double click the activity and drag “Create Task” activity (from SharePoint tab of the toolbox) and drop it inside the state initialization activity. Rename the Create Task activity to “createTaskInitialClearance”. Create a new correlation token by typing token name in the properties window. We will name the token as “InitialClearanceToken” and set owner activity as Initial Clearance State.

We need to bind a method with “Method Invoking” event. The nomenclature for method invoking event will be task name followed by an underscore (_) appened by methodInvoking, so for Initial Clearance task the method name will be “createTaskInitialClearance_MethodInvoking”.

Next we need to set the values to both TaskId and TaskProperties. Click the ellipsis in the TaskId property. It opens up a pop-up window. In “Bind to a new member” tab, choose “Create Field” radio option. Enter the name in textbox and click Ok. We create a TaskId with name “createTaskInitialClearanceTaskId”. Similarly for TaskProperties create a new field (not property) with name “createTaskInitialClearanceTaskProperties”. We are done with configuration of Create Task and State Initialization.

Step 6

Drag an Event Driven activity (from 3.0 tab of the toolbox) and drop it inside the Initial Clearance State. Name it as “eventDrivenActivityInitialClearance”. Double click the Event Driven activity, and drop “OnTaskChanged” activity (from SharePoint tab of the toolbox) and name it “onTaskChangedInitialClearance”. Create fields for AfterProperties and BeforeProperties (follow the process similar to creating TaskId and TaskProperties) with names “onTaskChangedInitialClearanceAfterProperties” and “onTaskChangedInitialClearanceBeforeProperties” respectively.

Now in Correlation Token field, choose the same token that we had associated the Create Task activity with. That allows the workflow instance to understand with which task this event handler is associated with. In our case we will choose “InitialClearanceToken” as the correlation token. Most of the workflow

Page 7: Share Point 2010 Custom Workflows - Post

errors are related to incorrect assigning of the correlation token. Hence we need to be extra careful when working with the correlation tokens.

Associate a method with Invoked event of the activity, we type in “onTaskChangedInitialClearance_Invoked” as the method name. We also need to bind the TaskId for this activity but we won’t be creating a new TaskId, instead we will bind the TaskId that we created in the Create Task activity. For that choose “Bind to an existing member tab” in the pop-up, select the TaskId that we had created in Create Task activity, and click Ok.

So to re-cap of what we have achieved so far, we created State, added a StateInitialization activity. Inside the StateInitialization Activity, we created a Task and gave it a correlation token. On MethodInvoking event of the CreateTask activity we have associated a method. We will write some logic in this method. Then we added an EventDriven activity to the State. In the EventDriven activity we have dropped an OnTaskChanged activity. We created the required fields for this activity, and gave it the same correlation token that we created in CreateTask activity. We associated a method with Invoked event of the OnTaskChanged activity. This method will be fired when user performs the task assigned to him.

Step 7

Now once the user performs a task, in this scenario, when the user indicates whether the received resume is approved or rejected, we need to perform some action based on it. A default task list item looks like Fig 1.5. We can customize the task list item, and use InfoPath form or an ASPX form instead of the default task list item.

Fig 1.5

For now if user types in “Approved” in the description column of the task, then we will proceed with next step of the workflow; else we will stop the workflow. So we drop an IfElse Activity (From 3.0 tab of the toolbox) below the OnTaskChanged activity, inside the EventDriven activity.

Page 8: Share Point 2010 Custom Workflows - Post

Select IfElseBranchActivity1, in properties window we have a Condition Property, select Code Condition for condition. Open the Condition tree node, in the left node property, type the name of the method which will have the logic to handle the condition. For this example we type in “InitialClearanceApprovalProcess” as the code condition. Now drop SetState Activity (from 3.0 tab of the toolbox) inside the IfElseBranchActivity1 and select the next state as the TargetStateName. In this example, “TechnicalClearance” will be the target state. Leave the IfElseBranchActivity2 as it is.

Step 8

We are done with the designing part of the workflow for this state, now we need to write the logic in code-behind file. So right click on the designer and select View Code from the context menu, or simply press F7 on the designer surface.

You can see all the fields and methods that we created from designer surface have been created in the code-behind file.

The first method is associated with OnWorkflowActivated activity. We won’t add any implementation logic in this method as of now.

Next, the method associated with Initial Clearance State -> State Initialization -> Create Task. We have associated a method “createTaskInitialClearance_MethodInvoking” with this event. In this event we will configure the title of the task, the users or group that will perform the task, due date of the task, and other such details.

Next, the method associated with Initial Clearance State -> Event Driven -> OnTaskChanged. We have associated a method “onTaskChangedInitialClearance_Invoked” with this event. In this method we will write the logic of the process we want to follow once the user has completed the task.

private void createTaskInitialClearance_MethodInvoking(object sender, EventArgs e){

try { //Create a new TaskId for the Task

this.createTaskInitialClearanceTaskId = Guid.NewGuid();

//TaskProperties field is used to configure the Task Details. this.createTaskInitialClearanceTaskProperties.Title = "Initial Clearance";

//You can assign a Task to a user or to a group. Here we assign the task to HR-Group

this.createTaskInitialClearanceTaskProperties.AssignedTo = "HRGroup"; this.createTaskInitialClearanceTaskProperties.DueDate =

DateTime.Today.AddDays(5.0); } catch (Exception ex) {

//Logging is used so that we can debug the errors in the workflow. System.Diagnostics.EventLog.WriteEntry("Recruitment Workflow", ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);

LogToHistoryListActivity log = new LogToHistoryListActivity(); log.HistoryDescription = ex.StackTrace;

Page 9: Share Point 2010 Custom Workflows - Post

If we have a look at onTaskChangedInitialClearanceAfterProperties and onTaskChangedInitialClearanceBeforeProperties field, they are objects of SPWorkflowTaskProperties Class. As the name suggest this class represents the properties of a Workflow Task. We will assign the values from task to these objects so that we can use them other methods.

In this example we will set the task as complete, by setting the value for PercentComplete Property to 1.0.

Now we will implement the logic for Code Condition. The IfElse Activity for the task was associated with the InitialClearanceApprovalProcess method.

We have set the result of if-else to true if user types in “Approved” in the description field of the task item, else the result is set to false. In later part of this tutorial we will see how to use a custom task form

private void onTaskChangedInitialClearance_Invoked(object sender, ExternalDataEventArgs e{

try{

this.onTaskChangedInitialClearanceAfterProperties = this.onTaskChangedInitialClearance.AfterProperties;

this.onTaskChangedInitialClearanceBeforeProperties = this.onTaskChangedInitialClearance.BeforeProperties;

//Set the PercentComplete property to 1.0 (i.e. 100%) to indicate that the task has been completed.this.onTaskChangedInitialClearanceAfterProperties.PercentComplete = (float)1.0;

}catch (Exception ex){

…}

}

private void InitialClearanceApprovalProcess(object sender, ConditionalEventArgs e){

try { if (this.onTaskChangedInitialClearanceAfterProperties.PercentComplete == 1.0) { if (this.onTaskChangedInitialClearanceAfterProperties.Description.Contains("Approved")) {

e.Result = true; }

else { e.Result = false; }

} else { e.Result = false; }}

Page 10: Share Point 2010 Custom Workflows - Post

to get these values. So we can have a drop-down control for user to indicate whether the candidate it approved or rejected.

Step 9

That’s all the code we have to write to completely configure one task. Perform Step 5 to Step 8 for the remaining tasks.

You can see below a snapshot of the completed workflow.

Build and deploy the workflow.

Page 11: Share Point 2010 Custom Workflows - Post

Part 2 – Custom Task Forms using InfoPath 2010

INTRODUCTION

As mentioned in part 1 of the tutorial, we can use custom task forms instead of the default task forms provided by SharePoint. Default forms have fixed number of fields which cannot be altered. Using custom forms we can gather the required information from the user and they also make the process more dynamic and flexible.

In this part of the tutorial we will see how to use InfoPath 2010 to design custom workflow task forms. InfoPath provides a richer interaction experience in which the user can interact with the workflow.

To handle the custom task forms in InfoPath, SharePoint 2010 links the hyperlink that displays a workflow form to an ASPX page that contains an Office Forms Services Web Part. The logic to handle the forms is written in this Web Part. This Web Part is configured such that it can receive as well as submit data. So, if we want to show some information on the InfoPath form, from a SharePoint List (or library) we create a Receive data connection in InfoPath form. Similarly to copy data from InfoPath form to the SharePoint List (or library) we create a Submit data connection.

We specify the custom forms we want to use in the workflow template definition (i.e. Elements.xml) rather than the workflow itself. This involves setting two elements, the form URL, and URN of the custom InfoPath 2010 form. The form URL, needs to be associated with a proper workflow process e.g. association, initiation, modification, etc. This linking is important so that the appropriate ASPX hosting page is included in SharePoint. Next, you add an element specifying the URN for the custom InfoPath 2010 form for that type of workflow process.

Before we proceed any further, we will add few more columns to the SharePoint List. The list has following columns.

1. Title2. Technology3. TotalExperience4. CandidateStatus5. InitialRemarks6. TechnicalInterviewRemarks7. HRRemarks8. InitialClearanceBy9. InitialClearanceOn10. TechnicalClearanceOn11. HRInterviewBy12. HRClearanceOn13. TechnicalInterviewAssignedTo

Page 12: Share Point 2010 Custom Workflows - Post

DESIGN

Let us start by designing an InfoPath form for our First task, i.e. Initial Clearance.

Open Microsoft InfoPath Designer 2010; double-click on blank form in new tab. This opens window with a blank form. For Initial Clearance Task, we will give the user an option approve or reject the candidate. If the user chooses to approve the candidate, then he/she will have to assign a Technical Interview Panel and a HR Interview Panel, else the user enters the comments for rejection, and the workflow is terminated.

Design the table structure you want to use for your task form. You can use predefined structures available in Page Layouts of Page Design Tab. Click on Show Fields button in Data tab of InfoPath Designer.

Drag-drop the controls on the form as required. At bottom of the page we will have a button control which will fire the Submit rule in InfoPath.

To add values to the Status dropdown list, right click on Status dropdown list and select Drop-Down List Box Properties. Using Properties you can add or modify the values as required. Rename the fields appropriately as we will be using these names in our code behind file in Visual Studio.

We also have Contact Selector on our InfoPath form. To configure the Contact Selector to use the user available in SharePoint, right click the control and go to properties. In SharePoint Server tab, enter the URL of the SharePoint site. This way the control will be able to pick up the users from SharePoint.

Double-click the “Complete Task” button. The Control Properties tab opens up. Click on “Rules” button in this tab. It opens a Rules Explorer, in this window, click “New” button, and select Action menu. This configures a rule for this button. In “Run these actions” panel, click on “Add” button, and select “Submit Data” menu option. This opens a pop-up window for Rule Details. In Data connection section, on clicking

Page 13: Share Point 2010 Custom Workflows - Post

the Add Button opens up another pop-up window to configure a data connection. Select “Create a new connection to:” radio button, and “Submit data” radio button. Click on Next, select “To the hosting environment, such as an ASP.NET page or a hosting application” option. Click on Next, and let this connection be a default connection, and click on Finish. Close the Rule Details window by clicking Ok.

We will have to close the window after the user clicks on Complete Task button. So, in Rules Explorer, click Add Button once again and select “Close the form” option. You can preview the form and make changes accordingly. Refer Fig for completed InfoPath Form.

IMPLEMENTATION

Step 1

In Visual Studio 2010, open the Solution we created in previous part. Right click on the workflow (RecruitmentWorkflow) folder and click add -> new item. Select module from SharePoint 2010 node. We will name it as Forms. Now right click newly created module and add an existing item. Browse the InfoPath form we created and add that to the Forms module. If you observe the Elements.xml file inside the Forms module, Visual Studio has added a new node under module corresponding to newly added InfoPath form.

In main the main feature manifest file (Feature1.Template.xml), add the following nodes inside the property node, if they are missing.

<Property Key="GloballyAvailable" Value="true" /><Property Key="RegisterForms" Value="Forms\*.xsn"/>

Page 14: Share Point 2010 Custom Workflows - Post

Step 2

We need to configure the Elements.xml file of the workflow, add details like URN of the InfoPath form Association Data, etc. Before doing that, we need to change the InfoPath form and publish our InfoPath form.

To configure the settings, in File menu, select Info tab. In the “Form Information” panel, select “Advanced form options”. In the “Security and Trust” tab uncheck the “Automatically determine security level” checkbox and select “Domain” radio button. Click Ok and close the form.

To publish the InfoPath form, in File Menu, in Publish tab, click on “Network Location” button. Browse the path on the file system, and click Next button. In the next window of the wizard, clear the textbox (very important as SharePoint does not recognize the form as published if this textbox is not empty, hence it will not render the form). This will pop-up an alert message, click Ok and continue. Complete the publishing process by clicking “Publish” button.

To find the URN of the InfoPath form, go to File Menu of Published InfoPath form (make sure it is the published InfoPath form), on the right hand side panel, click “Form Template Properties” button. It opens up a pop-up window, it ID field in this window is the URN of the InfoPath form.

In Elements.xml file we need to set the TaskListContentTypeId to the following:

TaskListContentTypeId="0x01080100C9C9515DE4E24001905074F980F93160"

This content type, included in Microsoft SharePoint Server 2010, specifies custom task display and edits forms that include an Office Forms Server control for rendering InfoPath forms.

Next, add an element to the Metadata element of the workflow template definition. This element is in form of <TaskN_FormURN>URN Value</TaskN_FormURN>, where N represents the integer value we assign to that task type within the workflow, and URN Value is the URN string we get from the InfoPath form.

In addition to this we also need to add the Association Data to our elements file. We will pass dummy data to the workflow as we do not have any data to be passed to the workflow while association. Add below code after Categories node in Elements.xml

<AssociationData> <Data></Data> </AssociationData>

Refer Fig for Elements.xml after configuration.

Page 15: Share Point 2010 Custom Workflows - Post

Step 3

If you are well versed with InfoPath 2010, you can create views in the same form for various tasks that we have in our workflow. Alternatively you can create a new form for each task and add it to the solution in similar manner. Adding new forms will only change the MetaData element of the Elements.xml file (Additional URNs will have to be added corresponding to the new InfoPath forms).

We have created different forms for tasks in our example. The next task, (if Initial Clearance is approved) will be Technical Clearance Task. Now, we want to show the comments of Initial Clearance in the Technical Clearance task, so that Technical Panel has additional information about the candidate.

To achieve this, we must be able to send information from Workflow to the InfoPath form. This can be done using Data connection in InfoPath. We need to create a XML file named “ItemMetadata.xml” which will contain the names of the fields we want to be available in InfoPath. Then we create a new Data Connection in InfoPath for receiving the data. The name of columns in ItemMetaData.xml should start with “ows_”. You pass multiple values to the InfoPath form using a single ItemMetaData.xml file. Refer Fig.

To add this xml file to InfoPath form, in InfoPath designer select Data tab and add new data connection by clicking Data Connection button. In Pop-up window click Add button, select Receive Data in next window, click Next button. Select XML Document option, in the next window, browse the xml file, click next, and finish the configuration with default values selected.

Page 16: Share Point 2010 Custom Workflows - Post

In Fields Explorer window, the drop-down shows two connections now. You can choose to drag and drop fields from the newly configured data connection onto the InfoPath form. Refer Fig.

Step 3

In Visual Studio, the MethodInvoking event of Create Task activity in the Initial Clearance State will be called when the task is created. We specify the details of the task in this event. For the task to be associated with a specific InfoPath form we need to configure the TaskType property of TaskProperties field of this task. For our example we will have following code. Here the TaskType we correspond to the number we have associated with the URN while entering it in the Elements.xml

//Task Type corresponds to TaskURN specified in Elements.xmlthis.createTaskInitialClearanceTaskProperties.TaskType = 1;

Make sure that the URN specified in the Elements.xml maps to the same task in code behind file; else workflow will encounter an error while opening the task form

To send data from SharePoint to InfoPath form we have setup a receive data connection in InfoPath forms. We can achieve this by setting up the ExtendedProperties of the task property field in the same event i.e. MethodInvoking event. ExtendedProperties is a hashtable (Key-Value pair) and the key in our case will be the name of field we have used in ItemMetaData.xml and value will be the value of remarks of previous stage.

The Invoked event of EventDriven activity will be called after the user has performed the task. Once the task has been completed we need to access the values entered by the user on the InfoPath Task forms. We can access these values by using the ExtendedProperties property of the AfterProperties field of this task. Below are the code snippets for all the events and methods associated with Technical Clearance task.

Page 17: Share Point 2010 Custom Workflows - Post

MethodInvoking Event:

private void createTaskTechnicalClearance_MethodInvoking(object sender, EventArgs e) { try { //Create a new TaskId for the Task this.createTaskTechnicalClearanceTaskId = Guid.NewGuid();

//TaskProperties field is used to configure the Task Details. this.createTaskTechnicalClearanceTaskProperties.Title = "Technical Clearance";

//You can assign a Task to an user or to a group. Here we assign the task to HR-Group

SPListItem listItem = this.workflowProperties.Item; //Write the remarks value to the list item if (listItem != null) { //Check if TechnicalInterviewAssignedTo Field has a value, and Assign this Task to the value of this Field if (listItem.Fields.ContainsField("TechnicalInterviewAssignedTo")) {

this.createTaskTechnicalClearanceTaskProperties.AssignedTo = listItem["TechnicalInterviewAssignedTo"].ToString();

}

//To send InitialRemarks to the InfoPath Form, we add it to the ExtendedProperty of the TaskProperties //ExtendedProperties is a hashtable (Key-Value pair). //The Key will be the name of field we have used in ItemMetaData.xml and Value will be the value of remarks if (listItem.Fields.ContainsField("InitialRemarks")) { if (this.createTaskTechnicalClearanceTaskProperties.ExtendedProperties.ContainsKey("InitialComments")) {

this.createTaskTechnicalClearanceTaskProperties.ExtendedProperties["InitialComments"] = listItem["InitialRemarks"].ToString();

} else {

this.createTaskTechnicalClearanceTaskProperties.ExtendedProperties.Add("InitialComments", listItem["InitialRemarks"].ToString());

} } }

//Task Type corresponds to TaskURN specified in Elements.xml this.createTaskTechnicalClearanceTaskProperties.TaskType = 2;

this.createTaskTechnicalClearanceTaskProperties.DueDate = DateTime.Today.AddDays(2.0); } catch (Exception ex)

Page 18: Share Point 2010 Custom Workflows - Post

Invoked Event:

Condition Handling - TechnicalClearanceApprovalProcess:

private void onTaskChangedTechnicalClearance_Invoked(object sender, ExternalDataEventArgs e){

try{

this.onTaskChangedTechnicalClearanceAfterProperties = this.onTaskChangedTechnicalClearance.AfterProperties;

this.onTaskChangedTechnicalClearanceBeforeProperties = this.onTaskChangedTechnicalClearance.BeforeProperties;

//Set the PercentComplete property to 1.0 (i.e. 100%) to indicate that the task has been completed.

this.onTaskChangedTechnicalClearanceAfterProperties.PercentComplete = (float)1.0;

//Get the value of Remarks Column (InfoPath Form) by using the ExtendedProperties property

string remarks = this.onTaskChangedTechnicalClearanceBeforeProperties.ExtendedProperties["Remarks"].ToString();

SPListItem listItem = this.workflowProperties.Item;

//Write the remarks value to the list itemif (listItem != null && listItem.Fields.ContainsField("TechnicalInterviewRemarks")){

listItem["TechnicalInterviewRemarks"] = remarks;}

}catch (Exception ex)

private void TechnicalClearanceApprovalProcess(object sender, ConditionalEventArgs e){

try{

if (this.onTaskChangedTechnicalClearanceAfterProperties.PercentComplete == (float)1.0 && this.onTaskChangedTechnicalClearanceAfterProperties.ExtendedProperties["Status"].ToString().Contains("Approved"))

{e.Result = true;

}else{

e.Result = false;}

}catch (Exception ex){ //throw ex;}