Archive for the ‘Workflow’ Category
Developing a custom workflow in EPiServer : Part one
This in a first of a series of posts about how to build a custom EPiServer workflow. There is a fair amount of information about EPiServer workflows (most of which are nicely summarised by Frederik Vig in his amazingly useful EPiServer Developer Resources). Hopeful these posts will be able to add to that and also provide further context. Comments are most welcome!
Over the course of five posts I’ll cover the following:
- Part One – Overview and Requirements
- Part Two – Windows Workflow Foundation in EPiServer
- Part Three – Designing the Workflow
- Part Four – EPiServer tasks and working with the user interface
- Part Five – Access control and finishing touches
Overview
The out-of-the box workflows in EPiServer cover off some common editor based scenarios such as approval and feedback. However the real world always throws up more exacting requirements that can’t be satisfied by the pre-defined workflows (or any combination of them – remember that you can chain them together).
In these situations you’ll have to build your own custom workflow piece utilising Windows Workflow Foundation and EPiServer’s own library of workflow elements and UI integration.
Requirements
First up we must start with requirements gathering. This is often a difficult process with workflows as you have to map and consolidate real business processes into a sensible technical solution.
Workflow requirements are always best distilled by a Visio flow diagram. Fact! So here’s ours (click to enlarge).
Looking at the required process, you can see that it’s a 2-stage approval process, where a page is created, sent for approval, and then finally sent through a further approval step, where upon the page is approved one final time before being published.
There are three user roles who interact with this process:
- Creators, who initially create the content and kick off the workflow.
- Approvers, who can decide to approve or decline the content, or pass on the approval decision.
- Publishers, who can approve or decline the content, and publish the content.
This is only slightly different than the out-of-the-box Sequential Approval workflow, but the following differences necessitate a custom solution:
- There are two stages of approval
- Approvers can opt to ‘pass-the-buck’ and pass the approval stage to a fellow Approver.
- The workflow creator is informed at every decision point.
There are some addtional requirements that can’t be shown on the diagram:
- Pages can only be published using the workflow
- Only one instance of the workflow can be in progress for a page at any one time.
Over the course of the next four posts I’ll piece together a workflow that meets the above requirements, covering the (very) basics of Windows Workflow Foundation and how you can use them and the integration methods that the EPiServer API exposes to allow any custom workflow to be implemented against EPiServer managed content.
Debugging Workflows and HttpContext
I stumbled across one of those ‘frustrating’ bugs last week whilst setting up some simple chained out-of-the-box EPiServer workflows.
The EPiServer UI reported that the workflow instance has successfully started, but no tasks or notifications were ever received and an immediate search for any running workflow instances reported that there were none in progress.
I wasn’t really sure where to start looking. I fired up SQL Profiler and could see that there were some workflow queries being passed, but no data was stored at the end of the request so something, somewhere along the line, was causing the transaction to be rolled back.
Debugging Workflows
The workflow module in EPiServer is built upon the .NET 3.0 workflow functionality and allows custom workflows to be developed which handle typical EPiServer events.
Workflows are managed under their own runtime, which itself is hosted by a .NET application – in this case EPiServer. The runtime is configured in the web.config file, along with the persistence mechanism (SQL Server).
<workflowRuntime EnablePerformanceCounters="false">
<Services>
<add type="System.Workflow.Runtime.Hosting.DefaultWorkflowSchedulerService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" maxSimultaneousWorkflows="5" />
<add type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService, System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" UnloadOnIdle="true" />
</Services>
</workflowRuntime>
Debugging can be enable by adding in and adjusting the following keys (which are commented out towards the bottom of the EPiServer web.config file).
<!--OPTIONAL Workflow Diagnostics - used for logging useful information for debugging purposes-->
<system.diagnostics>
<switches>
<add name="System.Workflow.Runtime" value="Off" />
<add name="System.Workflow.Runtime.Hosting" value="Off" />
<add name="System.Workflow.Runtime.Tracking" value="Off" />
<add name="System.Workflow.Activities" value="Off" />
<add name="System.Workflow.Activities.Rules" value="Off" />
<add name="System.Workflow LogToTraceListeners" value="1" />
<add name="System.Workflow LogToFile" value="0" />
</switches>
</system.diagnostics>
There are two choices of where to log any workflows messages, to file or to a TraceListener (aka the output window in Visual Studio). Full details of the configuration settings can be on found on MSDN.
HttpContext?
Setting up the workflow logging – quickly highlighted my issue. One of the methods in the workflow was throwing an exception which the EPiServer UI wasn’t reporting. The exact stack trace pointed to the application’s custom ProfileProvider which was explicitly trying to store items in the HttpContext.Current.Cache.
Remember that workflows are executed using their own runtime, which means they operate on a thread outside of the current web request. So trying to resolve the HttpContext will always return null. Problem identified!
In summary:
- Debugging workflows can be enabled in web.config.
- Workflows operate under their own runtime.
- Never assume an HttpContext – be careful when rolling your own providers. Certain EPiServer services (scheduled jobs, workflows operate on a background thread).
- The EPiServer UI does not always tell you the full story….
Happy workflowing!
