You are on page 1of 60

MICROSOFT CORP.

Building Document
Workflows in SharePoint
2007
Part 4: Creating, Emailing and Sending User Tasks
with ASP.NET forms (Task Edit Form)
Robert Shelton
9/17/2007
Table of Contents

WHY IS THIS WORKSHOP SO LONG? ............................................................................................... 3

THE WORKSHOP SCENARIO............................................................................................................... 4

MY DEVELOPMENT ENVIRONMENT & SETUP.............................................................................. 5

THE WORKSHOP STEPS....................................................................................................................... 7

Building your Task Edit form .................................................................................................................................. 7

Writing the code-behind for your Task Edit Form ................................................................................................ 10


Namespaces and using statements .........................................................................................................................10
Method stubs to handle the forms Button controls ...............................................................................................11
Declarations for the “Class Level” variable .............................................................................................................11
Adding methods to make the Instantiation Form work ..........................................................................................12
Adding code to make the Submit and Cancel Buttons work ...................................................................................15

Storing the User data in the Task list ................................................................................................................... 16


Creating the Custom Content Type file ...................................................................................................................17
Creating the Custom Columns file ...........................................................................................................................23
Creating the Feature.xml file ...................................................................................................................................26
Saving and deploying your new feature to the Portal.............................................................................................29
All done with the Task Form/Custom Content Type ...............................................................................................34

Building the Workflow ......................................................................................................................................... 34


Designing the workflow...........................................................................................................................................34
Issuing and monitoring a new task ..........................................................................................................................36
Adding our Task Activities .......................................................................................................................................41
Updating the File Copy Option Activities ................................................................................................................51

TESTING THE WORKFLOW .............................................................................................................. 53

WRAP UP ................................................................................................................................................ 60

WHERE TO GET MORE INFORMATION ......................................................................................... 60

LEARNING AND RESEARCH RESOURCES USED FOR THIS WORKSHOP ............................. 60

2
Why is this workshop so long?
I have to admit that this is the longest workshop series that I’ve ever written. But don’t be discouraged,
which is why I put this at the top, because most of it is screen shots. I am a fervent believer that when I
am trying to learn something, I want to see screen shots of every form, web page, and code that was
written. I also believe that the code should be documented and explained as well as possible, which is
why this workshop is so BIG!

Happy coding,

Robert Shelton

3
The Workshop Scenario

The purpose of this segment of the workshop series is to show you how to get data into the Workflow
from “Custom User Forms.” It turns out that SharePoint allows developers to prompt the administrators
and users for information at several stages along the workflow:

 When the workflow is connected to a SharePoint List or Document Library. This is done by
building and attaching a SharePoint Association Form which allows the Administrator, or a user,
who connects the workflow to a SharePoint List, to set “default” values and behavior for the
workflow.
 Just before the workflow is started, which gives the developer an opportunity to prompt the
user for information that might be needed at the start of the workflow and/or give the user an
opportunity to override the default values defined via the Association Form. This is done by
providing the user with a custom Instantiation/Initiation form.
 At anytime during a running workflow, by providing a Modification form.
 By assigning users Tasks (think” Outlook Tasks”), using Task-Edit forms.

For Part 4 of the series, we will focus on one of the highest requested features of SharePoint Workflow:
Sending and handling User Tasks. Fortunately, the SharePoint Team has given us a great set of tools
(workflow activities) to handle this request, and a custom form (Task Edit Form) that we can create to
request information.

Note: Since many of the steps for building Task Edit forms and creating and setting Activities and
Activity properties are the same as the forms that we’ve built in the previous workshops, I won’t take
snap-shots of each step, nor will I explain some of the basic steps as I have in the previous workshops.
In this workshop, I want to focus on the new steps that are specific to sending/handling User Tasks.
Please refer to, and work through, the previous workshops if you have trouble following along with
some of the basics.

4
My Development Environment & Setup

Just in case you find yourself facing screens that look different than mine, or not seeing certain screens
at all, I feel that it’s important to describe my Development Environment. Although my setup is not
required to do SharePoint Development, I would STRONGLY, STRONGLY suggest that you setup your
developer environment in a very similar way.

Note: For reference sake, I will define “SharePoint” as either Windows SharePoint Server 3.0 (WSS 3.0)
and/or Microsoft Office SharePoint Server 2007 (MOSS 2007). The demonstration that I am building will
work on both setups.

Here’s my setup:

1. Use a Virtual Desktop Environment, I cannot stress that enough.

I use Virtual PC 2007 (which you can get free from www.microsoft.com/download, search for
Virtual PC 2007), but you can use Microsoft Virtual Server (also free from Microsoft, but it is
typically installed on Servers versus desktops). You can also use some non-Microsoft Virtual
Machine technology, there are several out there including Parallels and VMWare. I cannot
attest to their capabilities, pricing, etc., since I don’t use them.

2. Install Windows Server 2003 or Windows Server 2008 (in Beta as I write this).

Install it into your Virtual Desktop Environment. The directions for installation vary by
product, so see your Virtual Desktop instructions for that.

3. Install Windows SharePoint Server 3.0 (WSS 3.0).

You can also get this freely from Microsoft, if you have a legal license for Windows Server
2003 or Windows Server 2008. You can get this from www.microsoft.com/download, search
for “WSS 3.0”.

4. Install Visual Studio 2008 (Beta 2 at the writing of this document)

I have chosen to use Visual Studio 2008 instead of Visual Studio 2005 with the Workflow
Extensions for SharePoint. The reasons are many fold, but primarily because it’s “easier” to
do SharePoint development and debugging with Visual Studio 2008.

At the time of writing this document, you can download Visual Studio 2008 Beta freely at
www.microsoft.com/download, by searching for “Visual Studio 2008”. Now, that being said,
if you choose to use Visual Studio 2005, then you will need the add-ins for Visual Studio 2005
found here (http://www.microsoft.com/downloads/details.aspx?FamilyID=19f21e5e-b715-
4f0c-b959-8c6dcbdc1057&DisplayLang=en), and you may need other pieces (I am not sure
since I am not using it). You can find out more about setting up on Visual Studio 2005 by
searching the web.

Whether or not you use Visual Studio 2008, as I am, or use Visual Studio 2005, most of what
you will see in this document will work with the exception of:

5
- How you deploy your solution in Visual Studio 2008 is easier and different than Visual
Studio 2005 (See this document for steps: http://msdn2.microsoft.com/en-
us/library/ms460303.aspx).
- How you debug your solution in Visual Studio 2008 is easier and different than Visual
Studio 2005 (See this document for steps: http://msdn2.microsoft.com/en-
us/library/ms455354.aspx).

5. Lastly, you should download the WSS 3.0 SDK, which is essentially the “Help File” for
SharePoint Development. You can get the SDK freely from www.microsoft.com/download,
search for “WSS 3.0 SDK”

6
The workshop steps

Building your Task Edit form


As I said earlier in the document: I won’t go over the steps with the level of detail that I went into for the
Instantiation Form in Part 3 of the workshop series, because building a Task Edit form is exactly the
same as an Instantiation form. If you have not built an Instantiation form as of yet, please refer to
Workshop Part 3, Page 7: Building an Instantiation Form.

In Part 2 of the workshop series, I laid out two approaches to designing a SharePoint Custom Workflow
Form: Two forms (one for Design and one for Production) with one code-behind, or “hand scripting”
form, using the Source View of Visual Studio. In that workshop, I chose the first option to get around
issues with how SharePoint handles Master Pages. Since we’ve already done that leg work, I will just
reuse that Form (Script) code to create and slightly modify my Instantiation Form.

Steps:

- Open the Visual Studio project for the Workflow Forms (not the Workflow Project itself),
created in Part 2 of the series. If you did not do that workshop, please refer to the section
called: “Creating your ASP.NET Solution on the SharePoint Development Server”, which will
explain the best way to setup your project.

If you did Part 3 of the workshop, your screen solution should look something like this:

- Create a folder to hold your Task Edit Form. I will call my folder “TaskEditForm”.
- Now, add a new web form
o Right-click on that folder and select “Add New Item”
o Then choose “Web Form”
 Name the form “TaskEditForm.aspx”
 Choose “Place code in separate file”
 Hit the “Add” Button

7
Your Solution should now look like this:

- Build the UI for your Instantiation form


o If you did Part 3 of the workshop (Instantiation Form), just copy the script (everything
below the <@Page> directive) from the Instantiation Form (InstantiationForm.aspx) and
paste it into this form. If you did not do Part 2, you can get the script from the Code
Directory of the workshop

8
o Lastly, remove the RadioButton Option that says “Ask me at the time of copy” because
that’s what we are doing in this workshop, so we don’t need to offer that option again.

It looks like this: (Before)

And should look like this: (Afterwards)

I’ve also added a few Label controls to show some of the Task List item values.

When you are done, the Source View should look like this:

9
- You can “Close and Save” that form. As I explained in Part 2 of the workshop, you can’t view
the form in Design Mode because of issues with the Master Page. So don’t worry about viewing
it at the moment, and if being able to see your UI for design purposes is important, then create
a “Design” version of your form as I suggested in Part 2 of the workshop.

If you try to view it in “Design Mode” you will get an error page that looks like this:

Writing the code-behind for your Task Edit Form


You’ll see that as compared to the other Workflow Forms (i.e., Association and Instantiation) the Task
Edit form requires the least code by far. As a point of reference I should be clear that whenever you
setup a SharePoint Workflow on a Document Library, SharePoint will require you to associate a Task List
with that workflow. The task list can be the one that was created with the SharePoint site that the
document library resides in, or you can request that a new one be setup when you associate the
workflow with the SharePoint Document Library.

One of the reasons for this requirement is that SharePoint will hold the Task-based interaction data
between the user(s) and the workflow in this list. Essentially the Task List associated with the Workflow
is the “database” for this interaction between the users and SharePoint.

So to start out this workshop, we’ll add a little bit of code to get information about the SharePoint Task
List.

Namespaces and using statements


These are the namespaces and using statements that we’ll need for the objects referenced in the Task
Edit Form.

10
Your code will look like this:

Method stubs to handle the forms Button controls


We need a couple of method stubs to handle the button controls that we added to our form earlier. We
will add the code to make these buttons work later in the workshop.

Your code will look like this:

Declarations for the “Class Level” variable


Portal and Site variables
These are the few variables that we need to store the Portal Site and our Team Site.

Your code will look like this:

11
Task List related variables
As I mentioned earlier, the Task List is where the data about our interaction with the user will be
persisted/stored. So we need a couple of variables that will allow us to access the task list and to send
the data back to the workflow to operate on.

Your code will look like this:

Workflow Parameter variables


This set of variables is related to the SharePoint list that we are connected to and the workflow itself.

Your code will look like this:

Adding methods to make the Instantiation Form work


Adding the code to load the Master Page
As we did in the Association and Instantiation Forms, we’ll need to add code to “programmatically”
assign our form the master page that the Team Site is using. This code will be added by overwriting the
PreInit() method.

12
Note: If you didn’t use a “Design” Form, then you can skip the code that checks to see if the form being
loaded is the Design form.

Your code will look like this: (I’ve added it just before the Form_Load() method, but this is not required)

Loading the Workflow Parameters (from the URL)


We only need a couple of Parameters, so very little code here.

You code will look like this:

13
Getting information about the Task List and Workflow
In this method we will use the SharePoint API’s to get some of the Task List and Workflow related
information/values that we will need later on in the project. We will also start (i.e., Instantiate) the
workflow from here.Your code should look like this:

Getting the Task List Item information


Now that we have the general information about the Task List and the workflow, we can use that
information to get the actual Task that we are working with and (as we will in the case of this workshop
example), “bubble” that information up to the user.

In this example, we will show the user the Tasks: Title, Priority and Assigned to information. You can
show whatever is relevant for your application’s needs.

Your code should look like this:

14
Adding code to the Page_Load() method
I am using the Page_Load() Method to orchestrate the gathering of data (setting to variables) by calling
the method calls that I’ve already written, before the forms UI is loaded for the user. This way, once the
user makes his choices and hits the “Submit Button”, I can serialize the data and return the processing
back to the workflow project.

Here’s how the code looks:

Adding code to make the Submit and Cancel Buttons work


Sending the information to the workflow (Submit Button)
The “Submit” button holds the code that actually sends the Users’ Task data to the workflow and allows
the Workflow to handle that data. The process of passing the data is pretty easy. You can pass Built-in
Task List fields and your custom forms by adding them to a hash table and calling the AlterTask() method
of the SPWorkflowTask object as shown below.

Note: The complete list of the Built-in Task fields is here: http://msdn2.microsoft.com/en-
us/library/ms439470.aspx

Your code should look like this:

What if the user decides to cancel the Task Edit Form? (Cancel Button)
If the user hits the cancel button, we’ll throw away the form data and put them back in the Document
Library, where they can choose to start the workflow again.

Your code should look like this:

15
Storing the User data in the Task list
Unlike all of the other Workflow Forms, the Task List has a unique requirement to store user data for
long periods of time. The reason for this is manifold, but the primary reason, at least in my mind, is that
when you assign a user a task, you have no idea how long it will be before that task is completed. It can
be one minute, one month, or one year (or more). The important thing is that SharePoint keep the user
data and in some cases, track how long the user has to complete the task (before you escalate to
another user, manager, etc.).

The fact that SharePoint can handle tracking Built-in Task fields (e.g., Assigned to, Start Date, Due Date,
etc.) is great, but what about custom data, (e.g., Directory to Copy the file to), the files name from this
Workshop’s example? The SharePoint Team gives you a way of storing the Built-in data and the custom
data via something called a “Custom Content Type.” In this section of the workshop I will show you how
to create this “Mythical Beast.” I say it’s mythical because even the examples that you can find on the
web and in books are confusing (to me) because they are focused on the many things that you can do
with Custom Content Types, and I just wanted to know the parts that concern workflow. So, hopefully
you will find my examples and explanation easy to follow, albeit only a fraction of what you can do with
a Custom Content Type in SharePoint.

Here are the steps to create one:

- Start up a new Visual Studio project. This isn’t a hard requirement, and you could add it to one
of your existing projects, but I found that it’s easier to keep this one separate, since you will
never have to compile this solution. As a matter of fact, you could build the whole thing in
NotePad if you wanted to, because it’s all XML files.
o Choose a “Blank Solution” project Type
o I will call my solution “CopyFileFeature”
o Place your solution in the “features” directory of your SharePoint Server.

My directory is:

C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\

o IMPORTANT: Make sure the “Create directory for solution” option is unchecked or
grayed out.

16
Your screen should look like this: (Step by step)

Creating the Custom Content Type file


(Called CopyFile Task Edit Content Type.XML in my case)

From the definition in the SharePoint SDK:

Content types enable you to store multiple different types of content in the same
document library or list. In the preceding example, you could define two content types,
named Specification and Contract. Each content type would include different columns
for gathering and storing item metadata, as well as different workflows assigned to them.
Yet items of both content types could be stored in the same document library.

You can think of a content type as a refinement and extension of a Windows SharePoint
Services 2.0 list, which by default defined a single data structure, or schema, to which all
items on that list had to adhere. In Windows SharePoint Services 2.0, the schema of an
item was inextricably bound to its location. When you defined a list or document library,
you also defined the columns for that list or library, in effect defining the data schema for
all items stored in that location. Each column represented an additional piece of data you
were tracking for all items on the list.

17
Steps to create our Custom Content Type file

- Add a new item to your solution (Right click on your solution -> Add New Item )
- Choose “XML File” Template
- Call it “CopyFile TaskEdit Content Type.XML”. I know it’s a long name, but I get carried away
sometimes. 
- Hit the “Add” Button

Your form should look like this:

- Now we can add the XML Elements to the file.


o First Create your Elements Tag

18
o Now your “ContentType” Tag

o Fill the tags in with these values


 ID = A unique GUID for the Content Type
o The ID MUST inherit from one of the SharePoint Document
Content Types, listed here: http://msdn2.microsoft.com/en-
us/library/ms452896.aspx.
o For Workflow Task, we MUST inherit from Workflow Task (Hex
ID: 0x010801), our ID will start with 0x010801
o Now you must add two zeros to the end of that ID (don’t ask
me why, because I don’t know, but I know that it is required!)
leaving you with an ID that looks like this: 0x01080100
o Now, you must add a unique ID (aka., GUID) to the end of this
number to finalize your ID.
 (Remembers these steps: because you will need to do
them several times for new GUIDS)
 Normally there is a “Create Guid” tool in the “Tools”
menu, but it doesn’t show up in Blank Solutions. Since
it doesn’t show in all Visual Studio project types, I use
an online GUID generator @
http://www.cloanto.com/uuid/
 Click on the link (http://www.cloanto.com/uuid/)
 Generate the GUID
 Copy and Paste it into the ID and remove the dashes
o You should now have something that looks like this (your GUID
will be different than mine, but remember to add it after the
0x01080100):
0x010801003af83030657611dc93a70050c2490048

19
Your file should look something like this:

 The rest are easy


o Name = The name that you want your Content Type to have.
o Group = The Group/Collection that you want your Content Type
to show up in SharePoint’s Gallery and Details Page.
o Description = The description of your Content Type, as seen in
the Content Type Details page.
o Version = The version of your content type; you can increment
it as you need to.
o Hidden = True/False, if you want users to be able to see (and
Enable/Disable) your content type.

My values all filled in look like this:

Note: Here’s a link to the full list of Content Type tags that you could have used and their definitions:
http://msdn2.microsoft.com/en-us/library/aa544268.aspx

- Now we need to add a “FieldRefs” tag and a “FieldRef” (no “s”) child tag. “FieldRefs” represent
a collection of column references (i.e., Fields) in a Custom Content Type and “FieldRef”
represents a Column (i.e., Field) Definition. The “FieldRefs” element can have one or more
“FieldRef” elements. For our example, we only need to define one field, to hold our “User

20
selected File Overwrite Option (Overwrite, or Append a random number)” from our Task Edit
form UI.

Your file should look like this:

o Filling in the values, we have:


 ID = Unique ID (GUID) for the field.
 Use the link that I gave above for generating a GUID and paste it into
the ID field with { } around it.

Here’s mine: {60fe6d10-6579-11dc-aeae-0050c2490048}

 Name = the “Internal SharePoint field name”, which will be the name that
shows in the SharePoint URL’s. I am calling my field “_FileOverwriteOptions”,
although I am not 100% sure why they have to have an underscore before the
name.
 Here’s a list of all of the Attributes that you can define for a FieldRef element:
http://msdn2.microsoft.com/en-us/library/aa543225.aspx.

21
Now your Content Type file should look like this:

- Lastly, we need to add our XMLDocument Tag which allows you to define the form that the user
sees, if you choose to use Custom ASP.NET Forms, as I have done throughout the workshop.

Here’s the empty tag:

In the New, Display and Edit Tags, you can define what forms the user sees when they are creating (i.e.,
New), viewing (i.e., Display) or editing a task. You can choose one form for all functions, like I will, or
different forms, or no forms at all for one or all of the choices.

22
I will use the Task Edit form that we created earlier, so my file looks like this:

My final “Custom Content Type” XML file (CopyFile TaskEdit Content Type) file looks like this:

Creating the Custom Columns file


The custom columns file is, as you can imagine by the name, the file in which you define your Content
Types custom columns. The custom columns, and in my case, the values (because we used a
RadioButton control to represent a SharePoint Multiple Choice option) have to match up. In other
words, for fields like the SharePoint “Choice” column, the choices/values that you give to the user in the
Web UI must match the choices that SharePoint can store, which means that it needs to know about
those values. On the other hand, for fields that represent free form data entry like Text Columns, this is
not necessary.

Again, the XML Markup that I am showing represents a Multiple choice User Option, and I will give you a
link (below) to a list of all of the options and their formats.

23
Steps to create the Custom Columns File:

- Add a new item to your solution (Right click on your solution -> Add New Item )
- Choose “XML File” Template
- Call it “CopyFile Custom Columns.XML”.
- Hit the “Add” Button
o You should now have the XML File added to your solution
- Now that we have a file, the first element to add is the “Elements” element, which is defined as:
“Top-level element in a feature manifest file that contains feature element declarations.”

Like this:

- Add a child “Fields Tag”, which defines the properties of a single SharePoint site column (or
Field).

Here’s a complete list of the “Field” Elements attribute names and descriptions:
http://msdn2.microsoft.com/en-us/library/ms437580.aspx. We will only need to define a few.

o The ID and Name fields are the values as defined in the Custom Content Type
“FieldRef” section built in the earlier section above this one.

24
It was here:

o The “Type” value needs to match up with what I offered to the user via the Task Edit
forms UI. I gave the user a multiple choice control (The Radio Button List control) which
I need to “marry up” to a SharePoint column type, and for this job, I will use the
SharePoint “Choice” column. Again, see this list for all of your options: (Under the
“Type” tag.) http://msdn2.microsoft.com/en-us/library/ms437580.aspx.
o The “Format” Attribute also matches up to the UI that I gave the user.

This is what it looks like completely filled out, including the “<Choice>” tag:

25
Creating the Feature.xml file
The Feature.xml file is the “Wrapper” file for your Custom Content Type. It is the file that describes the
elements (officially this is called the Manifest) of your Custom Content Type solution. This is where you
point to the Feature Elements (i.e., Files that define your Custom Content Type, and any Custom Fields),
so that SharePoint will know where to find them. I will talk about the Custom Content Type and Custom
Fields more in a moment.

Steps to create your “Feature.XML” file:

- Add a new item to your solution (Right click on your solution -> Add New Item )
- Choose “XML File” Template
- Call it Feature.XML
- Hit the “Add” Button

Your form should look like this:

26
This will give you a Feature.xml file in your solution:

- The Feature.XMl file starts out with “<Feature>” tag which describes/establishes its description
in the SharePoint Features gallery.

Here’s how it look all filled out:

o The key values to consider are:


 ID = A unique ID for the feature
 Use the GUID generator from above to create a new GUID
 Copy and paste it in for your ID
 Title = The title for your feature in the SharePoint Features Gallery.
 Scope = Features can be available at the Site (i.e., Portal) level or at the
individual Web (i.e, Subsite) level. Workflows, like the one that we are building
need to be Site-Level.
 Here’s a link to all of the possible attributes you can set and their descriptions:
http://msdn2.microsoft.com/en-us/library/ms436075.aspx.
- Next is the “<ElementManifests>” tag, which is the tag that tells SharePoint what files (i.e.,
elements) to include when you install/enable this feature.
o The only key element under this tag is the “<ElementManifest> (no ‘s’) tag, which
defines each files location.

27
Here’s how it will look when you add it and fill it out:

- Lastly we need to add the “<Properties>” element, which can define the default values for a
feature. In our case, we only define one <Property> element within it.
- The “Key=GloballyAvailable” and “Value=true” attributes signify that this Feature will be
available throughout the portal and across a Portal Farm if necessary.

It looks like this:

28
The final Features.XML file should look like this:

Saving and deploying your new feature to the Portal


Now that you have finished creating your Feature.XML and associated Element Manifest files, you can
“Save All” in visual Studio and exit this project. You are done, from a coding perspective, which is fine
with me, because I hate hand coding XML, even if it’s a small amount like we’ve just done.

Now, it’s time to deploy this Custom Content Type/Feature to the Portal, and unfortunately you have to
do this with the Command-console based utility called STSADM.exe.

Here are the steps:

- First, let’s make sure that our files are where they should be. Since you created a “Blank
Project” when we started out, all three of the XML files should be in the
“Features\CopyFileFeature” directory of your SharePoint server. If not, copy them there,
because they will need to be easily accessible for the STSADM.exe utility.

29
Your folder should look something like this:

- Next we need to find our STSADM.exe utility and execute a couple of commands
o Open a Command-console (aka., DOS Prompt)
o Switch over to the directory where your STSADM.exe file is, which should be something
like:

C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN

Note: A full list of STSADM.exe commands and switches can be found here:
http://blogs.technet.com/josebda/archive/2007/03/22/complete-reference-of-all-stsadm-commands-
with-options-in-moss-2007.aspx

- Now we need to “Install the feature”


o Type:
stsadm –o installfeature –name CopyFileFeature
o Note: To uninstall a feature, you would Type:
stsadm –o uninstallfeature –name CopyFileFeature
- Next we need to “Activate the feature”
o Type:
stsadm –o activatefeature –name CopyFileFeature –url http://localhost
 Your URL may be different than mine, so point it to the root of your Portal
o Note: To deactivate a feature you would Type:
stsadm –o deactivatefeature –name CopyFileFeature –url http://localhost
- Go to your SharePoint Portal and verify that your newly installed and activated feature is there
o Open your browser
o Go to your SharePoint site
o At the Top Portal page
 Open the Site Actions -> Site Settings -> Modify all Settings link

30
 Select the “Site collection features” link in the “Site Collections Administration”
column

 There you should see your new feature, and note that it is “Activated”

31
 You can also verify that your new Custom Content Type (that we built earlier) is
available on the site.
 Back up to the “Site Settings” Page
 Click the “Site content types” link in the “Galleries” column

 There you will see your new “Workflow Task Custom Content Type”

 Lastly, you can verify that your new custom column (field) exists

32
o Back up to the “Site Settings” page
o Click on the “Site Columns” link under the “Galleries” column
o Scroll down to the bottom and you will see our new “File Copy
Overwrite Options” custom column, which will hold the users
answer to the question from the UI. Note that it is a “Choice”
column/field, just as we defined in our XML file.

 Click on the new Field and you will see it even holds the correct values
allowable:

33
All done with the Task Form/Custom Content Type
What all this means is that we now have a Custom Content Type (aka, Custom Task Form) that has a
Custom Column (aka, Custom Field) to hold the users’ data while the task is being worked on, whether
that be for 1 minute, 1 month or 1 year!

Building the Workflow


Designing the workflow
Now that we have our Task Edit Form built to allow for custom data entry of task information and a
Custom Content type to hold that custom content (i.e., custom field data) in our task form, we can move
on to building/modifying our workflow. Fortunately the SharePoint Team has given some great
SharePoint Activities to handle Tasks and all of its events.

They’ve given us Activities to:

- Handle the event when a Task Item has been created (OnTaskCreated)
- Handle the event when a Task Item has been deleted (OnTaskDeleted)
- Create a Task (both the CreateTask and CreateTaskWithContentType Activities)
- Update a Task (UpdateTask)
- Delete a Task (DeleteTask)
- Notify the Task List when a Task is completed (CompleteTask)
- Update all tasks (UpdateAllTasks)
- Roll Back Task Changes (RollbackTask)

34
Here’s my design when I start (from Workshop Part 3):

35
Issuing and monitoring a new task
What we’re going to do, is to add a workflow process to handle the issue when the user requests to “Be
asked at the time of file copy” in the event where there is a duplicate file in the Destination Directory. I
am going to add a While Loop to keep “Looping” until the file is copied, which will handle the wait until
the user responds.

Here are the steps:

- First, I am going to add a While Loop Activity within the “ItemExists” If/Else branch, and then
move the “CheckFileCopy Choice into that loop.
o Steps:
 Add the While Loop Activity
 Call it “FileCopyProcess”

 Move the “CheckFileCopyChoice” If/Else branch into the loop

36
- Now we will need a variable to compare to for the While Loop.
o Switch to the code view
o Add two Boolean variables
 Go to the top of the class
 One to know when the Task has completed
 And another for when the “FileCopyProcess” process is done

o Switch back to the Properties of the “FileCopyProcess” loop


 Select the “Condition” Process

37
 Choose the “Declarative Rule Condition”
 Open the “Condition” Property, so that you can see “ConditionName” and
“Expression”

 Open the “ConditionName” Property

 Click the “New” button


 Add the following condition to the “Rule Condition Editor”

38
 Close the Rule Condition Editor (Hit OK)
 Rename it to “Copy Process While Condition Check”

 Hit OK

The resulting Property for the “FileCopyProcess” While Activity should look like this:

- Now we need to add another Loop to handle the actual issuance of the Task and wait for the
Task Status to be set (by the user) to “Completed”.

39
- Add a new loop (calling it WhileTaskNotCompleted) to the “IAskUser” If/Else branch
o Choose a “Declarative Rule Condition” in the property window
o Create a “ConditionName” or more aptly the Condition Rule Name

It should look like this:

o Rename the Rule from “Condition1” to “ Task Complete while condition check”

Hit OK and the final Property values look like this:

40
Adding our Task Activities
CreateTaskWithContentType event
The “CreateTaskWithContentType” event allows you to create many unique SharePoint Tasks based on a
SharePoint Content Type (like we created earlier). This Workflow Activity differs from the “CreateTask”
Activity, which only allows you to create one (1) task per workflow. I will not cover the “CreateTask”
activity in this workshop, but here’s an example of how you can use it: http://msdn2.microsoft.com/en-
us/library/ms580283.aspx.

Steps:
- Add a “CreateTaskWithContentType” Activity before the “WhileTaskNotCompleted” loop
- Name it “CreateAskUserTask”

41
Properties:
- CorrelationToken = Unique name for the task, so that the workflow engine can refer to this
specific task in a Workflow that has multiple workflows.
o Enter something unique, like: “CreateAskUserToken”
o Then assign the “OwnerActivityName” to the “IAskUser”. The Owner Activity is the
“thing” that holds the task, in this case the “IAskUser” If/Else Activity.

- ContentTypeId = This is the Content Type ID, that we created in the section called: Creating the
Custom Content Type file . In my case (your ID will be different), the number is:
0x010801003af83030657611dc93a70050c2490048
- TaskID = Just like all of the other ID’s, you have to give this task a unique ID (GUID). This is the
Task ID that all of the other Tasks (OnTaskChanged, CompleteTask) Activities in this block will
refer to. This allows you to have multiple Tasks throughout your workflow with multiple
associated Task Activies (e.g., OnTaskChanged, CompleteTask, UpdateTask, etc.) pointing back
to the correct “Original” Task Activity.
o I like to use a “Code Generated” ID here, so that I don’t have to remember it or have to
cut-and-paste it every time I want to use it.
o Here’s how:
 Click on the ellipses of the Task ID

 Click on the “Bind to a new Member” tab


 Select a “Field” Type
 I will leave the default name and hit OK

42
That’ll give us a Property value that looks like this:

o Now we will set the GUID via code


 Switch to the “Events” Tab of the Property Pane

 Double-Click on the “MethodInvoking” Property

43
 This should put you in the code window, inside of the
CreateAskUserTask_MethodInvoking() method.
 Just add a line of code that will set the GUID programmatically

o Switch back over to the Workflow Designer and back to the Properties Pane of the
CreateAskUserTask Activity

o We will now set the TaskProperties property. This one is important, because this is
where we can preset all of the values for our task, as you will see.
 Click on the ellipsis of “TaskProperties”

 Switch to the “Bind to a new member” tab


 Select “Create Field”
 Hit the OK Button

44
Your property should look like this:

o Now we can add our code to set the Tasks Properties

Like this:

Note: Task Lists have to have “Allow management of content types” enabled, and the content type has
to be added to the Task List, before you can start using it (i.e., saving Custom Task Data). You will see in
the code below, that we check to see if “Allow management of content types” is enable (if not, enabling)
it, and adding the Content Type to the Task List (if necessary).

45
Continued….

46
OnTaskChanged event
Now I will turn my focus on to the second activity (askUserTaskChangedEvent), which will monitor when
a change has been made to our task. Since many of the steps are the same as the previous activity, I will
not show as many images.

Steps:
- Add a OnTaskChanged Activity to the “WhileTaskNotCompleted” Loop
- Name it “askUserTaskChangedEvent”

Properties:
- AfterProperties = The Property that will hold the Task Forms values whenever the task is
modified.
- BeforeProperties = The Property that will hold the Task Form values before each Task Edit,
assuming that there is more than one edit in the lifetime of the task. Think of it as if someone is
working on a task but is doing a little bit each day.
- CorrelationToken = Will be set to the same one as the “CreateAskUserTask”
- TaskID = Will be set to the Task ID of the “CreateAskUserTask”

Here are the steps:

- Click on the AferProperties property and “Bind” it to a new member “Field”

47
- Leave the “BeforeProperties” blank, we won’t need it for this example
- Set the Correlation Property to the same one as the “CreateAskUserTask” Activity
(CreateAskUserToken)

- Set the TaskID to the Property that we created from the “CreateAskUserTask”

48
The properties should now look like this:

- Switch to the “Events” Pane


- Double-Click on the “Invoked” Method

49
- This will drop you in the “askUserTaskChangedEvent_Invoked()” method

Your code will look like this:

OnTaskChanged event
The last activity of this process will be the “TaskCompleted” Activity which we will call
“AskUserTaskCompleted.” The Activity will fire as soon as the “WhileTaskNotCompleted” loop has been
exited, which happens in the Activity we just coded. This is where you can interrogate your task
(actually you are interrogating your Custom Content Type as well) to get the user entered/selected
values.

Steps:
- Add a new “TaskCompleted” Activity
- Name it “AskUserTaskCompleted”

50
Properties:
- CorrelationToken = Will be set to the same one as the “CreateAskUserTask”
- TaskID = Will be set to the Task ID of the “CreateAskUserTask”
- TaskOutcome = A text message that you would like to show in the SharePoint UI when the task
has been completed.

Here are the steps:

- Since we have gone through these steps for the other controls, I will just show you the finished
Property pane.

- Switch to the “Events” Pane


- Double-Click on the “MethodInvoking()” method and enter the following code:

Updating the File Copy Option Activities


The last thing that we have to do for this workshop, other than test it, is add a line of code to each of the
file Copy Options (OverwriteFile and AppendFile) activities, so that we can exit the “FileCopyProcess”
loop after they are done.

We need to set the “_fileCopyProcessCompleted” to “True”.

Here are both methods, with that updated code

51
And,

52
Testing the workflow
Now that we have the task portion of the workflow designed and properly “coded,” it’s time to put it to
the test. You will need an email client logged in as whatever username you are working under in your
Workflow development. They will be the one that receives the email. You can change this, by changing
the “LoginName” within the workflows “CreateTaskWithContentType” code (see picture below).

Steps:

- Before we get started, let’s put a “Break Point” on the first shape in our workflow
(onWorkflowActivated1), so that we can watch the workflow in the Workflow Designer.

It should look like this:

- If you are using Visual Studio 2008, you can just build the solution and the “Start Debugging
(F5).” If you are using Visual Studio 2005, then you will need to use the deployment and
debugging process (attaching to the ASP.NET process) as outlined in the link earlier in the
document (Section: “My development environment & setup”).

53
When the workflow is started you will begin in the document library that your list is attached to:

- Let’s now start our workflow by hitting the “workflow” action on your test document.

- This will land you on the “Workflow’s Start Page”


- Click on your workflow to start it.

54
- Make sure that you have a “Test Document” in the Destination Directory and choose the “Ask
me at time of copy” option within the UI.

- Then, hit the “Submit” Button


- This will bring us to the workflow, where we can step through the workflow and the code, using
F10 (C#) to step through the code and F11 (C#) to step into the code blocks.

55
- Keep stepping through your workflow until you get to the Task Workflow Activities to see how
they work.
o You’ll notice that after it finishes the “CreateAskUserTask” SharePoint will come back to
the forefront and show you a screen like this:

o Notice that it doesn’t say “Completed” as it normally would, it says that it is “In
Progress” and it will sit there at this state forever, because it’s waiting for a user (you in
this case) to finish a task
o Click on the “In Progress” Link to see where it takes you.

56
You should be at the “Workflow Status” screen:

o Notice that we now have a new task, with


 The “Assigned To” column filled out (from our code)
 The “Title” column filled out (from our code)
 The “Due Date” column filled out (from our code)
 The status is set to “Not Started”
- If you were to switch to the Task List (within the Team Site) you would see a row that coincides
with our workflow.

Task List Screen:

57
- Switch back to the “Workflow Status” screen
o Click on the task link

Now you should find yourself on the Task Edit form that we created earlier:

- Select whichever option you want (I will choose “Append a random number”)
- Hit the “Submit Button”
- You should be sent back to the “Workflow Status” screen with updated task values

58
Your screen should look like this:

- Go back to your Task List and your screen should look like this:

- Click on the Tasks “Title” to see what the user choose in the Web Form.

- You will see that their data was persisted/saved, because of the Custom Content Type, which I
will show you in a moment.

Your screen should look like this:

59
o Hit cancel to exit from that screen

Wrap up
Hopefully you see that Creating, sending (emailing) and monitoring tasks with Custom ASP.NET forms is
not that difficult. The SharePoint Team gave us several useful Workflow Activities and setting/getting
values from the Task is pretty straight forward as well.

Where to get more information


Subscribe to my blog (www.sheltonblog.com) to see what other items I post around SharePoint
workflow.

Learning and research resources used for this workshop


I used the following resources to help me understand SharePoint Workflow. I am not personally
recommending/endorsing any of the books, however, I did read them and you may find them helpful.

- The Windows SharePoint SDK


o Go to www.microsoft.com/downloads
o Search for “Windows SharePoint Services 3.0 SDK”
- (Book) Inside Microsoft Windows SharePoint Service 3.0
o By Ted Pattison and Daniel Larson
o ISBN: 0735623201
- (Book) Workflow in the 2007 Microsoft Office System
o By David Mann
o ISBN: 1590597001

60

You might also like