You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Workflow Foundation封装为API?寻求WCF/ASP.NET托管工作流现代方案

现代化封装Workflow Foundation为API的方案(WCF/ASP.NET托管)

我之前帮好几个团队搞定过Workflow Foundation封装成API的需求,尤其是针对VS2017环境的现代化改造——毕竟老示例确实大多跑不起来了。下面给你两个实用方案,都是能直接在VS2017里落地的:


一、ASP.NET Core 托管方案(推荐,现代化轻量)

VS2017支持ASP.NET Core 2.1及以上版本,这个方案比WCF更适合做API层,生态也更活跃,后续维护起来更省心。

1. 项目初始化

  • 打开VS2017,新建ASP.NET Core Web应用程序,选「API」模板
  • 通过NuGet安装Microsoft.Workflow.Core和Microsoft.Workflow.Runtime(注意选适配.NET Core 2.1的版本,VS2017里搜的时候筛选一下版本范围)

2. 封装工作流服务层

核心是写一个工作流管理类,负责实例化、运行工作流,同时处理外部数据的传入和按需查询:

using System;
using System.Activities;
using System.Collections.Generic;
using System.Threading.Tasks;

public class WorkflowService
{
    // 运行工作流并传入外部参数
    public async Task<IDictionary<string, object>> RunWorkflow(Type workflowType, IDictionary<string, object> inputParams)
    {
        var workflowInvoker = new WorkflowInvoker(workflowType);
        // 把外部数据传入工作流的输入参数
        var outputs = await workflowInvoker.InvokeAsync(inputParams);
        return outputs;
    }

    // 按需查询工作流实例中的数据(这里用缓存演示,生产环境建议用持久化存储)
    public object GetWorkflowData(Guid workflowInstanceId, string dataName)
    {
        var cachedInstance = WorkflowInstanceCache.GetInstance(workflowInstanceId);
        return cachedInstance?.GetVariable(dataName);
    }
}

// 简单的工作流实例缓存类(用于演示按需查询,生产环境替换为SQL Server持久化)
public static class WorkflowInstanceCache
{
    private static readonly Dictionary<Guid, DynamicActivity> _instances = new Dictionary<Guid, DynamicActivity>();
    public static void AddInstance(Guid id, DynamicActivity instance) => _instances[id] = instance;
    public static DynamicActivity GetInstance(Guid id) => _instances.TryGetValue(id, out var inst) ? inst : null;
}

3. 编写API控制器

创建一个WorkflowController,暴露接口给外部系统调用:

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;

[Route("api/[controller]")]
[ApiController]
public class WorkflowController : ControllerBase
{
    private readonly WorkflowService _workflowService;

    // 依赖注入工作流服务
    public WorkflowController(WorkflowService workflowService)
    {
        _workflowService = workflowService;
    }

    // 触发工作流运行,接收外部数据
    // POST api/workflow/run
    [HttpPost("run")]
    public async Task<IActionResult> RunWorkflow([FromBody] WorkflowRunRequest request)
    {
        // 根据传入的工作流类型全名获取类型(比如"MyWorkflowProject.ApprovalWorkflow")
        var workflowType = Type.GetType(request.WorkflowTypeName);
        if (workflowType == null)
            return BadRequest("指定的工作流类型无效");

        var outputs = await _workflowService.RunWorkflow(workflowType, request.InputParams);
        return Ok(outputs);
    }

    // 按需查询工作流实例中的数据
    // GET api/workflow/data/{instanceId}/{dataName}
    [HttpGet("data/{instanceId}/{dataName}")]
    public IActionResult GetWorkflowData(Guid instanceId, string dataName)
    {
        var data = _workflowService.GetWorkflowData(instanceId, dataName);
        if (data == null)
            return NotFound("未找到该工作流实例的指定数据");
        return Ok(data);
    }
}

// 接收外部请求的模型类
public class WorkflowRunRequest
{
    public string WorkflowTypeName { get; set; }
    public Dictionary<string, object> InputParams { get; set; }
}

二、WCF托管方案(兼容旧系统)

如果你的项目依赖WCF生态,VS2017也完全支持,下面是简化的现代化封装方案:

1. 项目初始化

  • 新建WCF服务应用程序(VS2017里的官方模板)
  • 通过NuGet安装最新版的System.Activities包(适配.NET Framework 4.6及以上,VS2017默认支持)

2. 定义WCF服务契约

先写好对外的接口契约,明确调用方法:

using System.Collections.Generic;
using System.ServiceModel;
using System.Threading.Tasks;

[ServiceContract]
public interface IWorkflowService
{
    [OperationContract]
    Task<Dictionary<string, object>> RunWorkflow(string workflowTypeName, Dictionary<string, object> inputParams);

    [OperationContract]
    object GetWorkflowData(System.Guid instanceId, string dataName);
}

3. 实现服务类

把工作流的逻辑封装到服务实现里:

using System;
using System.Activities;
using System.Collections.Generic;
using System.Threading.Tasks;

public class WorkflowService : IWorkflowService
{
    public async Task<Dictionary<string, object>> RunWorkflow(string workflowTypeName, Dictionary<string, object> inputParams)
    {
        var workflowType = Type.GetType(workflowTypeName);
        if (workflowType == null)
            throw new FaultException("指定的工作流类型无效");

        var invoker = new WorkflowInvoker(workflowType);
        var outputs = await invoker.InvokeAsync(inputParams);
        return outputs as Dictionary<string, object>;
    }

    public object GetWorkflowData(Guid instanceId, string dataName)
    {
        // 和ASP.NET方案的缓存逻辑一致,生产环境替换为持久化存储
        var instance = WorkflowInstanceCache.GetInstance(instanceId);
        return instance?.GetVariable(dataName);
    }
}

4. 配置WCF服务

修改Web.config,配置HTTP绑定让外部可以通过HTTP调用:

<system.serviceModel>
  <services>
    <service name="YourNamespace.WorkflowService">
      <endpoint address="" binding="basicHttpBinding" contract="YourNamespace.IWorkflowService">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      <host>
        <baseAddresses>
          <add baseAddress="http://localhost:8733/Design_Time_Addresses/YourNamespace/WorkflowService/" />
        </baseAddresses>
      </host>
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior>
        <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
        <serviceDebug includeExceptionDetailInFaults="False"/>
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>

针对VS2017的关键注意事项

  • NuGet包版本:Workflow相关包要和你的.NET版本匹配——ASP.NET Core选Microsoft.Workflow.Core 1.1.x+,.NET Framework选System.Activities 4.x+
  • 工作流持久化:如果是长期运行的工作流(比如审批流程),不要用缓存,改用WorkflowApplication结合SQL Server实例存储,VS2017里可以通过Microsoft.Workflow.Runtime包配置
  • 调试技巧:把API/WCF服务设为启动项目,用Postman(ASP.NET Core)或WCF测试客户端(WCF)直接调用接口,就能在VS2017里调试工作流逻辑了

内容的提问来源于stack exchange,提问作者nasytnyk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:44:27