Part 4 - Custom Workflow Forms (TaskEdit Form)

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

description

This document is a reference to constuct a Workflow in MOSS

Transcript of Part 4 - Custom Workflow Forms (TaskEdit Form)

Page 1: Part 4 - Custom Workflow Forms (TaskEdit Form)

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

Page 2: Part 4 - Custom Workflow Forms (TaskEdit Form)

2

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

Page 3: Part 4 - Custom Workflow Forms (TaskEdit Form)

3

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

Page 4: Part 4 - Custom Workflow Forms (TaskEdit Form)

4

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.

Page 5: Part 4 - Custom Workflow Forms (TaskEdit Form)

5

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:

Page 6: Part 4 - Custom Workflow Forms (TaskEdit Form)

6

- 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”

Page 7: Part 4 - Custom Workflow Forms (TaskEdit Form)

7

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

Page 8: Part 4 - Custom Workflow Forms (TaskEdit Form)

8

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

Page 9: Part 4 - Custom Workflow Forms (TaskEdit Form)

9

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:

Page 10: Part 4 - Custom Workflow Forms (TaskEdit Form)

10

- 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.

Page 11: Part 4 - Custom Workflow Forms (TaskEdit Form)

11

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:

Page 12: Part 4 - Custom Workflow Forms (TaskEdit Form)

12

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.

Page 13: Part 4 - Custom Workflow Forms (TaskEdit Form)

13

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:

Page 14: Part 4 - Custom Workflow Forms (TaskEdit Form)

14

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:

Page 15: Part 4 - Custom Workflow Forms (TaskEdit Form)

15

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:

Page 16: Part 4 - Custom Workflow Forms (TaskEdit Form)

16

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.

Page 17: Part 4 - Custom Workflow Forms (TaskEdit Form)

17

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.

Page 18: Part 4 - Custom Workflow Forms (TaskEdit Form)

18

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

Page 19: Part 4 - Custom Workflow Forms (TaskEdit Form)

19

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

Page 20: Part 4 - Custom Workflow Forms (TaskEdit Form)

20

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

Page 21: Part 4 - Custom Workflow Forms (TaskEdit Form)

21

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.

Page 22: Part 4 - Custom Workflow Forms (TaskEdit Form)

22

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.

Page 23: Part 4 - Custom Workflow Forms (TaskEdit Form)

23

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.

Page 24: Part 4 - Custom Workflow Forms (TaskEdit Form)

24

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.

Page 25: Part 4 - Custom Workflow Forms (TaskEdit Form)

25

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:

Page 26: Part 4 - Custom Workflow Forms (TaskEdit Form)

26

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:

Page 27: Part 4 - Custom Workflow Forms (TaskEdit Form)

27

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.

Page 28: Part 4 - Custom Workflow Forms (TaskEdit Form)

28

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:

Page 29: Part 4 - Custom Workflow Forms (TaskEdit Form)

29

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.

Page 30: Part 4 - Custom Workflow Forms (TaskEdit Form)

30

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

Page 31: Part 4 - Custom Workflow Forms (TaskEdit Form)

31

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”

Page 32: Part 4 - Custom Workflow Forms (TaskEdit Form)

32

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

Page 33: Part 4 - Custom Workflow Forms (TaskEdit Form)

33

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:

Page 34: Part 4 - Custom Workflow Forms (TaskEdit Form)

34

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)

Page 35: Part 4 - Custom Workflow Forms (TaskEdit Form)

35

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

Page 36: Part 4 - Custom Workflow Forms (TaskEdit Form)

36

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

Page 37: Part 4 - Custom Workflow Forms (TaskEdit Form)

37

- 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

Page 38: Part 4 - Custom Workflow Forms (TaskEdit Form)

38

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”

Page 39: Part 4 - Custom Workflow Forms (TaskEdit Form)

39

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”.

Page 40: Part 4 - Custom Workflow Forms (TaskEdit Form)

40

- 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:

Page 41: Part 4 - Custom Workflow Forms (TaskEdit Form)

41

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”

Page 42: Part 4 - Custom Workflow Forms (TaskEdit Form)

42

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

Page 43: Part 4 - Custom Workflow Forms (TaskEdit Form)

43

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

Page 44: Part 4 - Custom Workflow Forms (TaskEdit Form)

44

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

Page 45: Part 4 - Custom Workflow Forms (TaskEdit Form)

45

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).

Page 46: Part 4 - Custom Workflow Forms (TaskEdit Form)

46

Continued….

Page 47: Part 4 - Custom Workflow Forms (TaskEdit Form)

47

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”

Page 48: Part 4 - Custom Workflow Forms (TaskEdit Form)

48

- 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”

Page 49: Part 4 - Custom Workflow Forms (TaskEdit Form)

49

The properties should now look like this:

- Switch to the “Events” Pane

- Double-Click on the “Invoked” Method

Page 50: Part 4 - Custom Workflow Forms (TaskEdit Form)

50

- 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”

Page 51: Part 4 - Custom Workflow Forms (TaskEdit Form)

51

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

Page 52: Part 4 - Custom Workflow Forms (TaskEdit Form)

52

And,

Page 53: Part 4 - Custom Workflow Forms (TaskEdit Form)

53

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”).

Page 54: Part 4 - Custom Workflow Forms (TaskEdit Form)

54

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.

Page 55: Part 4 - Custom Workflow Forms (TaskEdit Form)

55

- 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.

Page 56: Part 4 - Custom Workflow Forms (TaskEdit Form)

56

- 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.

Page 57: Part 4 - Custom Workflow Forms (TaskEdit Form)

57

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:

Page 58: Part 4 - Custom Workflow Forms (TaskEdit Form)

58

- 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

Page 59: Part 4 - Custom Workflow Forms (TaskEdit Form)

59

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:

Page 60: Part 4 - Custom Workflow Forms (TaskEdit Form)

60

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