XAMLX Workflow with c# expressions

I'm developing a self host workflow in vs2012/.Net 4.5/WF 4.5 and having quite a hard time figuring out the following message

Expression Activity type 'CSharpValue`1' requires compilation in order to run. Please ensure that the workflow has been compiled.

This error happens when i call a activity generated by a service reference (When you add a WCF service reference, each action on the endpoint become a activity).

Looking around in MSDN i've came across these articles:

  • http://msdn.microsoft.com/en-us/library/ee358749.aspx
  • http://msdn.microsoft.com/en-us/library/29110be7-f4e3-407e-8dbe-78102eb21115#CodeWorkflows
  • They said that

    When a workflow service is hosted in IIS or WAS then no additional steps are required, but if the XAML workflow service is self-hosted, then the C# expressions must be compiled

    So, i finally get to my question: What should I do so i can hit F5 and debug my workflow, having it run on IIS? and stop this god damn exception...

    I've tried to go to the project config and set to use local IIS as follow: iis配置

    but since i still get the error i assume it's not working...


    Old question, but after a day of piecing together various bits of information, I thought I'd share just in case someone else runs into this.

    From the C# expressions MSDN documentation:

    C# expressions are supported in XAMLX workflow services. When a workflow service is hosted in IIS or WAS then no additional steps are required , but if the XAML workflow service is self-hosted, then the C# expressions must be compiled.

    This is true until you add a custom WorkflowHostFactory. In that case, if you override the wrong method, your C# will NOT be compiled. The following code does NOT compile C# expressions and you will get the dreaded:

    Expression Activity type 'CSharpValue`1' requires compilation in order to run. Please ensure that the workflow has been compiled.

    Or, if you're not looking at tracing messages, the even more helpful:

    System.ServiceModel.FaultException: The operation could not be performed because WorkflowInstance '5cfc33d1-b546-4ba8-a8ec-86d3cb16a68b' was aborted.

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

    You can fix this by overriding the other factory method and then compiling your activity using the code provided via MSDN C# Expressions in Workflow Foundation 4.5:

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

    Here is the whole 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);
        }       
    } 
    

    尽管文章中提到的有关在IIS / WAS上运行的内容,但我只是在实施面料时才成功运行了工作流程......这不是问题的答案......它更像是一种解决方法...

    链接地址: http://www.djcxy.com/p/95882.html

    上一篇: 通过config指定WCF服务的运行时地址

    下一篇: XAMLX工作流与C#表达式