转:工作流服务Workflow Service(1):ReceiveActivity

转:http://www.cnblogs.com/carysun/archive/2009/01/11/receiveactivity.html

在.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属性,该属性来实现的协定和服务操作,如下图:

WFService1

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();}}
}

2.结果如下:

WFService2

手动宿主工作流服务

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 组中的用户调用此操作。具体如下图所示:

WFService3

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 声明检查调用方名称,以便验证发送第一个消息(导致实例创建)和发送后续消息的是否是同一个人。

可以使用上面的方面来宿主并进行相关测试。

作者:生鱼片
    
出处:http://carysun.cnblogs.com/
    
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载于:https://www.cnblogs.com/ookami/p/3969899.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/290717.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Echart..js插件渲染报错 data.length1?

问题 getJSON提交 返回数据正常&#xff0c;在传入参数进行序列化&#xff0c;渲染报表时报错 option.data.length < 1. 分析 1.可能情况一: . 可自己明明是getJSON()把渲染放在成功回调函数里面了&#xff0c;所以显然不是这个错误 2.可能情况二 &#xff1a; 序列化数据没…

《JavaScript专家编程》——第1章 对象和原型 1.1鸟瞰JavaScript

本节书摘来自异步社区《JavaScript专家编程》一书中的第1章&#xff0c;第1.1节&#xff0c;作者&#xff1a;【美】Mark Daggett&#xff08;达格特&#xff09;著&#xff0c;更多章节内容可以访问云栖社区“异步社区”公众号查看 第1章 对象和原型 练习不会造就完美&#xf…

c#使用PdfiumViewer展示、打印pdf文档

1:简介PdfiumViewer 是一个 WinForms 控件&#xff0c;它承载一个 PdfRenderer 控件并添加一个工具栏来保存或打印 PDF 文件2:兼容性除了常规的win7 win10 也支持xp win83:对比Spire.Pdf和Adobe PDF ReaderSpire.Pdf收费且免费版只能打印三页的pdfAdobe PDF Reader每台电脑都必…

apache 静态编译和动态编译参考

apache-2.2.22 编译安装笔记 一、静态编译 在使用./configure 编译的时候&#xff0c;即没有使用--enable-mods-shared[module]或者--enable-[module]shared这2个中的一个&#xff0c;那么所有的默认模块为静态。何谓静态&#xff1f; 其实就是编译的时候所有的模块自己编译进h…

jQuery插件ASP.NET应用之AjaxUpload

本次使用AJAXUPLOAD做为上传客户端无刷上传插件&#xff0c;其最新版本为3.9&#xff0c;官方地址&#xff1a;http://valums.com/ajax-upload/ 在页面中引入 jquery.min.1.4.2.js 和 ajaxupload.js Html代码 <script src"Scripts/jquery-1.4.2.min.js" type&quo…

Avalonia跨平台入门第十一篇之自定义Window

在前面分享的几篇中咱已经玩耍了Popup、ListBox多选、Grid动态分、RadioButton模板、控件的拖放效果、控件的置顶和置底、控件的锁定;今天趁着周末接着去摸索自定义Window样式,毕竟自带的样式不太让人满意;最终实现的效果如下图:前台Window样式:后台Window代码:咱也基于AvalonS…

ie8下修改input的type属性报错

摘要&#xff1a; 现在有一个需求如图所示&#xff0c;当用户勾选显示明文复选框时&#xff0c;要以明文显示用户输入的密码&#xff0c;去掉勾选时要变回密文&#xff0c;刚开始想到的就是修改输入框的type来决定显示明文还是密文&#xff0c;使用jQuery的attr来做试验&#x…

dotNet Core使用SignalR实现websocket

前言:最近有一个公司项目做一个排队叫号系统&#xff0c;系统功能不复杂&#xff0c;所以后端就我一人&#xff0c;难点在于消息推送到安卓屏上&#xff0c;最近有点时间&#xff0c;把我工作中使用的技术分享出来&#xff01;整个技术架构:前端使用vue uniapp&#xff0c;后端…

《手机测试Robotium实战教程》——导读

本节书摘来自异步社区《手机测试Robotium实战教程》一书中的导读&#xff0c;作者 杨志伟&#xff0c;更多章节内容可以访问云栖社区“异步社区”公众号查看 目 录前 言第1章 自动化测试简介 1.1节何为自动化测试1.2节自动化测试和手动测试的对比1.3节移动端自动化测试工具的选…

为record类型自定义Equals方法

前言record类型&#xff0c;这是一种新引用类型&#xff0c;而不是类或结构。record与类不同&#xff0c;区别在于record类型使用基于值的相等性。例如&#xff1a;public record DemoRecord(int id);public class DemoClass {public DemoClass(int id){this.id id;}public in…

解决IDEA修改已有项目为maven项目时目录结构被改变的问题

Idea可以在项目根目录上右键选择“添加框架支持”&#xff0c;选择maven&#xff0c;为项目添加Maven支持。 但这样会导致原有项目的目录结构被破坏。 更好的方法是在根目录添加pom.xml文件 在<build>标签内添加 <sourceDirectory>标签&#xff0c;并填入源码根目…

排序——选择排序

选择排序 作者&#xff1a;上品物语 知识点&#xff1a; 原理示意图算法特点复杂度1.1 原理 首先&#xff0c;找到数组中最小的那个元素&#xff0c;其次&#xff0c;将它和数组的第一个元素交换位置&#xff08;如果第一个元素就是最小元素&#xff0c;那么它就和自己交换&…

.Net/C#分库分表高性能O(1)瀑布流分页

框架介绍依照惯例首先介绍本期主角:ShardingCore 一款ef-core下高性能、轻量级针对分表分库读写分离的解决方案&#xff0c;具有零依赖、零学习成本、零业务代码入侵dotnet下唯一一款全自动分表,多字段分表框架,拥有高性能,零依赖、零学习成本、零业务代码入侵,并且支持读写分离…

centos静默安装oracle关于报错UnsatisfiedLinkError exception loading native library:njni10

静默安装oracle时&#xff0c;日志文件中打印出如下语句 提示Oracle NetConfiguration Assistant failed&#xff0c;原因是找不到libaio.so.1 这是缺少依赖 执行指令 yum -y install libaio* libaio-devel* 删除home文件夹&#xff0c;再次执行 ./runInstaller -silent…

Ant—使用Ant构建一个简单的Java工程(两)

博客《Ant—使用Ant构建一个简单的Java项目&#xff08;一&#xff09;》演示了使用Ant工具构建简单的Java项目&#xff0c;接着这个样例来进一步学习Ant&#xff1a;上面样例须要运行多条ant命令才干运行Test类中的main函数&#xff0c;能不能简化须要运行命令呢&#xff1f;答…

Java Thread Status(转)

public static enum Thread.State extends Enum<Thread.State>线程状态。线程可以处于下列状态之一&#xff1a; 1.NEW 至今尚未启动的线程的状态。 2.RUNNABLE 可运行线程的线程状态。 处于可运行状态的某一线程正在 Java 虚拟机中运行&#xff0c;但它可能正在…

秀!微软《550页图解.Net+WPF完整版》.pdf 附下载!

赶紧看看微软公司基于最新的.netwpf编写文档。对于零基础可以作为.net的快速入门教材&#xff0c;对于高级程序员而言&#xff0c;这也是你的充电之路&#xff01;NO.1资料介绍该手册,全面的介绍.net的新特性&#xff0c;看完这个资料&#xff0c;你能够对.net/c#WPF的新功能&a…

《移动App测试的22条军规》—第1章1.2节移动App的生命周期

本节书摘来自异步社区《移动App测试的22条军规》一书中的第1章&#xff0c;第1.2节移动App的生命周期&#xff0c;作者黄勇&#xff0c;更多章节内容可以访问云栖社区“异步社区”公众号查看。 1.2 移动App的生命周期移动App测试的22条军规&#xff08;1&#xff09;对于还处于…

电子商务应用课程知识整理 第一章-电子商务概述与类型

一、电子商务定义 电子商务&#xff08;Electronic Commerce&#xff0c;简称EC&#xff09;&#xff0c;是指在全球各地广泛的商业贸易活动中&#xff0c;在因特网开放的网络环境下&#xff0c;基于客户端&#xff08;浏览器、移动端&#xff09;/服务器&#xff0c;买卖双方…

电子商务应用课程知识整理 第二章-电子商务相关知识与技术

一、万维网 万维网&#xff08;亦作“网络”、www、Web或World Wide Web&#xff09;&#xff0c;是一个资源空间。在这个空间中包含一些有用的事务&#xff0c;有一个”统一资源标识符“&#xff08;URL&#xff09;表示。这些资源通过超文本传输协议&#xff08;HTTP&#x…