forge

Replication, Workflow Serialization Problems and DependencyObject

I’ve been working on a workflow that needs to do parallel approval and therefore I have a replicator in the workflow. One of the things that I did was used the pattern of a custom sequence activity inside the replicator to hold the instance data. The custom sequence ends up with a custom property that is set by utilizing the ChildInitialized event of the replicator. You can see Tom Lake’s detailed explanation of this process in the forums: http://social.msdn.microsoft.com/Forums/en-US/windowsworkflowfoundation/thread/ca034011-d2f7-407b-90c5-d0303f753f50

I was using this to manage my set of tasks for the parallel approval. The problem is I was trying to be “nice” and use dependency properties in a class. So my SequenceActivity contained a reference to my class ApprovalTask. The ApprovalTask class contained the properties for the TaskId and TaskProperties (that are needed for managing a task.) To be nice I made these dependency properties which meant that I had to derive ApprovalTask from DependencyObject. To make a long story short, there’s something wrong with deriving from DependencyObject that causes the serialization of the workflow to get screwed up. If you do an OnTaskChanged in your workflow (which makes sense if you want to see if the task was approved or not) you’ll get an error similar to the following in the ULS:

Help Your SharePoint User

Engine RunWorkflow: System.Workflow.Activities.EventDeliveryFailedException: Event “OnTaskChanged” on interface type “Microsoft.SharePoint.Workflow.ITaskService” for instance id “397f2b91-156c-4de2-b07b-6cae2fefd072” cannot be delivered. —> System.ArgumentNullException: Value cannot be null.     at System.Workflow.ComponentModel.DependencyObject.FixUpMetaProperties(DependencyObject originalObject)     at System.Workflow.ComponentModel.DependencyObject.FixUpMetaProperties(DependencyObject originalObject)     at System.Workflow.ComponentModel.Activity.FixUpMetaProperties(DependencyObject originalObject)     at System.Workflow.ComponentModel.CompositeActivity.FixUpMetaProperties(DependencyObject originalObject)     at System.Workflow.ComponentModel.Activity.Load(Stream stream, Activity outerActivity, IFormatter formatter)     at System.Workflow.ComponentModel.Activity.Load(Stream stream, Activity outerActivity)     at System.Workflow.Runtime.Hosting.WorkflowPersistenceService.RestoreFromDefaultSerializedForm(Byte[] activityBytes, Activity outerActivity)     at Microsoft.SharePoint.Workflow.SPWinOePersistenceService.LoadWorkflowInstanceState(Guid instanceId)     at System.Workflow.Runtime.WorkflowRuntime.InitializeExecutor(Guid instanceId, CreationContext context, WorkflowExecutor executor, WorkflowInstance workflowInstance)     at System.Workflow.Runtime.WorkflowRuntime.Load(Guid key, CreationContext context, WorkflowInstance workflowInstance)     at System.Workflow.Runtime.WorkflowRuntime.GetWorkflow(Guid instanceId)     at System.Workflow.Activities.WorkflowMessageEventHandler.EventHandler(Object sender, ExternalDataEventArgs eventArgs)     — End of inner exception stack trace —     at System.Workflow.Activities.WorkflowMessageEventHandler.EventHandler(Object sender, ExternalDataEventArgs eventArgs)     at Microsoft.SharePoint.Workflow.SPWinOETaskService.RaiseEvent(SPWinOeWorkflow workflow, SPWorkflowEvent workflowEvent, Object workItem, IPendingWork workHandler)     at Microsoft.SharePoint.Workflow.SPWinOeHostServices.Send(SPWinOeWorkflow winoeworkflow, SPWorkflowEvent e)     at Microsoft.SharePoint.Workflow.SPWinOeEngine.RunWorkflow(Guid trackingId, SPWorkflowHostService host, SPWorkflow workflow, Collection`1 events, TimeSpan timeOut)

The reason is because when ApprovalTask came back from serialization it’s SPWorkflowTaskProperties property was blank. The solution? Don’t derive from DependencyObject, mark my ApprovalTask as Serializable, and convert the properties into regular properties. This made the problem go away.