【问题标题】:XAMLX Workflow with c# expressions带有 c# 表达式的 XAMLX 工作流
【发布时间】:2014-12-10 13:07:56
【问题描述】:

我正在 vs2012/.Net 4.5/WF 4.5 中开发一个自托管工作流,并且很难弄清楚以下消息

表达式活动类型“CSharpValue`1”需要编译才能运行。请确保已编译工作流。

当我调用由服务引用生成的活动时会发生此错误(当您添加 WCF 服务引用时,端点上的每个操作都会成为一个活动)。

我在 MSDN 中四处寻找这些文章:

他们这么说

如果工作流服务托管在 IIS 或 WAS 中,则不需要额外的步骤,但如果 XAML 工作流服务是自托管的,则必须编译 C# 表达式

所以,我终于得到了我的问题:我应该怎么做才能按 F5 并调试我的工作流,让它在 IIS 上运行?并停止这个该死的异常......

我已尝试转到项目配置并设置为使用本地 IIS,如下所示:

但由于我仍然收到错误,我认为它不起作用...

【问题讨论】:

  • Leonardo 你在这个问题上还有什么运气吗?我似乎和你落入了同一个陷阱。 :(
  • @FryHard 实际上没有......我最终回答了我自己的问题......这是一个简单的配置......令人失望?是的,但没关系...
  • 在将预编译的工作流网站发布到 IIS 后,我什至收到此错误。似乎对 C# 的支持还不够成熟……
  • 我现在终于知道为什么会出现这个错误:connect.microsoft.com/VisualStudio/feedback/details/779794/…

标签: c# workflow-foundation-4 workflow-foundation


【解决方案1】:

老问题,但是在拼凑了一天的各种信息之后,我想我会分享一下,以防其他人遇到这个问题。

来自 C# 表达式 MSDN 文档:

XAMLX 工作流服务支持 C# 表达式。 如果工作流服务托管在 IIS 或 WAS 中,则不需要额外的步骤,但如果 XAML 工作流服务是自托管的,则必须编译 C# 表达式。

在您添加自定义 WorkflowHostFactory 之前都是如此。在这种情况下,如果你重写了错误的方法,你的 C# 将不会被编译。以下代码不会编译 C# 表达式,您会感到害怕:

表达式活动类型“CSharpValue`1”需要编译才能运行。请确保已编译工作流。

或者,如果您不查看跟踪消息,则更有帮助:

System.ServiceModel.FaultException:无法执行操作,因为 WorkflowInstance '5cfc33d1-b546-4ba8-a8ec-86d3cb16a68b' 已中止。

   public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
    {
        return base.CreateServiceHost(constructorString, baseAddresses);
    }

您可以通过覆盖其他工厂方法然后使用通过 MSDN C# Expressions in Workflow Foundation 4.5 提供的代码编译您的活动来解决此问题:

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

这是整个 WorkflowServiceHostFactory:

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

    static void CompileExpressions(Activity activity)
    {
        // activityName is the Namespace.Type of the activity that contains the
        // C# expressions.
        string activityName = activity.GetType().ToString();

        // Split activityName into Namespace and Type.Append _CompiledExpressionRoot to the type name
        // to represent the new type that represents the compiled expressions.
        // Take everything after the last . for the type name.
        string activityType = activityName.Split('.').Last() + "_CompiledExpressionRoot";
        // Take everything before the last . for the namespace.
        string activityNamespace = string.Join(".", activityName.Split('.').Reverse().Skip(1).Reverse());

        // Create a TextExpressionCompilerSettings.
        TextExpressionCompilerSettings settings = new TextExpressionCompilerSettings
        {
            Activity = activity,
            Language = "C#",
            ActivityName = activityType,
            ActivityNamespace = activityNamespace,
            RootNamespace = null,
            GenerateAsPartialClass = false,
            AlwaysGenerateSource = true,
            ForImplementation = false
        };

        // Compile the C# expression.
        TextExpressionCompilerResults results =
            new TextExpressionCompiler(settings).Compile();

        // Any compilation errors are contained in the CompilerMessages.
        if (results.HasErrors)
        {
            throw new Exception("Compilation failed.");
        }

        // Create an instance of the new compiled expression type.
        ICompiledExpressionRoot compiledExpressionRoot =
            Activator.CreateInstance(results.ResultType,
                new object[] { activity }) as ICompiledExpressionRoot;

        // Attach it to the activity.
        CompiledExpressionInvoker.SetCompiledExpressionRoot(
            activity, compiledExpressionRoot);
    }       
} 

【讨论】:

    【解决方案2】:

    尽管文章中提到了在 IIS/WAS 上运行,但我仅在实施建议的结构时才设法运行工作流...这不是问题的答案...更像是一种解决方法...

    【讨论】:

    • 您能否更准确地描述您为使其发挥作用所做的工作?
    • @TorbenRahbekKoch 我按照文章所说的做了:将提供的代码复制/粘贴到一个新类中,然后我只是在工作流设置(web.config)中将该类设置为工厂......
    • 对不起。在提到的任何两篇文章中都找不到任何关于将类用作工厂的信息。似乎我的问题无论如何都无关紧要。我忘了绑定一些使用CSharpReference 的运行时元素。
    • 看来我仍然可以使用有关您的解决方案的一些详细信息。我现在在具有非常简单的比较表达式的决策节点中遇到了问题。
    • 这个答案太模糊了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-09
    • 1970-01-01
    • 1970-01-01
    • 2018-06-04
    相关资源
    最近更新 更多