1. 创建一个空白的项目,在其中创建Host – Windows Console Application,Client – Windows forms Application和DataExchangeWorkflows – Activity Library这三个项目。创建后应该结构类似于下图:

2. 将工作流DataExchangeActivity.xaml设计为如下样式:

有几点需要注意:

1) 第一个Receive Activity的CanCreateInstance必须为True,否则客户端调用此Receive无法生成实例(一个工作流只需要第一个的CanCreateInstance为True)

2) TicketId变量保存生成的工作流示例编号,在后面更新时客户端将根据TicketId来更新状态。

3) _handler的类型是CorrelationHandle。_handler的作用是根据客户端发送过来的TicketId,搜索相匹配的工作流的TicketId。

4) 刚才说过,_handler是用于搜索相匹配的工作流的TicketId,在第二个Receive Activity「CheckCredit」的ServiceContractName不能为空白,否则在设置CorrelationOn的属性的时候,选择Id属性会报”ServiceContractName and OperationName properties of activity ‘Receive’ must be set in order to generate XPath”这个错。

5) 需要设置三个Arguments,用于传递Receive Activity「CheckCredit」的参数。

6) 最后生成的XML如下:

 <Activity mc:Ignorable="sap sap2010 sads" x:Class="DataExchangeWorkflows.DataExchangeActivity"

  xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities"

  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

  xmlns:mca="clr-namespace:Microsoft.CSharp.Activities;assembly=System.Activities"

  xmlns:p="http://schemas.microsoft.com/netfx/2009/xaml/servicemodel"

  xmlns:sads="http://schemas.microsoft.com/netfx/2010/xaml/activities/debugger"

  xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation"

  xmlns:sap2010="http://schemas.microsoft.com/netfx/2010/xaml/activities/presentation"

  xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib"

  xmlns:sco="clr-namespace:System.Collections.ObjectModel;assembly=mscorlib"

  xmlns:ssx="clr-namespace:System.ServiceModel.XamlIntegration;assembly=System.ServiceModel"

  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

   <x:Members>

     <x:Property Name="action" Type="InArgument(x:String)" />

     <x:Property Name="reviewId" Type="InArgument(x:Int32)" />

     <x:Property Name="comment" Type="InArgument(x:String)" />

   </x:Members>

   <sap2010:ExpressionActivityEditor.ExpressionActivityEditor>C#</sap2010:ExpressionActivityEditor.ExpressionActivityEditor>

   <sap2010:WorkflowViewState.IdRef>DataExchangeWorkflows.DataExchangeActivity_1</sap2010:WorkflowViewState.IdRef>

   <TextExpression.NamespacesForImplementation>

     <sco:Collection x:TypeArguments="x:String">

       <x:String>System</x:String>

       <x:String>System.Collections.Generic</x:String>

       <x:String>System.Data</x:String>

       <x:String>System.Linq</x:String>

       <x:String>System.Text</x:String>

       <x:String>System.ServiceModel.Activities</x:String>

     </sco:Collection>

   </TextExpression.NamespacesForImplementation>

   <TextExpression.ReferencesForImplementation>

     <sco:Collection x:TypeArguments="AssemblyReference">

       <AssemblyReference>Microsoft.CSharp</AssemblyReference>

       <AssemblyReference>System</AssemblyReference>

       <AssemblyReference>System.Activities</AssemblyReference>

       <AssemblyReference>System.Core</AssemblyReference>

       <AssemblyReference>System.Data</AssemblyReference>

       <AssemblyReference>System.Runtime.Serialization</AssemblyReference>

       <AssemblyReference>System.ServiceModel</AssemblyReference>

       <AssemblyReference>System.ServiceModel.Activities</AssemblyReference>

       <AssemblyReference>System.Xaml</AssemblyReference>

       <AssemblyReference>System.Xml</AssemblyReference>

       <AssemblyReference>System.Xml.Linq</AssemblyReference>

       <AssemblyReference>mscorlib</AssemblyReference>

       <AssemblyReference>DataExchangeWorkflows</AssemblyReference>

     </sco:Collection>

   </TextExpression.ReferencesForImplementation>

   <Sequence sap2010:WorkflowViewState.IdRef="Sequence_1">

     <Sequence.Variables>

       <Variable x:TypeArguments="p:CorrelationHandle" Name="_handler" />

       <Variable x:TypeArguments="x:Int32" Default="-1" Name="TicketId" />

     </Sequence.Variables>

     <Pick sap2010:WorkflowViewState.IdRef="Pick_1">

       <PickBranch DisplayName="Branch1" sap2010:WorkflowViewState.IdRef="PickBranch_1">

         <PickBranch.Trigger>

           <p:Receive CanCreateInstance="True" sap2010:WorkflowViewState.IdRef="Receive_2" OperationName="ReceiveOrder" />

         </PickBranch.Trigger>

         <Sequence sap2010:WorkflowViewState.IdRef="Sequence_2">

           <Assign sap2010:WorkflowViewState.IdRef="Assign_1">

             <Assign.To>

               <OutArgument x:TypeArguments="x:Int32">

                 <mca:CSharpReference x:TypeArguments="x:Int32">TicketId</mca:CSharpReference>

               </OutArgument>

             </Assign.To>

             <Assign.Value>

               <InArgument x:TypeArguments="x:Int32">

                 <mca:CSharpValue x:TypeArguments="x:Int32">new Random().Next()</mca:CSharpValue>

               </InArgument>

             </Assign.Value>

           </Assign>

           <p:InitializeCorrelation sap2010:WorkflowViewState.IdRef="InitializeCorrelation_1">

             <p:InitializeCorrelation.Correlation>

               <InArgument x:TypeArguments="p:CorrelationHandle">

                 <mca:CSharpValue x:TypeArguments="p:CorrelationHandle">_handler</mca:CSharpValue>

               </InArgument>

             </p:InitializeCorrelation.Correlation>

             <InArgument x:TypeArguments="x:String" x:Key="Id">

               <mca:CSharpValue x:TypeArguments="x:String">TicketId.ToString()</mca:CSharpValue>

             </InArgument>

           </p:InitializeCorrelation>

           <WriteLine sap2010:WorkflowViewState.IdRef="WriteLine_1">

             <InArgument x:TypeArguments="x:String">

               <mca:CSharpValue x:TypeArguments="x:String">"流程被创建,编号为:" + TicketId.ToString()</mca:CSharpValue>

             </InArgument>

           </WriteLine>

         </Sequence>

       </PickBranch>

     </Pick>

     <Pick sap2010:WorkflowViewState.IdRef="Pick_2">

       <PickBranch DisplayName="Branch1" sap2010:WorkflowViewState.IdRef="PickBranch_2">

         <PickBranch.Trigger>

           <p:Receive sap2010:WorkflowViewState.IdRef="Receive_3" OperationName="CheckCredit" ServiceContractName="ICheckCredit">

             <p:Receive.CorrelatesOn>

               <p:XPathMessageQuery x:Key="Id">

                 <p:XPathMessageQuery.Namespaces>

                   <ssx:XPathMessageContextMarkup>

                     <x:String x:Key="xgSc">http://tempuri.org/</x:String>

                   </ssx:XPathMessageContextMarkup>

                 </p:XPathMessageQuery.Namespaces>sm:body()/xgSc:CheckCredit/xgSc:id</p:XPathMessageQuery>

             </p:Receive.CorrelatesOn>

             <p:Receive.CorrelatesWith>

               <InArgument x:TypeArguments="p:CorrelationHandle">

                 <mca:CSharpValue x:TypeArguments="p:CorrelationHandle">_handler</mca:CSharpValue>

               </InArgument>

             </p:Receive.CorrelatesWith>

             <p:ReceiveParametersContent>

               <OutArgument x:TypeArguments="x:String" x:Key="action">

                 <mca:CSharpReference x:TypeArguments="x:String">action</mca:CSharpReference>

               </OutArgument>

               <OutArgument x:TypeArguments="x:String" x:Key="comment">

                 <mca:CSharpReference x:TypeArguments="x:String">comment</mca:CSharpReference>

               </OutArgument>

               <OutArgument x:TypeArguments="x:Int32" x:Key="id">

                 <mca:CSharpReference x:TypeArguments="x:Int32">reviewId</mca:CSharpReference>

               </OutArgument>

             </p:ReceiveParametersContent>

           </p:Receive>

         </PickBranch.Trigger>

         <If sap2010:WorkflowViewState.IdRef="If_1">

           <If.Condition>

             <InArgument x:TypeArguments="x:Boolean">

               <mca:CSharpValue x:TypeArguments="x:Boolean">action.ToUpper() == "APPROVAL"</mca:CSharpValue>

             </InArgument>

           </If.Condition>

           <If.Then>

             <WriteLine sap2010:WorkflowViewState.IdRef="WriteLine_2">

               <InArgument x:TypeArguments="x:String">

                 <mca:CSharpValue x:TypeArguments="x:String">"流程" + TicketId.ToString() + "通过审核"</mca:CSharpValue>

               </InArgument>

             </WriteLine>

           </If.Then>

           <If.Else>

             <WriteLine sap2010:WorkflowViewState.IdRef="WriteLine_3">

               <InArgument x:TypeArguments="x:String">

                 <mca:CSharpValue x:TypeArguments="x:String">"流程" + TicketId.ToString() + "被驳回"</mca:CSharpValue>

               </InArgument>

             </WriteLine>

           </If.Else>

         </If>

       </PickBranch>

     </Pick>

     <sads:DebugSymbol.Symbol>d2BFOlxLZXZpbl9Eb2N1bWVudFx3b3Jrc3BhY2VcRGF0YUV4Y2hhbmdlU29sdXRpb25cRGF0YUV4Y2hhbmdlV29ya2Zsb3dzXERhdGFFeGNoYW5nZUFjdGl2aXR5LnhhbWwbLwOOAQ4CAQEyMzI3AgECNAVXDAIBM1gFjAEMAgEDNQdWFAIBNFkHiwEUAgEENws3egIBVzkJVRQCATVbC3QXAgEadgmKAQ4CAQU6C0UUAgFKRgtPJQIBPVALVBcCATZmEWZiAgEtaxFrXQIBJ3ERcV4CASFuEW5eAgEbeQ95bAIBBn0NgQEZAgEThAENiAEZAgEMQhFCYQIBUT0RPV4CAUtND01gAgFESRFJYgIBPlIPUm8CATd/EX9yAgEUhgERhgFxAgEN</sads:DebugSymbol.Symbol>

   </Sequence>

   <sap2010:WorkflowViewState.ViewStateManager>

     <sap2010:ViewStateManager>

       <sap2010:ViewStateData Id="Receive_2" sap:VirtualizedContainerService.HintSize="255,90" />

       <sap2010:ViewStateData Id="Assign_1" sap:VirtualizedContainerService.HintSize="242,62" />

       <sap2010:ViewStateData Id="InitializeCorrelation_1" sap:VirtualizedContainerService.HintSize="242,97" />

       <sap2010:ViewStateData Id="WriteLine_1" sap:VirtualizedContainerService.HintSize="242,62" />

       <sap2010:ViewStateData Id="Sequence_2" sap:VirtualizedContainerService.HintSize="264,425">

         <sap:WorkflowViewStateService.ViewState>

           <scg:Dictionary x:TypeArguments="x:String, x:Object">

             <x:Boolean x:Key="IsExpanded">True</x:Boolean>

           </scg:Dictionary>

         </sap:WorkflowViewStateService.ViewState>

       </sap2010:ViewStateData>

       <sap2010:ViewStateData Id="PickBranch_1" sap:VirtualizedContainerService.HintSize="294,713" />

       <sap2010:ViewStateData Id="Pick_1" sap:VirtualizedContainerService.HintSize="608,759" />

       <sap2010:ViewStateData Id="Receive_3" sap:VirtualizedContainerService.HintSize="255,90" />

       <sap2010:ViewStateData Id="WriteLine_2" sap:VirtualizedContainerService.HintSize="211,62" />

       <sap2010:ViewStateData Id="WriteLine_3" sap:VirtualizedContainerService.HintSize="211,62" />

       <sap2010:ViewStateData Id="If_1" sap:VirtualizedContainerService.HintSize="464,212" />

       <sap2010:ViewStateData Id="PickBranch_2" sap:VirtualizedContainerService.HintSize="494,500" />

       <sap2010:ViewStateData Id="Pick_2" sap:VirtualizedContainerService.HintSize="608,546" />

       <sap2010:ViewStateData Id="Sequence_1" sap:VirtualizedContainerService.HintSize="630,1469">

         <sap:WorkflowViewStateService.ViewState>

           <scg:Dictionary x:TypeArguments="x:String, x:Object">

             <x:Boolean x:Key="IsExpanded">True</x:Boolean>

           </scg:Dictionary>

         </sap:WorkflowViewStateService.ViewState>

       </sap2010:ViewStateData>

       <sap2010:ViewStateData Id="DataExchangeWorkflows.DataExchangeActivity_1" sap:VirtualizedContainerService.HintSize="670,1549" />

     </sap2010:ViewStateManager>

   </sap2010:WorkflowViewState.ViewStateManager>

 </Activity>

3. Host项目引入System.Activities, System.ServiceModel.Activities和System.ServiceModel。如下图所示:

4. 修改Host项目的program.cs如下:

         static void Main(string[] args)

         {

             var host = new WorkflowServiceHost(

                 new DataExchangeActivity(),

                 new Uri("http://localhost:8080/WS"));

             host.AddDefaultEndpoints();

             host.Description.Behaviors.Add(

                 new ServiceMetadataBehavior() { HttpGetEnabled = true });

             host.AddServiceEndpoint(

                 "IMetadataExchange",

                 MetadataExchangeBindings.CreateMexHttpBinding(),

                 "mex");

             host.Open();

             Console.WriteLine("Server is ready.");

             Console.Read();

         }

5. 编译Host,然后以Administrator身份运行host.exe,这时会启动WCF,终端窗口显示如下:

6. 这时打开浏览器,浏览http://localhost:8080/ws,会显示如下页面:

7. 打开VS Command Prompt(VS命令行终端),运行svcutil.exe http://localhost:8080/ws?wsdl。结果如下图。这时会生成两个文件,DataExchangeActivity.cs和output.config。将这两个文件copy到client项目中,output.config改名为app.config。

8. 修改Client的Form1,界面如下:

9. 代码如下(很简单就不解释了):

         private void button1_Click(object sender, EventArgs e)

         {

             var proxy = new DataExchangeActivityClient();

             proxy.ReceiveOrder();

         }

         private void button2_Click(object sender, EventArgs e)

         {

             var proxy = new CheckCreditClient();

             proxy.CheckCredit(textAction.Text.Trim(), "", int.Parse(textId.Text));

         }

10. 运行Client后,启动流程并且输入对应工作流的审批意见后,结果如下:

源代码下载

Workflow:实现一个简单的审批流程的更多相关文章

  1. Springboot 整合Activiti流程设计器 完成一个简单的请假流程

    目录 1.前言 2.准备 3.下载解压 4.开始整合 mysql + activiti + thymeleaf 2.配置文件 3.复制文件 4.加入控制器 5.修改配置文件 6.剔除启动类里面的安全校 ...

  2. 【Star CCM+实例】开发一个简单的计算流程.md

    流程开发在CAE过程中处于非常重要的地位. 主要的作用可能包括: 将一些经过验证的模型隐藏在流程中,提高仿真的可靠性 将流程封装成更友好的界面,降低软件的学习周期 流程开发实际上需要做非常多的工作,尤 ...

  3. 一个简单CI/CD流程的思考

    因为公司有两地研发团队,在统一CI/CD上难度不亚于两家公司合并后的新流程建立,并非不可攻克,简单描述下心得. 首先,代码管理使用gerrit -> 因其强大的 codereview 功能被选中 ...

  4. 一个基于activiti审批流程示例,如何与系统整合

    前言 目前市场上有很多开源平台没有整合工作流,即使有,也是价格不菲的商业版,来看这篇文章的估计也了解了行情,肯定不便宜.我这个快速开发平台在系统基础功能(用户管理,部门管理-)上整合了工作流,你可以直 ...

  5. 基于SpringCloud的微服务架构实战案例项目,以一个简单的购物流程为示例

    QuickStart 基于SpringCloud体系实现,简单购物流程实现,满足基本功能:注册.登录.商品列表展示.商品详情展示.订单创建.详情查看.订单支付.库存更新等等. 每个业务服务采用独立的M ...

  6. uiautomator 一个简单脚本创建流程

    http://www.codeceo.com/article/android-ui-auto-test.html

  7. 我的第一个activiti实例 (代码方式) ctiviti入门列子一个简单的activiti请假流程

    转: (activiti入门列子一个简单的activiti请假流程) 我的第一个activiti实例 2017年05月31日 14:29:45 chf_mixueer 阅读数:1223   整个项目的 ...

  8. Python的网络编程[5] -> BOOTP + TFTP + FTP -> 实现一个简单的文件传输流程

    BOOTP-TFTP-FTP 目录 文件传输流程 服务器建立过程 客户端建立过程 1 文件传输流程 / File Transfer Flow 利用BOOTP,TFTP,FTP三种传输协议,建立起客户端 ...

  9. 一个简单的Eclipse调试Debug流程(四)

    本文链接:https://blog.csdn.net/u011781521/article/details/55000066    http://blog.csdn.net/u010075335/ar ...

随机推荐

  1. Treap(模板)

    人生第一次平衡树,Treap板子 #include<iostream> #include<cstdio> #include<cstring> #include< ...

  2. IT架构师介绍-软件架构设计学习第一天(非原创)

    文章大纲 一.架构师定义二.架构师分类与具备能力三.研发人员发展的技术路线四.架构师知识体系五.参考文章   一.架构师定义   什么是架构师,这个聊架构话题时永恒的问题.每个公司对架构师的定位也有所 ...

  3. vagrant使用centos的环境安装..

    vagrant这货挺好用的..简要就是, 下好virtualbox, vagrant, 然后下个你需要的box. 然后vagrant box add boxname boxpath就行. 然后在合适的 ...

  4. 使用UDEV SCSI规则在Oracle Linux上配置ASM

    对于使用ASM管理的磁盘来说,需要一种能够用于一致性标识磁盘设备及其正确的所属关系和权限的手段.在Linux系统中,可以使用ASMLib来执行这项任务,但是这样做的缺点是在操作系统上增加了额外的一层, ...

  5. B-Tree 漫谈 (从二叉树到二叉搜索树到平衡树到红黑树到B树到B+树到B*树)

    关于B树的学习还是需要做点笔记. B树是为磁盘或者其他直接存取辅助存储设备而设计的一种平衡查找树.B树与红黑树的不同在于,B树可以有很多子女,从几个到几千个.比如一个分支因子为1001,高度为2的B树 ...

  6. CF832B Petya and Exam

    思路: 模拟. 实现: #include <iostream> using namespace std; string a, b; ]; bool solve() { ) return f ...

  7. Raspberry Pi开发之旅-光照强度检测(BH1750)

    一.前期准备 1.环境要求 GY30模块(BH1750FVI传感器),树莓派系统,python-smbus,iic开启 2.取消对IIC驱动的黑名单 nano /etc/modprobe.d/rasp ...

  8. JS高级——变量提升

    JS执行过程 1.首先是预解析:预解析过程最重要的是提升,在JavaScript代码在预解析阶段,会对以var声明的变量名,和function开头的语句块,进行提升操作 2.执行操作 全局中解析和执行 ...

  9. JS——冒泡排序

    核心思想: 1.外层for循环控制比较的轮数 2.内层for循环控制每轮比较的次数 3.外层每进行一轮比较,内层就少一次比较,因为外层每进行一轮比较都会产生一个最大值 <script> v ...

  10. PHP 之微信小程序支付封装

    <?php /** * Created by PhpStorm. * User: yangs * Date: 2019/4/26 * Time: 14:28 */ class WeixinPay ...