Walkthrough: Create SharePoint 2010 Workflow Association Form and Initiation Form in Visual Studio 2010 by using Application Pages (Part 2 of 2)

This is Part 2 of 2 that describes the steps 18 to 27 . You will find Part 1 here: https://blog.kenaro.com/2011/04/24/walkthrough-create-sharepoint-2010-workflow-association-form-and-initiation-form-in-visual-studio-2010-by-using-application-pages-part-1-of-2/

The followings steps describe how to create a new sequential workflow in a Visual Studio 2010 project and associate a Initiation and Association Form with the workflow. Furthermore we will test the project. – In Part 1 we have created:

  • a Workflow Task list definition: “Workflow 2 Tasks”
  • a Workflow Host List definition: “Workflow 2 Host List”
  • a Data class: “Workflow2Data”
  • a base class "Workflow2DataPages” for the association and initiation form.
  • a Association Form
  • a Initiation Form.

Now we will go on.

Let’s start…

18. Deploy the project Smile – This will create  the list instances we need to create the workflow and assign them to lists for debug purpose. Of course you do not need to assign lists (such as Workflow Task List, History List, …) to the workflow at design time in Visual Studio. You could do this later, e.g. in a Feature Receiver.

19. Add a “Sequential Workflow” project item named “Workflow 2”.

image

Set “Workflow 2” as display name and “List workflow” as type.

image

Set “Workflow 2 Host List” as “library or list to associate with”, choose “Workflow History” in the second dropdown and choose “Workflow 2 Tasks” as list for “workflow tasks” in the third dropdown.

image

Now choose only “Start manually” in the next dialog.

image

20. Now the workflow designer opens.

image

Double click on “onWorkflowActivated1”. A new class member will be created in the workflows “codebehind” file.

Now add the following “usings” at the beginning of the file:

using System.IO;
using System.Xml;
using System.Xml.Serialization;

Above the previously created class member “onWorkflowActivated1_Invoked” add the following code. This will create a dependency property that will be persisted in the workflows data.

(You can use Visual Studio IntelliSense: type “propdp” and press “tab” two times. Then the structure of a new dependency property will be created.)

public Workflow2Data WorkflowDataAssociation
{
    get
    {
        return (Workflow2Data)GetValue(WorkflowDataAssociationProperty);
    }
    set
    {
        SetValue(WorkflowDataAssociationProperty, value);
    }
}

// Using a DependencyProperty as the backing store for WorkflowDataAssociation.  
//   This enables animation, styling, binding, etc...
public static readonly DependencyProperty WorkflowDataAssociationProperty =
    DependencyProperty.Register("WorkflowDataAssociation", typeof(Workflow2Data), typeof(Workflow_2));
 

Now add another dependency property of the “Initiation” data:

public Workflow2Data WorkflowDataInitiation
{
    get
    {
        return (Workflow2Data)GetValue(WorkflowDataInitiationProperty);
    }
    set
    {
        SetValue(WorkflowDataInitiationProperty, value);
    }
}

// Using a DependencyProperty as the backing store for WorkflowDataInitiation.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty WorkflowDataInitiationProperty =
    DependencyProperty.Register("WorkflowDataInitiation", typeof(Workflow2Data), typeof(Workflow_2));
 

We need to do this because Association and Initiation data are stored separatly.

In the method “onWorkflowActivated1_Invoked” enter this code:

using( StringReader stringReader = new StringReader(workflowProperties.AssociationData) )
{
    using( XmlReader reader = XmlReader.Create(stringReader) )
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Workflow2Data));
        WorkflowDataAssociation = (Workflow2Data)serializer.Deserialize(reader);
    }
}

using( StringReader stringReader = new StringReader(workflowProperties.InitiationData) )
{
    using( XmlReader reader = XmlReader.Create(stringReader) )
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Workflow2Data));
        WorkflowDataInitiation = (Workflow2Data)serializer.Deserialize(reader);
    }
}

This will deserialize the workflows association data for using them inside the workflows code.

21. Now we need tho modify the “Elements.xml” file of the “Workflow 2” project item.

We add the attribute “AssociationUrl” and set it’s value to “Workflow2Forms/Workflow2AssociationForm.aspx” and add the attribute “InstantiationUrl” with value “Workflow2Forms/Workflow2InitiationForm.aspx”.

image

22. Now we can deploy the project and see the first results of our (hard) work.

23. Open the URL “http://sharepoint.local/sites/workflow/Lists/Workflow2HostList” in the browser.

Then open the “List” tab in the Ribbon and click “Workflow Settings”.

Now you should see the associated “Workflow 2”:

image

Click them.

At the bottom of the next page you will find the “Next” button that will open the association form. Click this button.

You see your association form page:

image

Super! – Press “OK”.

24. Now we add a new list item to the “Workflow 2 Host List” and start the “Workflow 2” manually:

image

“OK”.

image

Choose “Workflows” from the context menu of the created list item.

image

Click “Workflow 2”.

image

You see your Initiation Form!!

Click “OK” and the workflow will start – and will be “Completed”.

25. Let’s define a Code Activity to use the initiation data.

In the workflow designer drag a “LogToHistoryListActivity” activity from the Toolbox pane into the Workflow designer view of “Workflow 2” and drop it behind “onWorkflowActivated1”.

image

Now select the “logToHistoryListActivity1”. In the Properties pane select the property “HistoryDescription” and click the button beside the edit box of this property. In the upcoming dialog we will bind property “Data1” of the WorkflowDataAssociation object to the activities property:

image

Click “OK”.

Now we add a “Delay” activity behind “logToHistoryListActivity1” and set the delay “TimeDuration” to “00:01:00”. This forces the workflow to delay the execution of the next activities for the defined amount of time.

Now we add another “LogToHistoryListActivity” and bind it’s “HistoryDescription” property to “WorkflowDataInitiation.Data3” as described above.

image

(The workflow after adding the two activities)

image

(Properties of the “delayActivity1” activity.)

 image

(Properties of the “logToHistoryListActivity2”.)

26. Deploy the project and open the “Workflow 2 Host List” in the browser. Modify the association of the “Workflow 2” of the list and enter some information on the association form:

image

Now add an item to the list, start the “Workflow 2” on this item and enter some data in the initiation form:

image

After the workflow starts the information stored in “Data1” you entered in the association form will be written to the workflows history:

image

After about 1 minute the workflow will add another workflow history entry with the content of the “Data3” property entered in the initiation form:

image

27. That’s it! – Everything works as expected. – Thanks for reading! –

Please post your comments or question!

12 thoughts on “Walkthrough: Create SharePoint 2010 Workflow Association Form and Initiation Form in Visual Studio 2010 by using Application Pages (Part 2 of 2)

  1. Hi Ingo,
    I tried your walkthrough but I got an Exception on class Workflow2AssociationForm in the line:

    workflowOptions.autoStartCreate = (Request.Params[“AutoStartCreate”] == “ON”);

    “Object reference not set to an instance of an object.”

    I used a document library instead of a custom list as Workflow host list, could be this the problem?

    thank you in advance,

    Luca

    1. Hi Luca!

      I would recommand to debug into the code and check whether the REQUEST object exists and what parameters are available in “Params”. Are you sure that you use the form as Association Form??

      How dow you call the site? – You have to use it while manually associating a workflow to a list or library… You cannot call this page in browser by typing its url. It does need data by HTTP POST!! If you access the page directly in the browser you are doing a HTTP GET.

      It should work with an library instead of an list.

      Kind regards
      Ingo

  2. Hi,Ingo!
    Thanks for the information, however, I have this problem with workflow 2:
    On Workflow2AssociationForm.aspx, this line gives an exception:

    string strPD = “Use this page to customize this instance of ” + m_workflowName + “.”;

    The reason is simple: there is no m_workflowName field!
    Can you fix it? Of course, I can fix it easily by removing this code, but I don’t know how to get the instance name.

    Thanks!

    RP

    1. m_workflowName should be workflowName, I can compile, but when I deploy, I got the following error:

      A Project Item with the following item ID could not be found: 560c4bdf-3296-4413-b58a-542da3e63a9d

      Can anyone advise, thanks

      1. The author has a copyright notice in the project that is called GPLv2.txt. I think the item pertains to it. You probably deleted it from the file system and not the project. Close VS. Open up the Package.package file (in package folder) using notepad. Delete the projectitems node with the GUID in it…

        That worked for me. Haven’t fully tested the workflow but it deployed and I see all the history and task lists have been created. Good luck.

  3. Hi Ingo!
    Is it possible to support some kind of client-side initiation form data validation? Can you give me direction to implement it?

    1. hi!

      this is possible.

      one way could be:

      1. “edit control block” menu item to open an application page with parameters listId, itemId.
      2. application page that start some client side code (javascript, silverlight,…)
      3. client side code that collects data from the user and starts a workflow by calling a web service
      4. web service that starts the workflow on the server.

      kind regards
      ingo

  4. Hi Ingo,

    Thank you for this fantastic tutorial !
    After some time, I managed to get my own version working, and I think I now got the concept – great, just great !

    Now I’m wondering how I could have different forms depending on the workflow step (or task) tey are associated to. (imagine a much more complex workflow, having tasks requiring minimal information to be displayed, and others having a lot of fields involved)
    Do you see any easy way to handle this ?

    Tanks,

    nico

    1. Well, even though I followed both walkthroughs, may be this question relates more to the previous one “Creating a simple Sequential Workflow with a custom Task Form in SharePoint 2010 using Visual Studio 2010”.
      Sorry if it creates any confusion…

  5. Hi,
    I am getting an error as “Error occurred in deployment step ‘Activate Features’: Cannot complete this action.

    Please try again.”.Please let me know if i am going beyond the process to move ahead

    Thanks & Regards,
    Sudheer

Leave a Reply

Your email address will not be published. Required fields are marked *