Many of use have worked with SharePoint workflow in one or another to fulfill our
requirements. Also, many of us have requirements of customizing the workflow
input forms to meet our requirements. So, in this article we will explore the
custom input forms for SharePoint workflow and learn how to develop, associate and use those forms.
Solution Overview
With our scenario of custom input forms for workflow, we will develop an application
that associates the different input forms for different processes of the workflow.
So, when the workflow is associated with any of the List or Document Library
of SharePoint site, the workflow uses these custom developed forms instead of
the default one. Each input for has different working process. When any user
associates our workflow with document library or list, the association form comes
up and asks to the user to provide the approver, to set the approval scope and
to provide instruction to approver. When the user provides these values and clicks
Ok, the workflow will be associated to the list or document library. The workflow
can be configured to start automatically when the new item is created or to start
it manually. When a user creates an item and starts the workflow manually, the
workflow initiation form comes up and show the approver set at the time of the
association of the workflow. When the user clicks Ok button, the workflow starts
on the item or file. Also creates the task for the approver and sends the notification
to him and places the workflow in the InProcess state. When the approver opens
his task, the custom task edit form comes up. There the approvers can approver,
reject or cancel the operation. Also the approver can provide his comments for
his action as well. The solution also provides the Modification form for modifying
the properties for the associated workflow as well.
Solution Walkthrough
Download the solution project HelloWorkflow. Open the solution named HelloWorkflow in Visual Studio 2008. Remember that this
project requires the WSPBuilder already installed on the development machine.
As you can see from the below image, a file named HelloSharePointWorkflow.cs
contains the definition for the WF program itself. Three XML files are used to
define the feature named HelloSharePointWorkflow that installs the workflow template
within a WSS farm. We will now focus on how the other souce files inside the
HelloWorkflow project are used to integrate workflow input forms.

The HelloWorkflow project contains four different .aspx files to supply each of the
four available types of input forms: an association form, an initiation form,
a modification form and a task edit form. Remember that all these forms are developed
as custom application pages which are deployed in the LAYOUTS directory. It is
recommended that you don’t deploy your custom application pages directly inside
the LAYOUTS directory. Instead, you should create a project specific or organization
specific directory inside the LAYOUTS directory to deploy your custom application
pages. The HelloWorkflow project is configured to deploy its four custom application
pages within a custom HelloWorkflow directory inside the LAYOUTS directory.
Now open the elements.xml file and have a look at its content and specifically see
the definition of Workflow element that defines the workflow template. You should
see the attributes named AssociateUrl, InstantiationUrl, and ModifiecationUrl
that contain references to three of the workflow input forms.
<Workflow
Name="HelloSharePointWorkflow"
Description="Description for HelloSharePointWorkflow"
Id="d95902f9-87a7-48ac-8154-664d5c54c39c"
CodeBesideClass="HelloWorkflow.HelloSharePointWorkflow"
CodeBesideAssembly="HelloWorkflow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d91c6ff34a688573"
AssociationUrl="_layouts/HelloWorkflow/HelloAssociation.aspx"
InstantiationUrl="_layouts/HelloWorkflow/HelloInitiation.aspx"
ModificationUrl="_layouts/HelloWorkflow/HelloModification.aspx"
TaskListContentTypeId="0x0108010084565D92BEFE4a75A28C2F658B7BECCA">
<MetaData>
<Modification_a06bd3e8-b10f-4026-a6b6-edbc5b12305b_Name>
Modify workflow instance with a custom hello form.
</Modification_a06bd3e8-b10f-4026-a6b6-edbc5b12305b_Name>
</MetaData>
</Workflow>
There are attributes containing references to three of four of the workflow input
forms, there is no reference to the task edit form because you do not integrate
a task edit form in the same way as the other three types of workflow input forms.
If you want a custom form instead of the standard WSS task edit form, you must
create a custom content type that inherits from the standard workflow task content
type. When you create a custom content type for a custom workflow task, you can
define it to use its own custom edit form, which is the approach used in the
HelloWorkflow project. The TaskListContentTypeID attribute of Workflow element
in elements.xml is configured with the ID content type, which identifies the
custom content type defined inside workflowTaskContentType.xml.
Walking through using the Hello Approval Workflow input forms
To test the workflow template and workflow custom input forms defined by the HelloWorkflow
project, you must follow the steps. Download the HelloWorkflow source code. Open it in Visual Studio 2008. Remember that, as said above, you need
WSPBuilder to successfully open this project in Visual Studio 2008. Build the
project by right clicking the Project name in Solution Explorer. After successful
build, again right click the project and click Build WSP from the context menu.
This will build the .wsp file which will be installed on the SharePoint Server.
Now to deploy the solution or .wsp file, again right click the project name and
click Deploy. The both Build WSP and Deploy options are available as the sub
items of the WSPBuilder menu item.

Once the HelloWorkflow project deployed successfully, you should then be able to
activate the feature with the Hello Approval workflow template within any site
collection within the farm. Next, create a new site collection or navigate to
an existing site collection so that we can test workflow template. Once navigated
to desired site’s top-level site of site collection, go to the Site Collection
Features page from Site Settings page. You should see the feature titled "HelloSharePointWorkflow”.
Activate this feature to make its workflow template available within the site
collection. Now you are able to use the workflow template to create a new workflow
association.
Custom Association Forms
It’s now time to create a new list or document library so that we can have a place
to create a new workflow association from the Hello Approval workflow template.
Once new list is created, go to the List Settings page and click the Workflow
Settings link to page on which you can view the existing workflow associations.
Click the Add A Workflow link to navigate to the standard application page named
AddWrkfl.aspx, which allows you to create a new workflow association for the
list or document library. If you have not any existing workflow association,
then you will be directly redirected to the AddWrkfl.aspx page. You can see the
HelloSharePointWorkflow as an available workflow template as shown in below image.

The AddWrkfl.aspx page allows the user to select a workflow template, provide a unique
name and parameterize other standard aspects of the workflow association. Here
user can parameterize the workflow association to use an existing task and history
lists or can select to create a new task/history list. Continuing the walk-through,
select the HelloSharePointWorkflow template, give the name Hello Approval Workflow,
and then click next.
What happens when a user clicks the Next button on the AddWrkfl.aspx page, is the
important question. The depending answer is that whether your workflow template
is configured with an associated form. If your workflow is not associated with
an association form, the Next button execution does all the required logic to
create a new workflow association and create a new task list and history list
if necessary. If your workflow is associated with an association form, clicking
the Next button simply redirects the use to that association form. When you click
Next to create the Hello Approval workflow for our example, you will be redirected
to the custom association form named HelloAssociation.aspx, as shown in the below
image.

An important point to be considered here is that when you configure a workflow template
to use a custom association form, then you have to take of supplying the code
to create new workflow association as well as to create a new task list or history
list if that is what the user selected.
Think what is the purpose of custom association form? It’s used to prompt the user
form extra data input whenever they create a new workflow association. In the
case of our example, the association form is used to get the default values for
the approver, the approval scope (internal or external) and instructions to the
approver. When a user enters data into the association form and clicks Ok, your
code must serialize the user input values into a string that is saved as association
data. This association data then used by the initiation form each time a user
starts a new workflow instance from the workflow association.
Implementing a Custom Association Form
We will now see some implementation details of the association form. Open the HelloAssociation.aspx
and inspect what’s in. You should notice that this source file does not contain
any code inside. Instead, it simply contains input controls, command buttons
for Ok and Cancel, and layout details. The actual code for this form is writer
into a class named HelloWorkflowAssociationForm.cs file which is compiled into
the same assembly DLL as the WF program itself, i.e. HelloWorkflow.dll. The Page
directive within HelloAssociation.aspx indicates that it is defined to inherit
from the code-behind class named HelloWorkflowAssociationForm.
Open the HelloWorkflowAssociationForm.cs file and examine the code that defines the
behavior of the aspx page. The HelloWorkflowAssociationForm class inherits from
LayoutsPageBase class, which follows the best practice for developing custom
application pages. Though this is a simple example about creating custom association
form, it contains couple of hundred lines of code. The high-level structure of
the class is as the following code:
public class HelloWorkflowAssociationForm : LayoutsPageBase {
// control fields
// form-level variables
protected override void OnLoad(EventArgs e) {...}
protected void PopulateFormDataFromString(string AssociationData){...}
protected string SerializeFormDataToString(){...}
protected void UpdateAssociation(SPWorkflowAssociation wfa,
SPList TaskList, SPList HistoryList) {...}
public void cmdCancel_OnClick(object sender, EventArgs e) {...}
public void cmdSubmit_OnClick(object sender, EventArgs e) {...}
protected override void OnPreRender(EventArgs e) {...}
}
The HelloAssociation.aspx page defines several input controls to collect input from
user. For example, page has a WSS PeopleEditor control that provides a handy
technique when you need a user to select another user, such as the approver.
The following example shows what the control tag looks like.
When you have an .aspx file and a code-behind class, there is a handy technique in
ASP.NET programming in which code-behind class defines a control field by using
the same name as a control on the .aspx page. When the ASP.NET runtime compiles
the .aspx file, it adds support to create the control instance and assign a reference
to the control field in the code-behind class. For example, HelloWorkflowAssociationForm
class define a control field named pickerApprover to match the control instance
defined in HelloAssociation.aspx page.
public class HelloWorkflowAssociationForm : LayoutsPageBase {
// define control field with name that matches .aspx file
protected PeopleEditor pickerApprover;
}
The benefit of this technique is that all of the methods in the HelloWorkflowAssociationForm
class have direct access to all the control instances defined on the .aspx page.
Now examine the form-level variables in the HelloWorkflowAssociationForm class and
go through the code of OnLoad method. You can see that the parameters passed
by WSS are read in this event handler and used them to initialize strings, GUIDs,
and various objects from the WSS object model. In this code, the association
of workflow is checked for whether it is for list or document library. If the
new workflow association is being created on a list, conditional code in the
OK button click event handler executes this code:
WorkflowAssociation = SPWorkflowAssociation.CreateListAssociation(WorkflowTemplate,
WorkflowAssociationName,
TaskList,
HistoryList);
Also, when the workflow association is being created for content type, the code behind
OK button must be conditionally programmed to call either CreateSiteContentTypeAssociation
or CreateListContentTypeAssociation instead of CreateListAssociation. The code
must also take care of deal with the scenario in which the user is updating an
existing workflow association instead of creating new one.
The other important aspect of implementing an association form is how to handle user
input values. The input values provided by a user must be serialized into a string
and then saved to the AssociationData property of the SPWorkflowAssociation object.
At the time of modification of existing workflow association these value are
deserialized and used to populate the form input controls. See the way we used
for this example project to serialize and deserialize the input data using the
DataSet named WorkflowData. This dataset can be used with the XmlSerializer class
to create strong-typed .NET objects that can be converted back and forth for
data store.
The HelloWorkflowAssociationForm class provides two methods, SerializeFormDataToString
and PopulateFormDataFromString. These methods are used to move input data back
and forth between the form’s input controls and a serialized string to be saved
in AssociationData property.
The final implementation details that needs attention is the logic in the association
form that is responsible for creating a new task list and history list when required.
So, who to know that a new task list or history list need to be created on our
custom association form? The WSS places ‘z’ character at the beginning of the
incoming list name to inform that it is the new of new list to be created. To
identity this, in the OnLoad method, two Boolean variables named NewTaskListRequired
and NewHistroyListRequired are initialized based on the input parameters and
the Ok button executes the code based on this variable values.
if (NewTaskListRequires) {
Guid taskListId = Web.Lists.Add(NewTaskListName, "Workflow Tasks", SPListTemplateType.Tasks);
TaskList = Web.Lists[taskListId];
}
if (NewHistoryListRequired)
{
Guid historyListId = Web.Lists.Add(NewHistoryListName, "Workflow history", SPListTemplateType.WorkflowHistory);
HistoryList = Web.Lists[historyListId];
}
As you can see this association forms require a good deal of code, but also, the
code can be reused across association forms for many different workflow templates.
Custom Initiation Forms
It’s now time to see the implementation of a custom initiation form for workflow
template. Let’s for our example, once the user creates the Legal Approval workflow
association from the Hello Approval workflow template, the user should then be
able to see the association from the standard application page named Workflow.aspx,
as shown in below image. The user can navigate to this Workflow.aspx page by
selecting the Workflow menu item from the ECB menu for an item or document.

From the Workflow.aspx page, by clicking the link to any available associated workflow
to start a new instance. If the workflow template is not configured to use an
initiation form, WSS automatically starts the workflow instance. If the workflow
template is configured to use an initiation form, the user is redirected to it.

In our case, click the Hello Approval workflow link, which takes you to HelloInitiation.aspx
page as shown in below image. You can see that the initiation form input controls
are initially filled with the default values from the AssociationData property
of the workflow association. This gives the user to keep them as it is or to
change them.
The most important point here is that custom initiation forms can be used only with
workflow associations that allow the user to manually start workflow instances
through the Workflow.aspx page. You can’t present the user to initiation form
in the case when you have configured a workflow to start automatically when item
list item or document library item is created or updated. These types of scenarios
do not provide a natural flow and therefore not supported by WSS.
Implementation of Custom Initiation Form
If you look in the HelloInitiation.aspx page, you observe the input control tags
and page layout are almost identical to those in HelloAssociation.aspx page.
This makes sense because the association form is used to obtain default values
for all workflow instances, and the initiation form then gives the user the opportunity
to see these default values and optionally change them when starting a particular
workflow instance.
The HelloInitiation.aspx page also relies on a code-behind base class named HelloWorkflowInitiationForm.
The high-level structure of the class is as the following code:
public class HelloWorkflowInitiationForm : LayoutsPageBase {
// control fields
// form-level variables
protected override void OnLoad(EventArgs e) {...}
protected void PopulateFormDataFromString(string AssociationData){...}
protected string SerializeFormDataToString(){...}
public void cmdCancel_OnClick(object sender, EventArgs e) {...}
public void cmdSubmit_OnClick(object sender, EventArgs e) {...}
protected override void OnPreRender(EventArgs e) {...}
}
The new SPWorkflowAssociation object is created in the OnLoad method by using the
incoming parameters passed by WSS. Then this object is used in the PopulateFormDataFromString
method to get the current workflow association data. When user changes the values
of the input controls and clicks OK to start a new workflow instance, the SerializeFormDataToString
method is called to serialize these data into a form-level variable InitiationData.
After this, the actual call to start a workflow instance is done.
The interaction with SPWorkflowManager is required when we need to start a workflow
instance. The SPWorkflowManager object is exposed through the WorkflowManager
property on the SPSite object that represents the current site collection. This
SPWorkflowManager object provides a method named StartWorkflow that dose exactly
what its name says.
Web.Site.WorkflowManager.StartWorkflow(ListItem,
WorkflowAssociation,
InitiationData);
When the user clicks OK button on the initiation form, the call to StartWorkflow
is made and that the WF program comes into action. At this point, the code in
the event handler of the OnWorkflowActivated activity of HelloSharePointWorkflow.cs
is able to retrieve the initiation data, deserialize them and store them in fields
defined within the WF program.
private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
{
workflowId = workflowProperties.WorkflowId;
userID = workflowProperties.OriginatorUser.ID;
if (workflowProperties.Item.File != null)
ItemName = workflowProperties.Item.File.Name;
else
ItemName = workflowProperties.Item.Title;
string initiationData = workflowProperties.InitiationData;
XmlSerializer serializer = new XmlSerializer(typeof(WorkflowData));
XmlTextReader reader = new XmlTextReader(new StringReader(initiationData));
WorkflowData data = (WorkflowData)serializer.Deserialize(reader);
HelloWorkflow.Resources.WorkflowData.DataTable1Row row = data.DataTable1.Rows[0]
as HelloWorkflow.Resources.WorkflowData.DataTable1Row;
Approver = row.Approver;
ApprovalScope = row.ApprovalScop;
ApproverInstructions = row.Instrucations;
}
Custom Modification Forms
Once a workflow instance is in progress, you can supply a modification form that
allows users to modify its state. When modification form is integrated properly,
the user is able to see a link on the WrkStat.aspx workflow status page as shown
in below image.

When you design a workflow modification form, you can display whatever input controls
make sense for the modifications a user might want to make to a workflow instance
in progress. The modification form used for our example provides an opportunity
to change the approver, approval scope and instructions while the workflow instance
is still running and waiting for approval.
Implementing a Custom Modification Form
Let’s open the elements.xml file again and examine the Workflow element and see what
is needed to configure a workflow with modification form. The ModificationUrl
attribute in the Workflow element references a specific .aspx file, which in
this case is HelloModification.aspx. Another important element is nested in the
MetaData element that defines a specific workflow modification, as shown in the
following XML snippet.
<Workflow
<!-other attributes are omitted for clarity -->
ModificationUrl=”_layouts/HelloWorkflow/HelloModification.aspx”
>
<MetaData>
<Modification_a06bd3e8-b10f-4026-a6b6-edbc5b12305b_Name>
Modify workflow instance with a custom hello form.
</Modification_a06bd3e8-b10f-4026-a6b6-edbc5b12305b_Name>
</MetaData>
</Workflow>
A workflow template can have only one workflow modification form, it can have more
than on modification. Each modification is identified through a unique GUID and
is defined using an element nested in the MetaData element. The text provided
in the Modification element is used as the caption for the link that the user
will see on WrkStat.aspx page. Till this we have seen what needs to be set up
in terms of declarative logic within the feature for the workflow template. Now,
next discussion is little bit tricky because you must add two different activities
to you WF program to make the workflow modification work properly.
Due to a bug in this version of WSS, any GUID used for a Modification ID must contain
only lowercase letters. Things will not work properly if you use a GUID that
contains uppercase letters.
First of all, you must add a method activity of type EnableWorkflowModification to
you WF program. This activity is used to make the modification active at a specific
point within the life cycle of each workflow instance. Secondly, you must add
an event activity named OnWorkflowModified. This activity listens for the occurrence
of any modifications by users and responds by firing an event handler that executes
you provided logic.
You must need to decide at what point in time the modification become active in the
life cycle of workflow instance. In our example, the modification is designed
to become active after the approval task is created so that workflow instance
initiators can access the modification form while waiting for the approvers to
do their work.
To make modification active requires creating an activity from the EventHandlingScope
activity type supplied by the WF base activity library. Then you need to add
Sequence activity so that you can add several child activities inside the EventHandlingScope
activity. Next, you need to add EnableWorkflowModification activity as the first
activity that executes within the scope of EventHandlingScope activity as shown
in below image.

The next step is to set up the listener by using the OnWorkflowModified event activity
type. If you right click the EventHandlingScope activity in the workflow designer.
It will show you different viewing options. You need to select the View Event
Handler and switch over the view to configure the OnWorkflowModified activity.
Now in the view of Event Hanlders for EventHandlingScope activity, add the EventDriven
activity to the EventHandlingScope activity. This makes possible to add an event
activity that acts as listener. In our example, only one EventDriven activity
contains the OnWorkflowModified activity. The event handler for OnWorkflowModified
activity fires when the user updates information in the modification form.
Each modification relies on a GUID and a correlation token. The GUID for modification
is hard-coded into the workflow template inside the elements.xml file. When EnableWorkflowModification
and an OnWorkflowModified activity are added to WF program to activate the modification,
you must configure ModificationId property of both activities to this GUID. Also,
create a new correlation token and assign it to both activities. It is also important
to see that the OwnerActivityName for the correlation token named modificationToken
is configured as the activity named eventHandlingScopeActivity and not the workflow
program named HelloSharePointWorkflow.
When modification is created, you need to add code to the WF program to pass any
initialization data to the modification form that it needs. In our example, the
WF program must pass the same data that the user enters on the initiation form.
These data exists only within the fields of the WF program, the event handler
of the EnableWorkflowModification must serialize the form data again and assign
them to the field named modificationContextData that is data bound to the ContextData
property of EnableWorkflowModification activity.
The OnLoad method of HelloWorkflowModificationForm class supplies the logic to initialize
the fields and retrieve content data passed by the WF program by accessing the
ContextData property of the SPWorkflowModification object.
// Get Form Parameters
string paramList = Request.Params["List"];
string paramID = Request.Params["ID"];
string paramWorkflowInstanceID = Request.Params["WorkflowInstanceID"];
string paramModificationID = Request.Params["ModificationID"];
// create WSS object
_List = Web.Lists[new Guid(paramList)];
_ListItem = _List.GetItemById(Convert.ToInt32(paramID));
_WorkflowInstance = _ListItem.Workflows[new Guid(paramWorkflowInstanceID)];
_ModificationID = new Guid(paramModificationID);
_Modification = _WorkflowInstance.Modifications[_ModificationID];
_ContextData = _Modification.ContextData;
_WorkflowAssociation = _List.WorkflowAssociations[_WorkflowInstance.AssociationId];
Input controls in the modification form as initialized in the same way that used
in thee association and initiation forms. As the final step, when the OK button
is clicked, call to ModifyWorkflow method on the WorkflowManager is done to pass
the updated context data back to the WF program in a serialized form.
ContextData = SerializeFormDataToString();
Web.Site.WorkflowManager.ModifyWorkflow(WorkflowInstance,
Modification,
ContextData);
At this stage, the control is returned to WF program. The event handler for the OnWorkflowModified
activity fires and allows your code to do whatever it needs to do with the updated
context data. The ContextData property must be data-bound on the OnWorkflowModified
activity to a field within the WF program to obtain access to the data that are
passed back from the modification form. Once this is done, the event handler
can write the updated data from the context data into the fields of the WF program
that are used to persist the data for the current running workflow instance.
Custom Task Edit Forms
We have now reached the final input form: the task edit form. You should develop
and design a custom task edit form when you want to take over the user experience
when it’s time for a user to complete a task. In our example, a custom task edit
form named HelloTaskEdit.aspx is developed for the users to approve or reject
an approval request.

The benefit of using a custom task edit form is that you can add extra command buttons,
direct the user’s attention to the data and input values that matter to complete
the task at hand.
Implementing a Custom Task Edit Form
To Implement custom task edit for requires to create a custom content type that inherits
from the workflow task content type that is part of WSS. The custom content type
created for Hello Approval Workflow template is defined in side workflowTaskContentType.xml
as follows:
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<ContentType
ID="0x0108010084565D92BEFE4a75A28C2F658B7BECCA"
Name="Jatin's workflow task"
Group="Jatin's Content Types"
Description="Create a workflow task"
Version="0"
Hidden="FALSE">
<FieldRefs>
<FieldRef ID="{1CA81E60-3104-4f32-A2AF-9AF74DAA80C1}" Name="Notes" DisplayName="Instructions" />
<FieldRef ID="{7615D4C9-4539-440e-A56B-A6D5B7AC8324}" Name="Comments" DisplayName="Comments" />
</FieldRefs>
<XmlDocuments>
<XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url">
<FormUrls xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url">
<Edit>_layouts/HelloWorkflow/HelloTaskEdit.aspx</Edit>
<Display>_layouts/HelloWorkflow/HelloTaskEdit.aspx</Display>
</FormUrls>
</XmlDocument>
</XmlDocuments>
</ContentType>
</Elements>
0x010801 is the content type ID of the standard workflow task content type. There
for any content type that inherits this must use a vale of 0x010801 as the first
part of its content type ID. You can also see that we’ve added to extra fields
named Notes and Comments to this custom content type.
The XmlDocument section at the bottom of the content definition give the view of
how we can integrate the custom task edit for into a workflow template. When
a user selects to edit an approval task, WSS takes a user to the HelloTaskEdit.aspx
page instead of the standard workflow task edit form.
The instructions that were written into the task when it was created, are retrived
in the OnLoad method of the HelloWorkflowTaskEditForm class. The static method
AlertTask of the SPWorkflowTask class is called in the Approve and Reject button
clicks. This method takes a HashTable of named proeprties as parameter and causes
the event handler for the OnTaskModified activity within the WF program to fire.
Hashtable taskHash = new Hashtable();
taskHash["Status"] = "Completed";
taskHash["Notes"] = "Approved";
taskHash["Comments"] = txtComments.Text.Trim();
SPWorkflowTask.AlterTask(TaskItem, taskHash, true);
Confusion what to choose: .aspx Forms or InfoPath Forms
We walked through the implementation details required to integrate the all four different
types of custom workflow input forms into a workflow template using .aspx files.
But as you see, this is quite hard to integrate custom workflow input forms also
to manage the code for those .aspx pages.
If you are developing workflow templates that run exclusively in a MOSS environment,
you have the much easier option of building you custom workflow input forms by
using the forms designer of Microsoft InfoPath 2007. The InfoPath forms designer
provides you with a great more pleasant experience for creating the user interface
for a workflow template also, it relieves you from writing any code behind .aspx
pages. MOSS provides standard .aspx pages and code for you. The only code need
to be done for this is the serialization of data that goes into WF program and
passes back and forth with the InfoPath forms.
While using InfoPath forms for workflow, that workflow templates have a dependency
on MOSS as WSS does not support this InfoPath forms. Creating the workflow templates
that integrate workflow input forms using .aspx is more flexible because these
templates can be deployed within any WSS farm whether MOSS is installed or not.
Summary
Hope that you have enjoyed and learned a lot about the custom input forms for workflow
template and how to integrate them with the workflow template and how to use.
You can download the source code from here.