As of version 5.6.2, WorkflowGen includes the WCF Service workflow application, which allows you to declare a WCF Service client proxy .NET class method as a workflow application.
The following example provides instructions on how to create a simple WCF Service with methods used as workflow applications. You can download the Workflow Application WCF Service Sample Pack for the complete sample source code.
Each supported datatype (Text, Numeric, DateTime, File) has a corresponding method. The supported .NET datatypes for each WorkflowGen process data datatype are:
-
Text:
String
,Char
,Byte
,SByte
,Boolean
-
Numeric:
Int16
,Int32
,Int64
,UInt16
,UInt32
,UInt64
,Single
,Decimal
,Double
-
DateTime:
DateTime
-
File:
XmlDocument
,XmlNode
,XmlElement
,WorkflowFile
Method
-
In Visual Studio, create a new .NET WCF Service website/application called
WorkflowAppWCFSample
underhttp://localhost/wfgen/WfApps/WebServices
.Note: WorkflowGen version 5.x.x supports .NET 2.0 and .NET 3.5; WorkflowGen versions 6.x.x and 7.x.x support .NET 4 and .NET 4.5.
-
Add a reference to WorkflowGen.My.dll v2.3.4 or above (this is only required when you need to exchange files). This library is found in
\wfgen\bin
and will be included in the WorkflowAppWCFSample website/application’s\bin
folder.Code:
IService.cs
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; using System.Xml; using WorkflowGen.My.Data; namespace WorkflowAppWCFSample { [ServiceContract] public interface IService { [OperationContract] string GetString(string message); [OperationContract] DateTime GetDateTime(DateTime message); [OperationContract] Double GetDouble(Double message); [OperationContract, XmlSerializerFormat] XmlDocument GetFileXmlDocument(XmlDocument message); [OperationContract, XmlSerializerFormat] XmlNode GetFileXmlNode(XmlNode message); [OperationContract] XmlElement GetFileXmlElement(XmlElement message); [OperationContract] WorkflowFile GetWorkflowFile(WorkflowFile message); } }
Reference:
Workflow Application WCF Service Sample Pack\WCF Service Web Site\WorkflowAppWCFSample\App_Code\IService.cs
.Code:
Service.cs
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; using System.Xml; using WorkflowGen.My.Data; namespace WorkflowAppWCFSample { public class Service : IService { public string GetString(string message) { return message + "!" } public DateTime GetDateTime(DateTime message) { return message.AddDays(1); } public Double GetDouble(Double message) { return message * 10; } public XmlDocument GetFileXmlDocument(XmlDocument message) { if (WorkflowFile.IsWorkflowFile(message)) { WorkflowFile file = new WorkflowFile(message); file.Save(@"c:\temp"); return file.GetXmlDoc(); } else { return message; } } public XmlNode GetFileXmlNode(XmlNode message) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(message.OuterXml); if (WorkflowFile.IsWorkflowFile(xmlDoc)) { WorkflowFile file = new WorkflowFile(xmlDoc); file.Save(@"c:\temp"); return file.GetXmlDoc(); } else { return message; } } public XmlElement GetFileXmlElement(XmlElement message) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(message.OuterXml); if (WorkflowFile.IsWorkflowFile(xmlDoc)) { WorkflowFile file = new WorkflowFile(xmlDoc); file.Save(@"c:\temp"); return file.GetXmlDoc().DocumentElement; } else { return message; } } public WorkflowFile GetWorkflowFile(WorkflowFile message) { message.Save(@"c:\temp"); return message; } } }
Reference:
Workflow Application WCF Service Sample Pack\WCF Service Web Site\WorkflowAppWCFSample\App_Code\Service.cs
-
Update the Service attribute with
WorkflowAppWCFSample.Service
.Code: Service.svc
<%@ ServiceHost Language="C#" Debug="true" Service="WorkflowAppWCFSample.Service" CodeBehind="~/App_Code/Service.cs" %>
Reference:
Workflow Application WCF Service Sample Pack\WCF Service Web Site\WorkflowAppWCFSample\Service.svc
-
Update the service
name
attribute withWorkflowAppWCFSample.Service
and the contract attribute withWorkflowAppWCFSample.IService
.Configuration: WorkflowAppWCFSample web.config
<services> <service name="WorkflowAppWCFSample.Service" behaviorConfiguration="ServiceBehavior"> <endpoint address="" binding="wsHttpBinding" contract="WorkflowAppWCFSample.IService"> </endpoint> </service> </services>
Reference:
Workflow Application WCF Service Sample Pack\WCF Service Web Site\WorkflowAppWCFSample\Web.config
Note: By default, this example WCF Service web site/app is configured in Anonymous authentication. For testing, you must enable the Anonymous authentication in IIS for the
WorkflowAppWCFSample
website/application. We’ll look at the three other authentication methods (Basic, Windows Integrated, and X.509 Certificate) in a later step. -
Build the website in Visual Studio.
-
Create the WCF Service client proxy .NET class using the svcutil tool.
Reference for svcutil tool: http://msdn.microsoft.com/en-us/library/aa347733(v=vs.110).aspx
-
In Visual Studio, right-click on
Service.svc
then choose View in the browser. Note the URL for the WSDL, then run thesvcutil
tool in a command prompt. This tool will generate a client proxy .NET classService.cs
and configuration fileoutput.config
to be used in your WorkflowGen application as a client to call your WCF Service.Command prompt
svcutil.exe http://localhost/wfgen/WfApps/WebServices/WorkflowAppWCFSample/Service.svc?wsdl
-
In Visual Studio, create a new .NET 3.5 Class Library called
WorkflowAppWCFSampleTest
. -
Add a reference to the .NET libraries
System.Runtime.Serialization
,System.ServiceModel
and the WorkflowGen.My v2.3.4 library (\wfgen\bin
). -
Add the generated client proxy .NET class
Service.cs
into the project. -
Edit the
Service.cs
file by removing the generated namespace WorkflowGen.My.Data {…} code completely. -
Add the
IService
interface and the rest of the code into a namespace calledWorkflowAppWCFSampleTest
. -
Update the
ConfigurationName
of theServiceContractAttribute
of the IService interface withWorkflowAppWCFSampleTest.IService"
. -
Compile the
WorkflowAppWCFSampleTest
project and deploy theWorkflowAppWCFSampleTest.dll
into the\wfgen\bin
folder.Note: If you use Remote Approval, the Web Services API, or the WorkflowGen Engine service to complete workflow actions, you must also copy the DLL into the
\wfgen\ws\bin
andDRIVE:\Program Files\Advantys\WorkflowGen\Services\bin
folders. (For more information, see Workflow Application: Assembly: The assembly system action started but did not complete successfully.)See the sample pack for the
Service.cs
source code.Reference:
Workflow Application WCF Service Sample Pack\WCF Service Client Proxy\WorkflowAppWCFSampleTest\Service.cs
-
Configure WorkflowGen for the WCF Service client proxy:
i. Edit WorkflowGen’s web.config and add the complete
<system.serviceModel>
node from theoutput.config
file generated in step 5 under the<configuration>
node.ii. Update the endpoint’s
contract
attribute withWorkflowAppWCFSampleTest.IService
.iii. Update the binding’s
maxReceivedMessageSize
andmaxArrayLength
attributes with104857600
(100 MB) to allow large file transfers.Configuration: WorkflowGen
web.config
<system.serviceModel> <bindings> <wsHttpBinding> <binding name="WSHttpBinding_IService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00 bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard maxBufferPoolSize="524288" maxReceivedMessageSize="104857600"messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false"><br /> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="104857600 maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" /> <security mode="Message"> <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" /> <message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" establishSecurityContext="true" /> </security> </binding> </wsHttpBinding> </bindings> <client> <endpoint address="http://localhost/wfgen/WfApps/WebServices/WorkflowAppWCFSample/Service.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService" contract="WorkflowAppWCFSampleTest.IService" name="WSHttpBinding_IService"> <identity> <dns value="localhost" /> </identity> </endpoint> </client> </system.serviceModel>
Reference:
Workflow Application WCF Service Sample Pack\WorkflowGen Configuration\web.config
-
Configure the WCF Service website/application:
i. Edit the WorkflowAppWCFSample
web.config
and add the complete<bindings>
node from step 8 above under the<system.serviceModel>
node.ii. Update the endpoint’s
bindingConfiguration
attribute withWSHttpBinding_IService
Configuration: WorkflowAppWCFSample
web.config
<system.serviceModel> <bindings> <wsHttpBinding> <binding name="WSHttpBinding_IService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="104857600" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="104857600" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" /> <security mode="Message"> <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" /> <message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" establishSecurityContext="true" /> </security> </binding> </wsHttpBinding> </bindings> <services> <service name="WorkflowAppWCFSample.Service" behaviorConfiguration="ServiceBehavior"> <!-- Service Endpoints --> <endpoint address="" binding="wsHttpBinding" contract="WorkflowAppWCFSample.IService" bindingConfiguration="WSHttpBinding_IService"> <identity> <dns value="localhost"/> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="ServiceBehavior"> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
Reference:
Workflow Application WCF Service Sample Pack\WCF Service Web Site\WorkflowAppWCFSample\Web.config
iii. On the Applications screen in the WorkflowGen Administration Module, click New application and configure it as follows:
-
Name:
WCFSERVICE_SAMPLE_GET_STRING
-
Description: Returns a string with a
!
- Type: WCF Service
- Assembly full name or path: WorkflowAppWCFSampleTest
Click Save.
-
Class full name: Select
WorkflowAppWCFSampleTest.ServiceClient
-
Method: Select
GetString
These parameters are automatically generated:
-
IN message (Text)
-
OUT
RETURN_VALUE
(Text)
-
Name:
You can now use this workflow application in your processes. You can repeat the application creation for each class method to test the other datatypes.
Note: WorkflowGen does not yet support method overload (two methods with the same name but different parameters). This will be supported in a future release.
Notes
Authentication methods
The following authentication methods are supported:
-
Basic authentication: See the Workflow Application: How to configure a WCF Service workflow application for IIS Basic Authentication article.
-
Windows Integrated authentication: See the Workflow Application: How to configure a WCF Service workflow application for IIS Windows Authentication article.
-
X.509 Certificate authentication: See the Workflow Application: How to configure a WCF Service workflow application for Certificate Authentication article.
References
http://msdn.microsoft.com/en-us/library/ff647503.aspx
About File parameter
You can send or receive the content of a File to or from your .NET Class Method. There are two ways to do this:
-
If your method uses a
WorkflowGen.My.Data.WorkflowFile
object:public WorkflowFile GetWorkflowFile(WorkflowFile message) { message.Save("c:\\temp"); return message; }
-
If your method uses an
XmlDocument
,XmlNode
, orXmlElement
object:public XmlDocument GetFile(XmlDocument message) { if (WorkflowFile.IsWorkflowFile(message)) { WorkflowFile file = new WorkflowFile(message); return file.GetXmlDoc(); } else { return message; } }
In this case your method can convert the XmlDocument
, XmlNode
, or XmlElement
into a WorkflowFile
object.
You can use WorkflowFile.IsWorkflowFile()
static method to check if the XmlDocument is a WorkflowFile.
Since the file content is stored in memory and sent over the network, you should avoid using these solutions for very large files.