Developing Workflows in VS: Part 4 - Design and Bind Your Forms

 Step 2: Design and Bind Your Forms

With your workflow skeleton in place, you should now be able to see where you will be collecting data and what data to collect.  With this information, you can create your forms, set up a schema for the collected data, and write the code behind your workflow to utilize that data.

Behind the Scenes of the Four Types of Workflow Forms

There are four types of workflow forms that you can implement: association, initiation, task edit, and modification.  To determine which ones you need, ask yourself the following questions:

                Association: Do I want to input default values for initiation, or values that the workflow needs that only list administrators should set?

                Initiation: Do I want people to start the workflow manually?  If so, is there information that the workflow needs to start off with?

                Tasks: Are people involved in my workflow?  Will I be assigning tasks?

                Modifications: Will the workflow need to be adjusted in-flight?

If you answer yes to these, then you’ll probably need a form. 

All your workflow forms will need to do the following things:

1)      Collect data from the user

2)      Call an object model function to perform its action (e.g. create an association, start the workflow, edit a task, etc).  This function takes the data as a parameter and passes it into the workflow.  (MOSS provides a shortcut for IP forms that we’ll talk about in a bit)

Once this function is called, the SharePoint will trigger an event in the workflow schedule and pass in data (excluding associations, which happen outside of the schedule).  Thus, the workflow schedule must have a corresponding event handler activity to respond to the event.  The data will be stored into a variable bound to a receiving property on that activity.  

For example as seen in the following diagram, to start a workflow, the initiation form calls a function called StartWorkflow, which takes the initiation data string as an argument.  StartWorkflow triggers the workflow activated event, which triggers the OnWorkflowActivated activity (Hence, OnWorkflowActivated needs to be the first activity in your workflow).  It stores the initiation data into the variable bound to the WorkflowProperties property on that activity.  The following diagram shows this process: 1) aspx page calls StartWorkflow and passes in form data, 2) SharePoint stuffs the data into an event handler activity in the workflow (OnWorkflowActivated).

original.aspx

And it works similarly for tasks and modifications.  Below is a chart of what functions each form type calls, which activity you need to receive the event, and which property on that activity gets stuffed with the data:

Form Type<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Required Actions

Event Handler activity and Data Receiving Property

Association

(MOSS host page: CstWrkflIP.aspx)

Create SPWorkflowAssociation object (SPWorkflowAssociation::CreateListAssociation(… associationData))

Add association to list or content type (SPList.AddWorkflowAssociation(association))

None (associations exist outside of the workflow schedule)

Initiation

(IniWrkflIP.aspx)

Start a new instance of a workflow (SPWorkflowManager.StartWorkflow(association, web, list)

OnWorkflowActivated.WorkflowProperties

Stored into these SPWorkflowActivationProperty fields: InitiationData, AssociationData

Task edit

(uses form specified in OffWFCommon task content type, WrkTaskIP.aspx)

Change the task (SPWorkflowTask.AlterTask())

OnTaskChanged.AfterProperties

Modification

Modify the workflow (SPWorkflowManager.ModifyWorkflow)

OnWorkflowModified.ContextData

 

Specifying Which Forms To Use

When you have your forms, you’ll probably want to specify which form to use for what stage of the workflow, i.e. which form to use for association, initiation, etc.  This is defined in the workflow template xml file (workflow.xml), which we’ll see in the deployment step.  There is a one-to-one mapping between form and type, for example:

<Workflow

       Name=…

       TaskListContentTypeId="0x01080100C9C9515DE4E24001905074F980F93160"

       AssociationUrl="_layouts/CstWrkflIP.aspx"

       InstantiationUrl="_layouts/IniWrkflIP.aspx"

       ModificationUrl="_layouts/ModWrkflIP.aspx"> 

In this snippet, we’re using the out-of-box IP host pages for that come with MOSS (we’ll explain what we mean by IP host pages in the next section).  In short, you would use the pages specified above if you’re using IP forms, and you’d want to specify your own aspx pages in these fields if you’re using aspx forms.

For Tasks, instead of specifying a page, you specify a content type that specifies the appropriate view and edit aspx page.  The OffWFCommon content type that comes with MOSS is for use with IP forms.

FAQ:  How to specify multiple task or modification forms
You can only specify one aspx page for each form type, and one default task content type.  However, your workflow might need more than one form for tasks and modifications.  If you are creating your own custom aspx pages and need more than one task edit form, you will need to create a content type for each type of task and use the CreateTaskWithContentType activity to create a task that uses that type (instead of the CreateTask activity).  If you need more than one modification form, either create an aspx page that redirects to multiple forms, or create a page with multiple views based on page parameters and workflow template fields.  If you are using InfoPath forms, the MOSS out-of-box aspx pages, which automatically load the appropriate IP form based on “FormURN” tags in Metadata section of the workflow template xml.

InfoPath vs. ASPX Forms

We now know what needs to happen in the forms behind the scenes, so we just need to choose the technology: InfoPath (IP) or ASPX forms.

In reality, all (browser-based) workflow forms that you see are aspx pages.  What makes InfoPath forms different is that they are hosted in an XmlFormView control in out-of-the-box aspx pages in MOSS.  These are the pages we specified in our workflow.xml snippet in the last section.

There are several advantages to using InfoPath forms that you should consider:

1)      They can be used directly in the core Office 2007 client applications. 
The client applications (Word, Excel, PowerPoint, Outlook, InfoPath), like aspx pages, can host InfoPath forms for workflow.  So when you click on that “Edit this task” button that appears in Outlook or Word, the IP task form will appear as a dialog directly in the application to maintain context.  This form is exactly the same form as you’d see in the browser, so you have a symmetric experience.  If you’re using ASPX forms, this button will redirect you to a browser.

2)      They are easy to author with InfoPath designer.
Drag and drop, IP rules wizard… if you enjoy the authoring experience in InfoPath, this is a plus.

3)      No code required
No code required?  But what about calling the functions to perform the specified action?  Well, the MOSS aspx host pages make the object model calls for you, so that all you need to focus on is designing your IP forms in the IP designer.  More specifically, these forms 1) load the IP form, 2) wait for the IP form to send its xml back to it, and 3) make the OM calls.  If the out-of-box functionality is not what you desire, you can code your own ASPX page to host the IP form and make the appropriate calls.  But remember that you might also be able to write code behind your IP form to add that functionality.

Creating InfoPath Forms

For every IP form you create for workflow, you’ll need to do the following things:

1)      Name your fields
Define your schema according to how you want to reference your data in the workflow.  So if you have a control to collect comments and call it “comments”, and in your workflow code, you’ll be able to reference the data in that field as “comments”.

2)      Add a submit button with 2 rules
We know that IP forms are hosted in an aspx page or client application, so when the user wants to submit the form, have the submit button a) create a connection to submit the xml data/string to the host environment (the host will handle the rest), then b) close the form so that it doesn’t just submit and stick around.

3)      Add domain level trust
Yeah, you need this for workflow forms.  In IP, it’s in Tools->Form Options->Security and Trust

4)      Publish to your project folder
Workflow forms will be deployed when you deploy your workflow, so keep them handy with your project so that the deployment tool picks them up and you can tweak as necessary.  Don’t forget to leave the alternate access path blank, or else it won’t install!

Pitfall: Forgetting to clear the alternate access path
It’s easy to forget to clear the alternate access path in the Publish wizard, since it’s filled in by default after you specify the publish location; be sure to actively delete the default value that they provide.

Pitfall: Confusing the IP document with an IP workflow form
A trap that people run into is thinking that a workflow IP form is the same as an IP document that is saved as an xml file (such as a forms library document).  If you are designing a workflow for a forms library, think of the library’s form template as an ordinary document, and the workflow forms as process UI.  Workflow forms are not files that are saved; they are merely UI to collect data, and the results are passed into the workflow, not a file.

A Fifth Step for Tasks: ItemMetadata.xml

If you need to load task data in your task forms without any code, you need an extra step. Unlike the other workflow objects, tasks are list items that can be tweaked in ways that the form and workflow don’t expect, for example, adding a column and hence changing the item schema.   So to compensate for the possibility of schema differences between the task data and the form, we let the developer define the fields in the task that are needed to populate the form controls, through a file called ItemMetadata.xml.

SharePoint passes the task as xml into this file, which should be a secondary data source on the form.  It’s case sensitive, and it uses the exact schema of the task.  So step 5 (do this before step 4) for task forms is:

5)      Add an ItemMetadata.xml file as a secondary data source to your form

The file contents would look something like this:

<z:row xmlns:z="#RowsetSchema"

                ows_instructions=""/>

where “instructions” is the name of a field or column on the SharePoint task itself.  You can select ows_instructions as a default value for your fields.

Binding Form Data into Your Workflow

As we saw earlier, the form pages call functions that trigger events in the workflow and stuff the form data into a property on the corresponding activity.  So all you need to do when the event is triggered is write a handler that parses the data and uses the data to perform actions in the workflow.

Initiation form data is passed into the OnWorkflowActivated activity as a string, so whether it’s via a serializable class or by xml parsing helper functions, you just need to get the string into data you can use.  Modifications also pass a string into the OnWorkflowModified activity.  Parse this similarly to Initiation form data.  Again, if you’re using IP forms, the “Submit to host” passes the form data as an xml string to the host that is then passed directly into the function call, so for initiation and modifications, follow the form schema to parse it (e.g. by using the xsd generator tool to create a class for it).

Tasks are slightly different in that when a form is submitted, data is saved directly to the task item on the list.  SharePoint does a little magic on the task and copies the task info into the workflow as an SPWorkflowTaskProperties object that contains the properties that changed on the task item itself (and null for properties that didn’t).  For IP forms, the host parses the xml and saves each field to a column on the task item with the same name. So if you have a form field named “AssignedTo”, it would write the value to the “AssignedTo” property on the item.  For a field that does not have a matching column on the list, e.g. “foo”, that field will be saved as a hidden field on the task object.  Hidden fields are exposed in the workflow as a hashtable called ExtendedProperties on an SPWorkflowTaskProperties object, and can be referenced in the workflow by using the field name as a key, e.g. afterProps.ExtendedProperties[“foo”].

Binding Object Data into Your Forms

Pre-populating data into the forms does not come from the workflow itself.  Rather, these forms get their data from SharePoint objects related to the workflow.

For example, both association and initiation forms load initial data from the SPWorkflowAssociation object on the list or content type. 

Task forms pull their data from ItemMetadata.xml, which is the SharePoint task object as xml.

Modifications pull data from the ContextData string in the SPWorkflowModification object.  Note: this object needs to be reinitialized by the workflow if the data changes.

 

Next on Developing Workflows in VS: Coding Your Workflow

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章