Step by Step Tutorial. Creating Workflows for Windows Sharepoint Services and MOSS2007 (part 11/20). Modification Forms

 

 

image

Step by Step Tutorial. Creating Workflows for Windows Sharepoint Services and MOSS2007 (part 11/20). Modification Forms

 

By Serge Luca

MVP Connected System 

image

 

 

 

 

Introduction

Modification forms allow us to reassign a workflow task to another user.

3 parts in this article:

  1. What are Modification Forms
  2. Introduction to the EventHandlingScope activity
  3. Adding a Modification form to an existing workflow

Part 1. What are Modification Forms

To illustrate this concept, I will run a workflow provided with the downloadable version of the Sharepoint Sdk (1.3 in my case).

By default, the samples are installed in the following location :

 

image

 

  • Try to open the ModificationSample project;if you try to compile it, you will get a compilation exception since this project references another assembly provided with the sdk as well: ECMActivities; recompile the ECMActivities project and resolve the reference in ModificationSample.

 

  • If you doubleclick on the Workflow1 class you’ll get the following model(I will describe the different elements of this workflow in the second part of this post, don’t worry).

image

 

  • If we compare this model to the workflows we did in the previous tutorials, we’ll notice 2 new activities: EnableWorkflowModification (a Sharepoint activity) and EventHandlingScopeActivity (which is part of the base activity library of Workflow Foundation).

 

  • Let’s click on the manifest file (workflow.xml), you will notice a couple of new tags :

image

Several Infopath forms are also provided with this example and one of them which is referenced in the Modification element of the manifest is the Modification form:

image

 

  • In the Install.bat file, replace http://localhost with our site collection url and run it.
  • Associate the workflow with a Sharepoint list and start the workflow. You’ll notice that the Reviewer is U2UCOURSE\serge :

image

The workflow is in progress; if you click on its status:

image

You’ll be redirected to this form where you have the option to reassign the task:

image

A task has been created and assigned to serge:

image

  • Let’s reassign the task to john by clicking on the "Update task owner" hyperlink described above:

image

 

  • If you get back to the task list, you will notice that the task owner has been changed appropriately:

image

 

  • Now, if John click on its task, the task form will show up; if he clicks in the "completes" field, the workflow will complete; there is a small bug in the application, however : john’s task doesn’t complete, it is still necessary to add a Sharepoint  "CompleteTask" activity :

image

..and to link it to the task Id

image

…and the correlation token to "taskToken1" :

image

Recompile, and (re)install the workflow.

 

Part 2. Understanding the EventHandlingScopeActivity

The EventHandlingScopeActivity is an activity that allows a workflow (or part of a workflow) to run while listening to events; it is a kind of (but just a kind of) ListenActivity or ParrallelActivity.

Ok, I’ll give you a quick tutorial on it:

 

  • Create a Workflow Console application (Sequential workflow) and drag and drop a EventHandlingScopeActivity from the toolbox into the workflow surface:

image

 

  • Drag and drop a Sequence activity into the EventHandlingScope activity

image

 

  • Drag and drop a Delay activity followed by a code activity:

 

image

 

  • Set the TimeoutDuration of the delayActivity to 20 seconds and in the codeActivity1 associated code, display "Main Application Completed".

These activities can be considered as part of the main flow of the workflow sequence.

In the background however, the workflow can listen to events while the main flow is not completed: in the case of our Sharepoint workflow the potential event that could come up is the OnWorkflowModified event which is triggered when a task is reassigned to another owner for instance.

 

  • To keep it simple, I will use another delay activity (it must be any activity implementing the IEventActivity interface and that’s the case of the delay activity but also the case of all  "green" Sharepoint activities : these green activites are derived from HandleExternalEvent activity, which implement IEventActivity). The activity must be encapsulated in an EventDriven activity (the first activity of an EventDriven activity must implement IEventActivity); it is like a catch for an event (instead of a catch for an exception). Lets go for it.

 

  • To show the event side of the EventHandlingScope activity, right click on it and select "view Event Handlers" as following:

 

image

You’ll see this :

image

  • Drag and drop an EventDriven activity (or several if you need to listen to several events).

image

 

  • Lets drag and drop a Delay activity (and set its timeout property to 10 seconds, to make sure the event will fire before the main flow completes).
  • Just after the Delay activity, add a code activity and display the message "delay event fired in the background" in the associated code:

image

 

  • Run the application and you will get something like this

image

 

Part 3. Using a Modification form in an existing workflow

 

  • I will assume that you know how to create sharepoint workflows and how to link Infopath Forms to the workflow association, Initiation and task changing state; if it is not the case, follow the previous versions of my sharepoint workflow tutorials.
  • Add an existing Sharepoint workflow project to the current solution

 

Step 1.Add to your solution the HelloWorldSequential workflow provided with the sdk ; in its install.bat file, replace http://localhost with your site collection url, deploy it and play with it.

Step 2.Add the ModSimpleModificationForm.xsn Infopath Form of ModificationSample (sdk)  to the location of the HelloWorldSequential project.

Step 3.Register the Modification forms in workflow.xml:

 

-generate a Guid with Guidgen (Visual Studio-Tools-Create GUId menu)

-after the <Task0_FormURN> elements, add 2 elements: <Modification_xxx_FormURN> and <Modification_xxx_Name> where xxx is the generated Guid like this:

       <Modification_bf35e820-5070-4e33-bc91-de30388e0b7e_FormURN>

          urn:schemas-microsoft-com:office:infopath:ModSampleModificationForm:-myXSD-          2006-05-17T01-22-06

      </Modification_bf35e820-5070-4e33-bc91-de30388e0b7e_FormURN>

      <Modification_bf35e820-5070-4e33-bc91-de30388e0b7e_Name>

              Update task owner

      </Modification_bf35e820-5070-4e33-bc91-de30388e0b7e_Name>

 

 

Step 4.Run Install.bat, associate the workflow with a list and run it on a list item. If you click on the workflow status (when the workflow is "in progress", you will notice that the "update task owner" message is not visible; we need to add another functionality (next step).

 

Step 5.Add the EnableWorkflowModification activity just before the CreateTask activity :

 

image

 

  • set its correlation token to the current token, "modifToken" and the OwnerActivityName to HelloWorldSequential.
  • set its ModificationId property to the Guid defined before: bf35e820-5070-4e33-bc91-de30388e0b7e
  • compile, install and test the workflow : the workflow will crash and you will get an "an error has occured" message.
  • try to visualize the error message by setting up a FaultHandler activity in the Fault Handler view of the workflow and  log the error message in the workflow history by using a LogToHistoryList activity :

 

image

  • Set the FaultType property of the FaultHandler activity to System.Exception and the HistoryOutCome property of the LogToHistoryList activity to the exception message property as following:

image

You will get a rather unclear exception (if you click on the workflow completed status hyperlink):

image

Step 6. Add a sequence activity in yhe EventhandlingScope activity and move the EnableWorkflowModification activity and the other  activities that follow (disable the SendMail, LogToHistoryList and CodeActivity) into an EventHandlingScope activity (group them all in a sequence activity):

image 

  • in the CorrelationToken property of the grouped activities, set the owner activity property to the EventHandlingScope activity name
  • Build and test, you will get the following (same) error:

 image

  • In the EventHandlingScope activity Event Handler, add an EventDriven activity and a OnWorkflowActivated activity like this:

 

 image

  • Set the OnWorkflowModified activity CorrelationToken property to "modifToken".
  • Set the ModificationId to the value defined above.
  • Build, run and test the  workflow, and this time the workflow status will be "in progress" which is a good sign ! 
  • If you click on the workflow status, you will see the "Update task owner" hyperlink:

image

  • However, if you click on the "Update Task owner" hyperlink, you will get an Infopath Form exception; indeed the contextData, which is supposed to contain the data to be transferred to/from the modification form is not yet ready. We will manage this in the next step.

Step 7. Sending data to the modification form

As we did it in one of the  the tutorial, let’s use xsd.exe to generate a class that will be mapped to the modification form.

  • Open the modification form with Infopath and use the "save as source"  menu; this will generate (among others), an .xsd file.
  • generate the mapping .net class : xsd.exe myschema.xsd /c
  • rename the generated class file as  "modificationForm.cs"
  • add the file to the workflow project
  • create an helper function to serialize an Infopath form schema:

        private string SerializeModificationData(ModificationForm form)

        {

            using (MemoryStream stream = new MemoryStream())

            {

                XmlSerializer serializer = new XmlSerializer(typeof

                                                 (ModificationForm));

                serializer.Serialize(stream, form);

                return Encoding.UTF8.GetString(stream.GetBuffer());

            }

        }

  • select the EnableWorkflowModifcation actvity and bind its ContextDate property to a new workflow field that we will call _ContextData.
  • at the end of the OnWorkflowActivated event handler, add the following lines :

            ModificationForm modifForm = new ModificationForm();

            modifForm.taskOwner = assignee;

            this._ContextData = this.SerializeModificationData(modifForm);

 

  • Build, install and test the workflow : click on the "Update Task owner" link and the modification form will show up:

image

We still need to be able to take the modification data into account.

Step 8. Sending data from the modification form

  • Everytime the modification form data will be submitted, the OnWorkflowModified activity will be triggered.
  • To get the new task owner, we need to deserialize to data from the Modification form.
  • To manage this, create a function to deserialize Infopath form data:

        private ModificationForm DeserializeFormData(string xmlString)

        {

            using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes

                                                                    (xmlString)))

            {

                XmlSerializer serializer = new XmlSerializer(typeof

                                                        (ModificationForm));

                ModificationForm data = (ModificationForm)serializer.Deserialize

                                                        (stream);

                return data;

            }

        }

  • Define a newAssignee data member in the workflow class :

         private string newAssignee = default(string);

  • Switch to the EventHandler of the EventHandlingScope activity
  • Add an eventHandler to the Invoked event of the OnWorkflowModified activity
  • Deserialize the Infopath form as following:

     private void onWorkflowModified1_Invoked(object sender, ExternalDataEventArgs e)

     {

            ModificationForm modForm = this.DeserializeFormData(this._ContextData);

            this.newAssignee = modForm.taskOwner;

     }

  • We still need to update the existing task(s) by using an UpdateTask activity: drag & drop an Update Task activity just after the onWorkflowModified1 activity:

image

  • Link the UpdateTask activity to the created task activity by "databinding" its TaskId property to the workflow taskId property and by "databinding" its TaskProperties to the workflow member afterProps (which is databound to the afterProperties property of the onTaskChanged1 activity).
  • Set also its correlation token to modifToken.
  • Set an event handler to the updateTask1 activity with the following code that will modify the Assigned to user :

       private void updateTask1_MethodInvoking(object sender, EventArgs e)

        {

            afterProps.AssignedTo = this.newAssignee;

 

        }

step 9. Testing

  • Build deploy and test the workflow; it is very important to make sure the task data are updated even when you redirect the form to another user:

 

 image

image

Get to the Tasks list

image

Click on the title hyperlink and modify the instructions in the form as following (here I’ve added "modified by admin") :

 image

Click on the Submit button.

Get back to the original list, click on the workflow status ("in Progress)

image

Update the task owner ("here to Serge)

image

Go to the Tasks list, make sure the task owner has been modified

image

Click on the Title hyperlink, should get the modified data in the form :

image
 

Congratulations !!!


This hands-on training is the property of Redwood S.L sprl and may not be organized in class or in group without the prior written permission of Serge Luca. Should you wish to organize this hands-on training in your company or institution, please contact Serge Luca  first to enter into a licence agreement. Each trainer or teacher using this hands-on training should have a licence agreement. Please ask your trainer or Serge Luca whether he or she has entered into a licence agreement with Redwood S.L sprl.

The hyperlink to this hands-on training may be placed on your website for free, on the condition that the name Serge Luca is clearly mentioned in the reference. Please send us a mail containing the link to the web page our reference is used on.


Leave a comment