1.关联可以保证消息之间的正确路由,本文举一个简单的例子,首先定义一个流程表单类,如下:
namespace CaryContract
{
[DataContract]
public class FlowForm
{
[DataMember]
public Guid FormNum { get; set; }
[DataMember]
public string FlowStatus { get; set; }
[DataMember]
public string ApplyName { get; set; }
[DataMember]
public string ApplyContent { get; set; }
}
}
2.然后工作流中完成提交申请和审批两个动作,每个动作我们都使用了ReceiveAndSendReply模板,具体
设计如下:
3.对应工作流的XAML如下:
<Activity mc:Ignorable="sap" x:Class="CaryService.Workflow1" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:c="clr-namespace:CaryContract;assembly=CaryContract, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns:c1="clr-namespace:CaryContract;assembly=CaryContract" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="clr-namespace:Microsoft.VisualBasic;assembly=System" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:p="http://schemas.microsoft.com/netfx/2009/xaml/servicemodel" xmlns:s="clr-namespace:System;assembly=mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" xmlns:s1="clr-namespace:System;assembly=mscorlib" xmlns:s2="clr-namespace:System;assembly=System" xmlns:s3="clr-namespace:System;assembly=System.Xml" xmlns:s4="clr-namespace:System;assembly=System.Core" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=System" xmlns:scg1="clr-namespace:System.Collections.Generic;assembly=System.ServiceModel" xmlns:scg2="clr-namespace:System.Collections.Generic;assembly=System.Core" xmlns:scg3="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:sd="clr-namespace:System.Data;assembly=System.Data" xmlns:sd1="clr-namespace:System.Data;assembly=System.Data.DataSetExtensions" xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" xmlns:ssa="clr-namespace:System.ServiceModel.Activities;assembly=System.ServiceModel.Activities" xmlns:ssx="clr-namespace:System.ServiceModel.XamlIntegration;assembly=System.ServiceModel" xmlns:st="clr-namespace:System.Text;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Sequence sad:XamlDebuggerXmlReader.FileName="c:\users\baby\documents\visual studio 2010\Projects\CaryService\CaryService\Workflow1.xaml" sap:VirtualizedContainerService.HintSize="300,1056">
<Sequence.Variables>
<Variable x:TypeArguments="c1:FlowForm" Name="flowApp" />
<Variable x:TypeArguments="p:CorrelationHandle" Name="flowHandle" />
</Sequence.Variables>
<sap:WorkflowViewStateService.ViewState>
<scg3:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg3:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<Sequence DisplayName="提交申请" sap:VirtualizedContainerService.HintSize="278,446">
<Sequence.Variables>
<Variable x:TypeArguments="p:CorrelationHandle" Name="__handle1" />
</Sequence.Variables>
<sap:WorkflowViewStateService.ViewState>
<scg3:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
<x:Boolean x:Key="IsPinned">False</x:Boolean>
</scg3:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<p:Receive x:Name="__ReferenceID0" CanCreateInstance="True" CorrelatesWith="[flowHandle]" sap:VirtualizedContainerService.HintSize="256,92" OperationName="SendFlow" ServiceContractName="FlowService">
<p:Receive.CorrelatesOn>
<p:XPathMessageQuery x:Key="key1">
<p:XPathMessageQuery.Namespaces>
<ssx:XPathMessageContextMarkup>
<x:String x:Key="xg0">http://schemas.datacontract.org/2004/07/CaryContract</x:String>
<x:String x:Key="xgSc">http://tempuri.org/</x:String>
</ssx:XPathMessageContextMarkup>
</p:XPathMessageQuery.Namespaces>sm:body()/xgSc:SendFlow/xgSc:p1/xg0:FormNum</p:XPathMessageQuery>
</p:Receive.CorrelatesOn>
<p:Receive.CorrelationInitializers>
<p:RequestReplyCorrelationInitializer CorrelationHandle="[__handle1]" />
</p:Receive.CorrelationInitializers>
<p:ReceiveParametersContent>
<OutArgument x:TypeArguments="c1:FlowForm" x:Key="p1">[flowApp]</OutArgument>
</p:ReceiveParametersContent>
</p:Receive>
<Assign sap:VirtualizedContainerService.HintSize="256,58">
<Assign.To>
<OutArgument x:TypeArguments="s1:Guid">[flowApp.FormNum]</OutArgument>
</Assign.To>
<Assign.Value>
<InArgument x:TypeArguments="s1:Guid">[Guid.NewGuid()]</InArgument>
</Assign.Value>
</Assign>
<p:SendReply Request="{x:Reference __ReferenceID0}" DisplayName="SendReplyToReceive" sap:VirtualizedContainerService.HintSize="256,92">
<p:SendParametersContent>
<InArgument x:TypeArguments="x:String" x:Key="result">[flowApp.FormNum.ToString() + "-" + flowApp.ApplyName + "-" + flowApp.ApplyContent + "-" + flowApp.FlowStatus]</InArgument>
</p:SendParametersContent>
</p:SendReply>
</Sequence>
<Sequence DisplayName="审批" sap:VirtualizedContainerService.HintSize="278,446">
<Sequence.Variables>
<Variable x:TypeArguments="p:CorrelationHandle" Name="__handle1" />
<Variable x:TypeArguments="s1:Guid" Name="flowID" />
<Variable x:TypeArguments="x:String" Name="flowStatus" />
</Sequence.Variables>
<sap:WorkflowViewStateService.ViewState>
<scg3:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
<x:Boolean x:Key="IsPinned">False</x:Boolean>
</scg3:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<p:Receive x:Name="__ReferenceID1" CorrelatesWith="[flowHandle]" sap:VirtualizedContainerService.HintSize="256,92" OperationName="ApproveFlow" ServiceContractName="FlowService">
<p:Receive.CorrelatesOn>
<p:XPathMessageQuery x:Key="key1">
<p:XPathMessageQuery.Namespaces>
<ssx:XPathMessageContextMarkup>
<x:String x:Key="xgSc">http://tempuri.org/</x:String>
</ssx:XPathMessageContextMarkup>
</p:XPathMessageQuery.Namespaces>sm:body()/xgSc:ApproveFlow/xgSc:pid</p:XPathMessageQuery>
</p:Receive.CorrelatesOn>
<p:Receive.CorrelationInitializers>
<p:RequestReplyCorrelationInitializer CorrelationHandle="[__handle1]" />
</p:Receive.CorrelationInitializers>
<p:ReceiveParametersContent>
<OutArgument x:TypeArguments="s1:Guid" x:Key="pid">[flowID]</OutArgument>
<OutArgument x:TypeArguments="x:String" x:Key="pstatus">[flowStatus]</OutArgument>
</p:ReceiveParametersContent>
</p:Receive>
<Assign sap:VirtualizedContainerService.HintSize="256,58">
<Assign.To>
<OutArgument x:TypeArguments="x:String">[flowApp.FlowStatus]</OutArgument>
</Assign.To>
<Assign.Value>
<InArgument x:TypeArguments="x:String">[flowStatus]</InArgument>
</Assign.Value>
</Assign>
<p:SendReply Request="{x:Reference __ReferenceID1}" DisplayName="SendReplyToReceive" sap:VirtualizedContainerService.HintSize="256,92">
<p:SendParametersContent>
<InArgument x:TypeArguments="x:String" x:Key="result">[flowApp.FormNum.ToString() + "-" + flowApp.ApplyName + "-" + flowApp.ApplyContent + "-" + flowApp.FlowStatus]</InArgument>
</p:SendParametersContent>
</p:SendReply>
</Sequence>
</Sequence>
</Activity>
4.我们使用WorkflowServiceHost来宿主工作流如下:
namespace CaryService
{
class Program
{
static void Main(string[] args)
{
string baseAddress = "http://localhost:8081/FlowService";
using (WorkflowServiceHost shost = new WorkflowServiceHost(new Workflow1(), new Uri(baseAddress)))
{
shost.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true });
shost.Open();
Console.WriteLine("FlowService is listening:" + baseAddress);
Console.ReadLine();
}
}
}
}
5.客户端使用WebForm,WebForm1.aspx对应的cs文件的代码如下:
namespace CaryClient
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
FlowForm flow = new FlowForm();
ServiceReference1.FlowServiceClient fs = new ServiceReference1.FlowServiceClient();
flow.ApplyName = TextBox1.Text;
flow.ApplyContent = TextBox2.Text;
flow.FlowStatus = "申请";
ListBox1.Items.Add(fs.SendFlow(flow));
}
protected void Button2_Click(object sender, EventArgs e)
{
FlowForm flow = new FlowForm();
flow.FlowStatus = "审批";
ServiceReference1.FlowServiceClient fs = new ServiceReference1.FlowServiceClient();
ListBox1.Items.Add(fs.ApproveFlow(flow.FormNum,flow.FlowStatus));
}
}
}
6.执行结果如下: