在.NET3.5中WF提供了和WCF的整合,就是工作流服务,即使用工作流创作的 WCF服务。服务协定的实现是通过一个或多个 ReceiveActivity 活动处理的。
在WCF中提供了三种消息交换模式分别为One-Way Calls,Request/Response和Duplex,在工作流服务中只支持One-Way Calls和Request/Response两种模式。
下面就举例说明,新建一个顺序工作流库CaryWFLib项目
1.先定义服务契约接口,我们建立的是一个无状态的工作流服务,所以要设置如下SessionMode = SessionMode.NotAllowed
namespace CaryWFLib { [ServiceContract(Namespace = "http://CaryWF", SessionMode = SessionMode.NotAllowed)] public interface IAddService { [OperationContract] Double Add(Double num1, Double num2); } }
2.在工作流设计器中拖入ReceiveActivity,设置ServiceOperationInfo属性,该属性来实现的协定和服务操作,如下图:
3.设置该活动的CanCreateInstance属性为true,当服务客户端调用时,服务将创建工作流的新实例。 如果设置为 false,客户端无法使用服务操作调用来创
建工作流的新实例,只能使用关联的 WorkflowRuntime 对象的 CreateWorkflow 方法可以创建。
在IIS中宿主工作流服务
主要通过以下步骤:
1.创建AddServiceWorkflow.svc放到IIS虚拟目录中,代码如下:
<%@ServiceHost language=c# Debug="true" Service="CaryWFLib.AddWorkflow" Factory="System.ServiceModel.Activation.WorkflowServiceHostFactory" %>
2.增加web.config文件,在web.config中我加载了持久化服务,当然我已经建立好了持久化数据库,代码如下:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name="CaryWFLib.AddWorkflow" behaviorConfiguration="ServiceBehavior"> <endpoint address="" binding="wsHttpContextBinding" contract="CaryWFLib.IAddService"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="ServiceBehavior"> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="true"/> <workflowRuntime name="WorkflowServiceHostRuntime" validateOnCreate="true" enablePerformanceCounters="true"> <services> <add type= "System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService, System.Workflow.Runtime,Version=3.0.00000.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35" connectionString="Initial Catalog=WorkflowPersistence; Data Source=localhost\SQLEXPRESS; Integrated Security=SSPI; Trusted_Connection=True;" LoadIntervalSeconds="1" UnLoadOnIdle="true" /> </services> </workflowRuntime> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> <system.web> <compilation> <assemblies> <add assembly="System.WorkflowServices,Version=3.5.0.0, Culture=neutral,PublicKey Token=31bf3856ad364e35"/> </assemblies> </compilation> </system.web> </configuration>
3.将编译后生成的CaryWFLib.dll放到IIS的虚拟目录的bin目录下
4.然后你就可以在浏览器中输入http://localhost/CaryWFWCF/AddServiceWorkflow.svc来测试是否部署成功了。
5.有几点要注意的:
5.1.在使用iis承载wcf时,如果遇到无法访问iis元数据的权限的错误,可以使用如下命令
aspnet_regiis –ga <WindowsUserAccount>来给制定用户权限。
5.2.无法打开登录所请求的数据库 "WorkflowPersistence"。登录失败。用户 XXXX\ASPNET' 登录失败。
这个时候需要给aspnet用户访问持久化数据库的权限,可以将aspnet用户添加到state_persistence_users角色中,该角色是随着持久化数据库创建
而产生的。我使用的是express版,我的方法是利用sql server 2005外围应用配置器的添加新管理员,将aspnet账户添加为管理员。
5.3.如果在安装 WCF之后安装了 IIS,必须运行以下命令:
"%WINDIR%\Microsoft.Net\Framework\v3.0\Windows Communication Foundation\ServiceModelReg.exe" -r
这将在 IIS 中注册所需的脚本映射。 还必须确保将 .svc 文件类型映射到 aspnet_isapi.dll。
创建客户端测试
1.在你的项目中添加服务引用,添加完成后,项目中会自动添加System.ServiceModel和System.Runtime.Serialization引用,和App.config配置文件。
测试代码如下:
namespace AddServiceConsole { class Program { static void Main(string[] args) { try { AddServiceClient client = new AddServiceClient(); Console.WriteLine("Server endpoint: {0}", client.Endpoint.Address.ToString()); Double result = client.Add(1, 2); Console.WriteLine("1加2的结果为:{0}", result); client.Close(); } catch (Exception exception) { Console.WriteLine("未处理的异常: {0} - {1}", exception.GetType().Name, exception.Message); } Console.WriteLine("Press any key to exit"); Console.ReadKey(); } } }
手动宿主工作流服务
1.代码如下:
WorkflowServiceHost serviceHost = null; try { serviceHost = new WorkflowServiceHost(typeof(CaryWFLib.AddWorkflow));
serviceHost.Description.Behaviors.Find<WorkflowRuntimeBehavior>().WorkflowRuntime.WorkflowCompleted
+= delegate(object sender, WorkflowCompletedEventArgs e) { Console.WriteLine("WorkflowCompleted: " + e.WorkflowInstance.InstanceId.ToString()); };
serviceHost.Open(); if (serviceHost.Description.Endpoints.Count > 0) { Console.WriteLine("Contract: {0}",serviceHost.Description.Endpoints[0].Contract.ContractType); Console.WriteLine("Endpoint: {0}",serviceHost.Description.Endpoints[0].Address); } Console.WriteLine("Press any key to exit"); Console.ReadKey(); } catch (Exception exception) { Console.WriteLine("Exception hosting service: {0}",exception.Message); } finally { try { if (serviceHost != null) { serviceHost.Close(new TimeSpan(0, 0, 10)); } } catch (CommunicationObjectFaultedException exception) { Console.WriteLine("CommunicationObjectFaultedException on close: {0}",exception.Message); } catch (TimeoutException exception) { Console.WriteLine("TimeoutException on close: {0}",exception.Message); } }
2.手动宿主要使用WorkflowServiceHost类为基于工作流的服务提供主机。使用 WorkflowServiceHost 对象可加载工作流服务、配置终结点、应用
安全设置并启动侦听器来处理传入的请求。
3.可以通过如下代码来得到WorkflowRuntime:
serviceHost.Description.Behaviors.Find<WorkflowRuntimeBehavior>().WorkflowRuntime
4.然后要配置app.config文件,如下:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name="CaryWFLib.AddWorkflow" behaviorConfiguration="ServiceBehavior" > <host> <baseAddresses> <add baseAddress= http://localhost:8802/CaryWFWCF/AddServiceWorkflow.svc /> </baseAddresses> </host> <endpoint address="" binding="basicHttpBinding" contract="CaryWFLib.IAddService" /> </service> </services> <behaviors> <serviceBehaviors> <behavior name="ServiceBehavior" > <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> <workflowRuntime name="WorkflowServiceHostRuntime" validateOnCreate="true" enablePerformanceCounters="true"> <services> <add type= "System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionString="Initial Catalog=WorkflowPersistence; Data Source=localhost\SQLEXPRESS;Integrated Security=SSPI;" LoadIntervalSeconds="1" UnLoadOnIdle= "true" /> </services> </workflowRuntime> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
运行自己host的程序后,就可以使用前面的测试程序来再次测试,测试得到的结果是一样。
工作流服务创作样式
协定优先
协定优先的工作流服务是一种使用预先存在的服务协定信息的工作流。 我们上面的例子使用的都是这种方式,他的服务契约部分和WCF是一样的方式。
工作流优先
WF还支持另一种叫做工作流优先的模型,在ReceiveActivity的ServiceOperationInfo属性对话框中可以直接添加约定就是这种方式。在自动生成的代码中
是使用 ContractName 属性定义的,而操作名称是使用 Name 参数设置的。 操作的参数(包括返回值)是使用 OperationParameterInfo 类并将每个参数
添加到 OperationInfo 对象的参数集合中。下面的例子我就将使用这种方式。
工作流服务中的安全性
工作流服务为服务提供两个级别的安全性。 在第一个级别中,您可对操作指定原则权限安全性。 服务运行时会在将消息传递到工作流之前检查权限。 如果消息不满足原则权限安全性,则不会将消息发送到工作流。 第二个级别是“操作验证条件”,OperationValidation事件在ReceiveActivity活动即将收到消息时激发。可以使用关联的处理程序来执行基于 ClaimSet 的安全检查,以对由 ReceiveActivity活动实现的服务操作的客户端调用进行授权,如果OperationValidationEventArgs.IsValid设置为 false 会拒绝服务操作调用,并且客户会收到 FaultException。如果将 OperationValidationEventArgs.IsValid设置为 true,则服务操作调用将成功完成,并且 ReceiveActivity活动将接收并处理消息。下面我就举例说明:
1.我们新建一个WFFirstWorkflow并实现同样的加法运算的功能,这次我们使用的是工作流优先的创作样式,并指定只允许 Administrators 组中的用户调用此操作。具体如下图所示:
ReceiveActivity的OperationValidation事件的代码如下:
public string owner;
private void AddValidate(object sender, OperationValidationEventArgs e) { if (string.IsNullOrEmpty(owner)) { owner = ExtractCallerName(e.ClaimSets); e.IsValid = true; Console.WriteLine("Owner: " + owner); } if (owner.Equals(ExtractCallerName(e.ClaimSets))) e.IsValid = true; } private string ExtractCallerName(ReadOnlyCollection<ClaimSet> claimSets) { string owner = string.Empty; foreach (ClaimSet claims in claimSets) { foreach (Claim claim in claims) { if (claim.ClaimType.Equals(ClaimTypes.Name) && claim.Right.Equals(Rights.PossessProperty)) { owner = claim.Resource.ToString(); break; } } } return owner; }
2.AddValidate方法的OperationValidationEventArgs
参数的ClaimSets属性中存储ClaimSet对象的集合,这些对象包含已添加到操作的授权上下文的声明。 我们就使用这些声明集来完成消息验证。 注意,此时实际的消息正文参数尚不可用。 ExtractCallerName
方法从 Name 声明中提取调用方名称并将其存储起来。 在后续请求中,将根据传入消息的 Name 声明检查调用方名称,以便验证发送第一个消息(导致实例创建)和发送后续消息的是否是同一个人。
可以使用上面的方面来宿主并进行相关测试。
发表评论
-
平淡的2007
2007-12-24 08:04 786早上起来,送女朋友去公交车站,然后回来赶紧打开电脑,先 ... -
DreamSpark发布,高校学生免费使用Visual Studio 2008 Professional Edition 等微软软件
2008-02-20 13:23 1384今天上网无意中搜索到学生可以免费使用VS2008专业版,后来又 ... -
坚持学习WF(1):从HelloWorld开始
2008-04-04 16:30 851[置顶]坚持学习WF文章索 ... -
坚持学习WF(2):WF创作模式和设计时工具
2008-04-05 17:19 600[置顶]坚持学习WF文章索 ... -
坚持学习WF(3):WF框架概览
2008-04-08 07:27 740[置顶]坚持学习WF文章索 ... -
坚持学习WF(4):活动(Activity)和依赖属性(DependencyProperty)
2008-04-12 00:01 1105[置顶]坚持学习WF文章索引 活动(Activity) 活动 ... -
坚持学习WF(5):自定义活动(CustomActivity)
2008-04-13 15:25 883当WF提供的标准活动不能满足我们的需求的时候,我们就需要定义自 ... -
MOSS点滴(1):如何开发和部署feature
2008-04-16 21:35 808Features 是MOSS 2007以开箱即用的一套新功能, ... -
MOSS点滴(2):自定义Application Page
2008-04-19 20:07 810在MOSS中后台管理的页面都是Application Pag ... -
坚持学习WF(6):开发可复用的宿主程序
2008-04-21 21:45 664我们之前写工作流宿主 ... -
MOSS点滴(3):说说MOSS中的母版页
2008-04-25 21:15 1139MOSS中有两种页面:Site P ... -
MOSS点滴(4):实现Form认证
2008-04-29 21:12 671本文主要参考了网上的一些文章,但有些文章有些地方说的不是很明确 ... -
坚持学习WF(7):流程控制(Flow Control)
2008-04-30 18:10 776本文主要说说WF中和流 ... -
坚持学习WF(8):本地服务之调用外部方法
2008-05-09 08:17 722WF提供了一组核心服务 ... -
MOSS中的WebPart开发
2008-05-10 13:53 1025由于在asp.net1.1的时候asp.net中还没有webp ... -
坚持学习WF(9):本地服务之事件处理
2008-05-28 07:49 766[置顶]坚持学习WF文章索引 一:先来介绍两个活动 Even ... -
坚持学习WF(10):在工作流中使用关联
2008-06-01 13:03 660[置顶]坚持学习WF文章索 ... -
坚持学习WF(11):工作流通信与队列
2008-06-07 15:45 698[置顶]坚持学习WF文章索引 WF 提供的通信模型是构建于 ... -
MOSS中创建自定义内容类型
2008-06-12 20:23 1072一:简要介绍 某类内容 ... -
.NET中IDisposable接口的基本使用
2008-06-15 12:01 911首先来看MSDN中关于这个接口的说明: [ComVisible ...
相关推荐
泛微工作流(WorkflowService)WebService接口使用说明
泛微非常细的webservice接口开发说明,应用于泛微E8,E9版本,Ecology8、Ecology9的webservice开发文档
工作流(workflow)入门实例 工作流(workflow)入门实例 工作流(workflow)入门实例
Microsoft Windows Workflow Foundation 入门:开发人员演练
workflow 工作流 实例 有流程图
最近公司用的workflow 里面有一些说明性的文档供参考,仅仅用于学习和交流!
微软工作流Demo,workflow,微软工作流Demo,workflow,微软工作流Demo,workflow
《疯狂Workflow讲义:基于Activiti的工作流应用开发》内容概括: 本书是一本介绍Java工作流领域的书,以Activiti为核心,内容囊括了多个流行的企业级Java EE框架,全书主要可分为以下几个部分。 第1部分:对...
该当请求或完成工作流运行发生的事件,并允许您根据另一个工作流的最终结果执行工作流。 例子 on : workflow_run : workflows : [ test ] types : - completed 但是,就其本身而言,这并不完全符合预期。 ...
workflow node flow instance 工作流-workflow
Vue-Workflow-Chart开发用于可视化流程或工作流。 例如,在一家公司中,工作流程会变得非常复杂和混乱,因此插图可以帮助您理解流程。 由于工作流由状态和过渡组成,因此必须将这些元素传递到vue-workflow-chart。...
现代工作流(workflow)实例介绍,现代工作流(workflow)实例介绍,例子详细易懂
WinFrom的Workflow工作流的Hello World简单实例
工作流(workflow)请假流程实例,包括请假开启流程,签收工单,结束工单等等
工作流(workflow)两个基本jar包,以及eclipse插件包和myeclipse插件包
Windows Workflow Foundation(以下简称WWF)提供了一个编程框架和工具以开发和执行各种不同的基于工作流的应用程序,比如文档管理、线型的商业应用、贸易单据流程、IT管理、B2B应用以及消费者应用。 有状态的、...
svg-workflow画布使用基于SVG的画布对组件进行响应以进行工作流构建安装yarn add svg-workflow-canvas用法有关如何使用此组件的信息,请参见示例文件夹。 下面只是一个非常简单的示例。 import React from "react" ;...
WorkFlow C++ 工作流 图形,源代码提供了C++的图形库
工作流程核心 Workflow Core是面向.NET Standard的轻量级可嵌入工作流引擎。 想一想:长时间运行的流程需要执行多个任务以跟踪状态。 它支持可插拔的持久性和并发提供程序,以支持多节点群集。公告内容新的相关项目...
关工作流(Workflow)的基本概念、原理与方