当C#表达式使用引用类型时,Activity会抛出异常

时间:2014-04-07 14:15:01

标签: c# workflow-foundation-4

我有一个原始的"作业"活动。它从父序列的输入变量中获取值,并将它们放入父序列的输出变量中。如果我只是执行此复制操作,一切正常,工作流成功完成。如果我介绍一个系统类型"随机"或项目枚举" ReportStatusType"工作流引发异常"抛出了System.NotSupportedException:"表达式活动类型' CSharpValue`1'需要编译才能运行。"

我从wf 4的一个例子创建了这个工作流程。我认为我使用的是wf 4.5。我在VS2013中工作,目标是.NET Framework 4.5。我使用了" WCF工作流服务应用程序"使用IIS平台的模板。我正在使用" WCF测试客户端"调用服务并查看响应。

此值表达式的工作原理:

new ExpenseReportConfirmation() {
       Amount = report.Amount,
       City = report.Amount,
       Client = report.Client,
       Employee = report.Employee,
       EndDate = report.EndDate,
       StartDate = report.StartDate,
       ReportID = 5
    };

此值表达失败:

new ExpenseReportConfirmation() {
       Amount = report.Amount,
       City = report.Amount,
       Client = report.Client,
       Employee = report.Employee,
       EndDate = report.EndDate,
       StartDate = report.StartDate,
       ReportID = new Random().Next(0,5),
    };

我的导入命名空间如下所示:

enter image description here

如果我尝试在另一个赋值活动中创建ReportID,然后在上面显示的值表达式中引用它,那么这也会失败。无论表达Random()的地方都会失败。

这可能是我的一个新手错误,但我没有想法。其他人有没有?

3 个答案:

答案 0 :(得分:3)

来自here

  

XAMLX工作流服务支持C#表达式。 当a   工作流服务托管在IIS或WAS中,然后没有其他步骤   必需,但如果XAML工作流服务是自托管的,那么C#   必须编译表达式。编译一个C#表达式   自托管XAMLX工作流服务,首先将XAMLX文件加载到   WorkflowService,然后将WorkflowService的Body传递给   前面使用C#中描述的CompileExpressions方法   代码工作流程部分中的表达式。在以下示例中,a   加载XAMLX工作流服务,编译C#表达式,以及   然后打开工作流服务并等待请求。

所以你可以:

// Load the XAMLX workflow service.
WorkflowService workflow1 =
    (WorkflowService)XamlServices.Load(xamlxPath);

// Compile the C# expressions in the workflow by passing the Body to CompileExpressions.
CompileExpressions(workflow1.Body);

// Initialize the WorkflowServiceHost.
var host = new WorkflowServiceHost(workflow1, new Uri("http://localhost:8293/Service1.xamlx"));

// Enable Metadata publishing/
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);

// Open the WorkflowServiceHost and wait for requests.
host.Open();
Console.WriteLine("Press enter to quit");
Console.ReadLine();

选项2 - 使用自定义主机工厂(可能更简单,更直接)

public class CSharpWorkflowServiceHostFactory : WorkflowServiceHostFactory
{
    protected override WorkflowServiceHost CreateWorkflowServiceHost(WorkflowService service, Uri[] baseAddresses)
    {
        CompileExpressions(service.Body);
        return base.CreateWorkflowServiceHost(service, baseAddresses);
    }
}

现在将工厂添加到web.config:

<system.serviceModel>
    <serviceHostingEnvironment>
        <serviceActivations>
             <add relativeAddress="WcfWorkflow.xalmx" service="WcfWorkflow.xalmx" factory="Namespace.CSharpWorkflowServiceHostFactory" />
        </serviceActivations>
    </serviceHostingEnvironment>
</system.serviceMode>

答案 1 :(得分:1)

此问题与编译C#表达式无关,因为我在IIS下部署服务并处理编译。阅读this Visual Studio Feedback article后解决了这个问题。我的赋值活动值是这样写的,并且在包含Random()函数时总是抛出异常:

new ExpenseReportConfirmation() {
  Amount = report.Amount,
  City = report.City,
  Client = report.Client,
  Employee = report.Employee,
  EndDate = report.EndDate,
  StartDate = report.StartDate,
  ReportID = new Random().Next(0, 50)
};

我重写了这个表达式并且一切正常:

new ExpenseReportConfirmation() { Amount = report.Amount, City = report.City, Client = report.Client, Employee = report.Employee, EndDate = report.EndDate, StartDate = report.StartDate, ReportID = new Random().Next(0, 50) };

PS: 我正在使用WCF测试客户端与我的工作流服务进行交互。当它捕获错误时,会向用户转储大量文本,包括服务响应的前1024个字节。我花了一段时间才学会挖掘所有这些并找到内部异常。以下是在文本转储底部附近寻找内容的示例:

  

[ConfigurationErrorsException:扩展名'.xalmx'不是   在WCF / WF处理程序中注册。

答案 2 :(得分:0)

必须编译C#表达式,而VB表达式不必编译。

From the docs:

  

编译Xaml

     

编译的XAML工作流支持C#表达式,这些工作流作为面向.NET Framework 4.5的C#工作流项目的一部分编译为类型。编译的XAML是Visual Studio中默认的工作流创作类型,在Visual Studio中创建的以.NET Framework 4.5为目标的C#工作流项目使用C#表达式。

     

松散的Xaml

     

松散的XAML工作流程支持C#表达式。 加载和调用松散XAML工作流的工作流主机程序必须以.NET Framework 4.5为目标,并且CompileExpressions必须设置为true(默认值为false)。要将CompileExpressions设置为true,创建一个ActivityXamlServicesSettings实例,其CompileExpressions属性设置为true,并将其作为参数传递给System.Activities.XamlIntegration.ActivityXamlServices.Load(System.IO.Stream)
  如果CompileExpressions未设置为true,则将抛出NotSupportedException,并显示类似于以下内容的消息:表达式活动类型&#39; CSharpValue`1&#39;需要编译才能运行。请确保已编译工作流程。