2

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

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

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

在 MSDN 中环顾四周,我发现了这些文章:

他们说

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

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

我尝试进入项目配置并设置为使用本地 IIS,如下所示:iis配置

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

4

2 回答 2

4

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

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

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

 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);
    }       
} 
于 2014-12-10T02:43:57.760 回答
-3

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

于 2012-12-10T12:56:38.640 回答