A sample EPiServer workflow based on Microsoft workflow foundation. This workflow is started from some pages workflow tab, assigns a task to the role everyone with a custom user interface and terminates when the user clicks accept.
Download source code
EPiServerWorkflowWithGUI.zipCreate the workflow
Create a new project in Visual studio 2008 (the only working one for CMS 6 R2) using the "State Machine Workflow Library" standard template.
Add the EPiServers activity by drag the EPiServer.WorkflowFundation assembly to the tools folder.
Create a .Net 3.5 state machine workflow
Add the EPiServer and EPiServer.WorkflowFoundation assemblies as references to the project
Add a Serializable class to handle event arguments (inheriting from ExternalDataEventArgs)
using System;
using System.Workflow.Activities;
using EPiServer.Core;
namespace EPiServerWorkflowWithGui
{
[Serializable]
public class AcceptedEventArgs : ExternalDataEventArgs
{
public AcceptedEventArgs(Guid instanceId, PageReference pageLink)
: base(instanceId) {}
public PageReference PageLink { get; internal set; }
}
}
Add a workflow service interface (decorated with the ExternalDataExchange attribute) here called IAcceptedService with one event handler named Accepted.
using System;
using System.Workflow.Activities;
namespace EPiServerWorkflowWithGui
{
[ExternalDataExchange()]
public interface IAcceptedService
{
event EventHandler<AcceptedEventArgs> Accepted;
}
}
Use the wca.exe tool to generate event driven activities from the IAcceptedService
wca EPiServerWorkflowWithGui.dll
Two classes should be generated IAcceptedService.Invoke.cs and IAcceptedService.Sink.cs include them in the project.
Build a simple workflow with
One start state activity called Start
One start finish activity called End
Set the properties InitialStateName to Start and CompleleStateName to End
Add a state activity WaitForAccept add an EventDriven activity with your own Accepted activity named WaitForAccepted. Finnish the event by a set state activity with the TargetStateName to End.
To decorate your activity with the ActivityPlugIn so it will work as the GUI for the activity –add a partial class to the activity sinks Accepted class
using EPiServer.WorkflowFoundation.UI;
namespace EPiServerWorkflowWithGui
{
[ActivityPlugIn(
Area = EPiServer.PlugIn.PlugInArea.None,
Url = "~/Templates/Plugins/Workflows/AcceptWorkflow.ascx")]
public partial class Accepted{}
}
To the Start state add a StateInitialization with a CreateTask activity to create the EPiServer task, fill the properties
AssingTo: <your login name> or any group you want to assign the task to
AssosiatedActivity: WaitForAccepted
TaskDescription: Description
TaskSubject: Subject
Add a SetState activity with the property TargetStateName set to "waitForAccept"
Create a service to communicate between the workflow host and your application
using System;
namespace EPiServerWorkflowWithGui
{
public class AcceptedService : IAcceptedService
{
public event EventHandler<AcceptedEventArgs> Accepted;
public void InvokeAcceptedEvent(AcceptedEventArgs args)
{
EventHandler<AcceptedEventArgs> acceptedEvent = Accepted;
if (acceptedEvent != null)
{
acceptedEvent(null, args);
}
}
}
}
Register the workflow service in the sites episerver.config (or web.config)
<episerver...
<workflowSettings…
<externalServices>
<externalService type="EPiServerWorkflowWithGui.AcceptedService, EPiServerWorkflowWithGui" />
Create the user interface
Add a reference to the EPiServerWorkflowWithGui and System.Workflow.Activities to your sites project
Add a user control to use as the user interface for our task in the folder \Templates\Plugins\Workflows
AcceptWorkflow.ascx
<%@ Control Language="C#"
AutoEventWireup="true"
CodeBehind="AcceptWorkflow.ascx.cs"
Inherits="EPiServer.Templates.Plugins.Workflows.AcceptWorkflow" %>
Accerpt this workflow and finnish it!
AcceptWorkflow.ascx.cs
using System;
using System.Web.UI;
using EPiServer.Core;
using EPiServer.WorkflowFoundation;
using EPiServer.WorkflowFoundation.UI;
using EPiServerWorkflowWithGui;
namespace EPiServer.Templates.Plugins.Workflows
{
public partial class AcceptWorkflow : UserControl, IWorkflowTaskControl
{
protected void Page_Load(object sender, EventArgs e) {}
public void ContextData(
Guid workflowInstanceId,
int taskId,
string eventQualifiedName,
EPiServer.Core.PageReference pageLink){}
public string InvokeButtonText{ get { return "Accept"; } }
public bool InvokeEvent(
Guid workflowInstanceId,
int taskId,
string eventQualifiedName)
{
AcceptedService service =
WorkflowSystem.WorkflowManager.GetService<AcceptedService>();
service.InvokeAcceptedEvent(
new AcceptedEventArgs(workflowInstanceId,
PageReference.EmptyReference));
return true;
}
public void PageHasChanged(
EPiServer.Core.PageReference previousPageLink,
EPiServer.Core.PageReference newPageLink)
{}
}
}
Test the project
Add the workflow in Admin mode by selecting "Workflows" below the "Tools" heading.
EPiServerWorkflowWithGui: AcceptWithGui
Class name: EPiServerWorkflowWithGui.Accept
Assembly name: EPiServerWorkflowWithGui
Start the workflow from edit mode
Add a startup configuration interfaceReferences
EPiServer Workflow foundation SDKA well written sample state machine workflow sampleTroubleshooting EPiServer workflows