博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WF与WebService
阅读量:6423 次
发布时间:2019-06-23

本文共 6538 字,大约阅读时间需要 21 分钟。

WF与WebService交互

WF中提供了WebServiceInputActivity,WebServiceOutputActivity,InvokeWebServiceActivity,WebServiceFaultActivity四个活动来完成与Webservice

的交互,下面简要介绍下这四个活动:

1.WebServiceInputActivity活动:使工作流能够从 Web 服务接收数据。 在启动 Web 服务时将自身作为 Web 服务方法发布,然后在随后调用 Web 服务

方法时接收数据。
2.WebServiceOutputActivity活动:用于响应对工作流所做的 Web 服务请求,该活动必须与WebServiceInputActivity 活动关联。
3.WebServiceFaultActivity活动:为所出现的 Web 服务错误建立模型。
4.InvokeWebServiceActivity活动:通过代理类调用 Web 服务,并传递和接收指定的参数。

应用举例

1.下面我们举例说明,由于WebServiceInputActivity活动所接收的方法必须定义在接口中,所以我们先建立一个接口IAddService ,代码如下:

namespace CaryWFLib{    interface IAddService    {        double Add(double number1, double number2);    }}

2.工作流设计器如下图:

3.在工作流设计器中我们首先拖入了一个WebServiceInputActivity活动,设置其InterfaceType属性,然后MethodName,然后将IsActivating设为true,

默认为false,当选了MethodName属性后属性窗口会自动多出参数的属性。在CodeActivity活动中完成加法运算逻辑,最后是WebServiceOutputActivity
活动,工作流的代码如下:

public sealed partial class AddWorkflow: SequentialWorkflowActivity{     public double number1;     public double number2;     public double result;
public AddWorkflow()     {        InitializeComponent();     }     private void codeActivity1_ExecuteCode(object sender, EventArgs e)     {         result = number1 + number2;     }        }
4.这个时候你就可以用项目的右键菜单里的"作为Web服务发布"来将工作流发布为WebService,发布完成后会在当前的解决方案里多出一个WebService 的项目,我们就可以运行测试了,如下图:
 
只有工作流库才可以发布为WebService,新生成的WebService项目会包含一个CaryWFLib.AddWorkflow_WebService.asmx文件和一个Web.config 配置文件,web.config文件的内容如下:
web.config中的SqlWorkflowPersistenceService是我们手动添加的,其他的都是自动生成的。
5.我们第一次调用WebService是正常的,如果你再次调用就会出现下错误:
System.InvalidOperationException: 在状态持久性存储中找不到 ID 为“21cf8af3-885d-47dd-acbc-530eeba794ed”的工作流。
这是由于在web.config中使用了WorkflowWebHostingModule,我们第二次调用的时候WebService会去装载之前的工作流实例,而第一次调用完成后该实 例就销毁了,如果你关掉浏览器在打开就又正常了,这是因为新的工作流实例又产生了。
 
WorkflowWebHostingModule

1.WorkflowWebHostingModule类是默认的路由机制,用于通过使用ASP.NET cookie将web服务请求路由到相应的工作流,发出这些请求的客户端要支持

cookie。这个主要目的是为了可以多次的调用一个工作流实例的方法。我们从新设计一个工作流用于解决上面的问题,将原接口扩展一下,代码如下:

namespace CaryWFLib{    interface IAddStatefulService    {        void StartWorkflow();        double Add(double number1, double number2);        void StopWorkflow();    }}

2.工作流设计如下:

我们使用ListenActivity来监听,WebServiceInputActivity1绑定StartWorkflow方法,WebServiceInputActivity2绑定Add方法,WebServiceInputActivity3

绑定StopWorkflow方法,如果调用StopWorkflow方法,我们就在WebServiceInputActivity3的调用完成的事件中将While的条件设为false。我们在web.config
中装载了持久化服务,所以在工作流Idle的时候就进行持久化的存储,当第二次调用的时候会根据cookie中保存的工作流实例id从持久化数据库中装载相同的
工作流实例。

3.如果在其他程序中,比如winform中,我们需要手动装载持久化中的工作流实例,那我们如何知道工作流实例的id呢,我们reflector一下WorkflowWebHostingModule的代码如下:

public sealed class WorkflowWebHostingModule : IHttpModule{    // Fields    private HttpApplication currentApplication;    // Methods    public WorkflowWebHostingModule()    {        WorkflowTrace.Host.TraceEvent(8, 0, "Workflow Web Hosting Module Created");    }    private void OnAcquireRequestState(object sender, EventArgs e)    {        WorkflowTrace.Host.TraceEvent(8, 0, "WebHost Module Routing Begin");        HttpCookie cookie = HttpContext.Current.Request.Cookies.Get("WF_WorkflowInstanceId");        if (cookie != null)        {            HttpContext.Current.Items.Add("__WorkflowInstanceId__", new Guid(cookie.Value));        }    }    private void OnReleaseRequestState(object sender, EventArgs e)    {        if (HttpContext.Current.Request.Cookies.Get("WF_WorkflowInstanceId") == null)        {            HttpCookie cookie = new HttpCookie("WF_WorkflowInstanceId");            object obj2 = HttpContext.Current.Items["__WorkflowInstanceId__"];            if (obj2 != null)            {                cookie.Value = obj2.ToString();                HttpContext.Current.Response.Cookies.Add(cookie);            }        }    }    void IHttpModule.Dispose()    {    }    void IHttpModule.Init(HttpApplication application)    {        WorkflowTrace.Host.TraceEvent(8, 0, "Workflow Web Hosting Module Initialized");        this.currentApplication = application;        application.ReleaseRequestState += new EventHandler(this.OnReleaseRequestState);        application.AcquireRequestState += new EventHandler(this.OnAcquireRequestState);    }}4.从reflector出的源代码我们可以发现,工作流实例的id存储在名称为WF_WorkflowInstanceId的cookie中,Item为__WorkflowInstanceId__。 我们通过如下代码就可以得到工作流实例的id了,如下:
localhost.AddWorkflow_WebService ws = new localhost.AddWorkflow_WebService();ws.CookieContainer = new System.Net.CookieContainer();ws.Url = "http://localhost:6411/CaryWFLib_WebService1/CaryWFLib.AddWorkflow_WebService.asmx";ws.Add(1, 2);Uri uri = new Uri(ws.Url);CookieCollection cc = ws.CookieContainer.GetCookies(uri);foreach (Cookie c in cc){   if (c.Name == "WF_WorkflowInstanceId")   {       this.Label3.Text = c.Value;   }}
5.由于WorkflowWebHostingModule必须要求客户端启用cookie,当不能在客户端中启用 Cookie 时我们可以从新写一个WorkflowWebHostingModule。 6.上面的发布WebService是使用WF本身提供功能,我们完全可以自己来实现,代码如下:
namespace CaryWFLib{    [WebService(Namespace = "http://CaryWFLibWebService.com/")]    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]    public class CaryWFLibWebService:System.Web.Services.WebService    {        private static WorkflowRuntime workflowRuntime = new WorkflowRuntime();        [WebMethod]        public double Add(double number1,double number2)        {            double result=0;            AutoResetEvent waitHandle = new AutoResetEvent(false);            workflowRuntime.WorkflowCompleted +=               delegate(object sender, WorkflowCompletedEventArgs e)               {                   result =Convert.ToDouble( e.OutputParameters["result"]);                   waitHandle.Set();               };            workflowRuntime.WorkflowTerminated +=               delegate(object sender, WorkflowTerminatedEventArgs e)               {                   waitHandle.Set();               };                       Dictionary
wfParas = new Dictionary
(); wfParas.Add("number1", number1); wfParas.Add("number2", number2); WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(ManualAddWorkflow),wfParas); instance.Start(); waitHandle.WaitOne(); return result; } }}

当然这个时候,ManualAddWorkflow工作流的设计就只需要一个CodeActivity来完成加法的逻辑就可以了,WebServiceInputActivity等这些活动就不需要了。

本文转自生鱼片博客园博客,原文链接:http://www.cnblogs.com/carysun/archive/2008/12/14/WF-WebService.html,如需转载请自行联系原作者

你可能感兴趣的文章
网络时间的那些事及 ntpq 详解
查看>>
《Visual Studio程序员箴言》----2.5 代码段
查看>>
《UML面向对象设计基础》—第2章2.4节面向对象的益处
查看>>
人工智能的基础--知识分类
查看>>
《Adobe Flash CS4中文版经典教程》——1.2 了解工作区
查看>>
《Unity着色器和屏幕特效开发秘笈(原书第2版)》一2.7 创建透明材质
查看>>
《像计算机科学家一样思考C++》——第1章 编程方式
查看>>
JAVA性能优化调查结果(第二部分)
查看>>
为你的 项目安装Sql跟踪工具-P6Spy
查看>>
Quagga上使用验证加固BGP会话安全
查看>>
演讲实录丨李德毅:无人驾驶的图灵测试
查看>>
自己动手写malloc
查看>>
双11数据大屏技术演进
查看>>
高可用笔记(2)redis
查看>>
Android 仿ios屏幕右边的圆圈
查看>>
《C语言及程序设计》资料——C语言中的运算符
查看>>
负载均衡双向证书配置方法
查看>>
Java NIO原理图文分析及代码实现
查看>>
C语言及程序设计初步例程-13 数值型数据的存储原理
查看>>
docker 文件位置[备忘]
查看>>