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
WorkflowAppWCFSampleunderhttp://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\binand will be included in the WorkflowAppWCFSample website/application’s\binfolder.Code:
IService.csusing 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.csusing 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
nameattribute withWorkflowAppWCFSample.Serviceand 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.configNote: 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
WorkflowAppWCFSamplewebsite/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.svcthen choose View in the browser. Note the URL for the WSDL, then run thesvcutiltool in a command prompt. This tool will generate a client proxy .NET classService.csand configuration fileoutput.configto 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.ServiceModeland the WorkflowGen.My v2.3.4 library (\wfgen\bin). -
Add the generated client proxy .NET class
Service.csinto the project. -
Edit the
Service.csfile by removing the generated namespace WorkflowGen.My.Data {…} code completely. -
Add the
IServiceinterface and the rest of the code into a namespace calledWorkflowAppWCFSampleTest. -
Update the
ConfigurationNameof theServiceContractAttributeof the IService interface withWorkflowAppWCFSampleTest.IService". -
Compile the
WorkflowAppWCFSampleTestproject and deploy theWorkflowAppWCFSampleTest.dllinto the\wfgen\binfolder.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\binandDRIVE:\Program Files\Advantys\WorkflowGen\Services\binfolders. (For more information, see Workflow Application: Assembly: The assembly system action started but did not complete successfully.)See the sample pack for the
Service.cssource 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.configfile generated in step 5 under the<configuration>node.ii. Update the endpoint’s
contractattribute withWorkflowAppWCFSampleTest.IService.iii. Update the binding’s
maxReceivedMessageSizeandmaxArrayLengthattributes 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.configand add the complete<bindings>node from step 8 above under the<system.serviceModel>node.ii. Update the endpoint’s
bindingConfigurationattribute withWSHttpBinding_IServiceConfiguration: 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.configiii. 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.WorkflowFileobject:public WorkflowFile GetWorkflowFile(WorkflowFile message) { message.Save("c:\\temp"); return message; } -
If your method uses an
XmlDocument,XmlNode, orXmlElementobject: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.