InfoPath forms, repeating sections, and Workflow Tasks in SharePoint 2007

This was just bound to not work

So, the project I’m working on needs a repeating section in an InfoPath form, which is being used as the display form for a Workflow Task. (Well, apparently it is ‘required’).

InfoPath forms hand back their data into a SPWorkflowTaskProperties object, and custom data – including all the fields on the form – gets put in the ExtendedProperties ‘Dictionary’ (or Hash table, if you’re like me).

The thing is, the items in that hash table are keyed by the name of the field on the form. For example, the following would get the value of the ‘name’ field:

x = AfterTaskChangedProperties1.ExtendedProperties["name"];

The thing about repeating sections, though, is that those field names will be repeated. But the hash key must be unique. So how are repeating sections represented.

I built a form to test this out. When the task was changed, I logged the key and value of everything in the Extended Properties. There were some other things in their – ‘standard’ extended properties – and I’ve stripped them from the log below.

What I did was I opened up the form. I filled in the fields. The repeating section was shown once – one line on the ‘UsersLog’ section. I filled it in, added 2 rows, and filled them in. I then submitted the form. Here’s what the log said:
"DocumentURL" = "Kumquat"
"UsersLog" = "
<ns1:User xmlns:ns1="urn:soj-deltascheme-com.invoiceapproval">
<ns1:NetworkId>1234567890</ns1:NetworkId>
<ns1:Name>AndyData1</ns1:Name>
</ns1:User>
<ns1:User xmlns:ns1="urn:soj-deltascheme-com.invoiceapproval">
<ns1:NetworkId></ns1:NetworkId><ns1:Name></ns1:Name></ns1:User>
<ns1:User xmlns:ns1="urn:soj-deltascheme-com.invoiceapproval">
<ns1:NetworkId></ns1:NetworkId><ns1:Name></ns1:Name></ns1:User>
"
"InvoiceId" = "Juggernaut"
"InvoiceCategory" = "34134"

So, the repeating section gets handed in as a chunk of XML. Great! That could be really useful – except…

Except that it is missing the data from 2 of my lines! It’s got the correct number of ‘ns1:User’ nodes (3), but only the first one ever has data. I’ve repeated, this seems to always be the case.

Bug. Let’s hope the tech refresh fixes it, ‘cos I can’t build the workflow I’ve been asked to with Beta 2.

STILL trying to update the Task Assignee

Right, so I had a suggestion from Nick Swan, and it was a good one, so I gave it a try.

What he said was:

With OnTaskChanged there is the BeforeProperties and AfterProperties variables.

In the event can’t you set the AssignedTo in the AfterProperties?

This seemed perfectly reasonable – and I hadn’t thought of it already, so it was worth a try (wood/trees obscuration).

I created a workflow that consisted of 3 steps – a Create Task step, a While Loop (that is always true) and in the While, I put an onTaskChanged event step.

Creating the task, you set the assignee using an SPWorkflowTaskProperties object. Here is my line for doing that:

TaskProperties.AssignedTo = "MOSS\\Domain Users";

That’s pretty clear. I then wrote code to set the AfterProperties of the onTaskChanged event:

TaskAfterProperties.AssignedTo = e.Identity;

Typically, e.Identity is something link “MOSS\\burnsa”. I’ve checked. And that’s what I’d expect it to be.

So, the workflow enters the while loop – which as I say, deliberately never exits – an the workflow awaits a change in the task. When that change comes, I’m going to look at the AssignedTo field of both the BeforeProperties, and AfterProperties. Oh, yeah, and I deliberately WASN’T changing the assignee within the task.

BeforeProperties – Expected: “MOSS\\Domain Users” – Actual: null

AfterProperties – Expected: “MOSS\\Domain Users” – Actual: “16″

…and setting the AfterProperties with e.Identity did damn all. WTF?

I could understand that setting AfterProperties with e.Identity might not work – although it seems a reasonable thing to try and do – but the AssignedTo fields being null, and then 16? Don’t make no sense.

Oh, further – I tried again, but this time setting the assignee as my change to fire the onTaskChanged event. This time the AfterProperties assignedTo field was ’13′, so clearly it is some sort of identity – just not an obvious or particularly useful one.

Even more on Updating SharePoint Workflow Tasks

Okay, so having tried the programmatic route and got stuck, and investigated it, I realised that I’d been dumb.

There is an UpdateTask workflow activity

Okay, so I missed the obvious – that to update a task would require an activity if it is to work in SharePoint Designer. However, I tried adding this to a workflow. When I went to the workflow code, I got the error:

Code generation for property ‘PercentComplete’ failed. Error was: ‘Property accessor ‘PercentComplete’ on object ‘Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties’ threw the following exeception: ‘Object reference not set to an instance of an object’

Phew. Nice error. Then, sometimes, I managed to get the Designer view to have errors – it couldn’t draw the workflow. And build failed – the workflow designer.cs file lacked the line defining the private variable referencing the UpdateTask object. Oh, and trying to set properties of the task to update – more errors.

The short is, in Beta 2, Update Task doesn’t seem to work. I don’t think that there is a lot I can do to fix this…

Configuration Information for Workflows

In the workflow I’m working on, some xPaths. I don’t want to hard code them, as this is the sort of crap that always changes. However, I’m not sure where a good place to store such properties would be. I’d figured the workflow.xml file, or even features.xml, but I didn’t find information about doing this. All it’d need is a series of properties and values, but neither seems to do that.

I guess I could write an association form – but given that this workflow will only be used on one list, and that the settings shouldn’t change very often, this would be like using an anti-aircraft gun to kill a mosquito.

It is really frustrating to have simple tasks, no documentation, and no answers. I mean, come on guys, all I want to know is the right way to install a config data, and access it.

Confusing Modification Forms and State Machines

I’m building a state machine workflow for MOSS, but as part of this we need to be able to reassign tasks to other users (in case someone is ill, on holiday, etc.)

The ECM Sample Starter Kit has an example that uses an Infopath Modification form to do just that. Looking at the code for it, I can see how it has an ‘EnableWorkflowModification’ step to, well, enable a modification form, and I looked this up on the MSDN site.

The MSDN site pages I looked at here and here discuss the scope of the enabled form. However, this seems to be related to the step it is contained within a sequential workflow. This, presumably, doesn’t apply in a state machine workflow? Or maybe it applies to the whole state (i.e. the state is the scope)- which raises questions as a state might be reached by many routes, without enabling the modification.

More on Updating SharePoint Workflow Tasks

So, I’ve continued investigating my problems updating a SharePoint Workflow Task. I decided to learn about event receivers, as this is what the message was about.

Event receivers, well, receive events that happen on an item, and process them. I listed the ones on my workflow task list with the following code:

for (int j = 0; j < myList.EventReceivers.Count; j++)
{
SPEventReceiverDefinition d = myList.EventReceivers[j];
Log (d.Assembly + " - " + d.Class + " - " + d.Data + " - " + d.Filter + " - " + d.Name + " - " + d.Type.ToString());
}

This gave the the results:

31/08/2006 11:13:57 – Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c – Microsoft.SharePoint.Workflow.WorkflowTaskUpdateEventReceiver – – – – ItemAdding

31/08/2006 11:13:57 – Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c – Microsoft.SharePoint.Workflow.WorkflowTaskUpdateEventReceiver – – – – ItemUpdating

31/08/2006 11:13:57 – Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c – Microsoft.SharePoint.Workflow.WorkflowTaskUpdateEventReceiver – – – – ItemDeleting

31/08/2006 11:13:57 – – – – – – 32767

It turns out that there is an easier way of list the event receivers, but dumping to a log file works. Interestingly, he also had the same 32767 result, which is weird. It’s (2^15)-1, so presumably the highest value that can be represented by a 16bit signed integer – but what is it doing in my log?

Anyway, I reckon that the ItemUpdating event receiver is killing my update – but don’t effing know why.

Incidentally, this is a good article demonstrating event receivers. Shame about the bugs they’re finding, though.

Updating SharePoint ‘Workflow Tasks’

Problems doing the simplest things. I want to update a task created by the CreateTask activity, when the activity is changed. I have the following function, which is run when the Task list item is edited…

private void onTaskChanged1_Invoked(object sender, ExternalDataEventArgs e)
{
SPWeb mySite = new SPSite(workflowProperties.SiteId).OpenWeb(workflowProperties.WebId);
SPList myList = mySite.Lists[workflowProperties.TaskListId];
SPListItem myTask = myList.GetItemById(TaskBeforeProperties.TaskItemId);
SPUser myUser = mySite.AllUsers[e.Identity];
myTask["Assigned To"] = myUser;
myTask.Update();
}

Everything seems okay, but when I call myTask.Update(), I get the exception “An event receiver has cancelled the request.” And I’m damned if I know why.