Question

I have a primitive "Assignment" activity. It takes values from an input variable for the parent sequence and puts them into an output variable for the parent sequence. If I simply perform this copy operation, everything works and the workflow completes successfully. If I introduce a system type "Random" or a project enum "ReportStatusType" the workflow throws an exception "A System.NotSupportedException was thrown: "Expression Activity type 'CSharpValue`1' requires compilation in order to run."

I created this workflow from an example for wf 4. I'm using wf 4.5, I think. I'm working in VS2013 and targeting .NET Framework 4.5. I used "WCF Workflow Service Application" template which uses an IIS platform. I'm using "WCF Test Client" to invoke the service and view the response.

THIS VALUE EXPRESSION WORKS:

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

THIS VALUE EXPRESSION FAILS:

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

My Imported Namespaces look like this:

enter image description here

This also fails if I try to create the ReportID in another assignment activity and then refer to it in the value expression shown above. It fails wherever Random() is expressed.

This may be a rookie mistake on my part, but I'm out of ideas. Anyone else have any?

Was it helpful?

Solution 2

This issue had nothing to do with compiling the C# expressions since I was deploying the service under IIS and it handles the compilation. It was resolved after reading this Visual Studio Feedback article. My assignment activity value was written like this, and always threw an exception when the Random() function was included:

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

I re-wrote the expression to this and everything works:

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: I was using the WCF Test Client to interact with my workflow service. When it catches an error, a large amount of text is dumped to the user, including the first 1024 bytes of the service response. It took me a while to learn to dig down past all that and find the internal exception. Here is an example of what to look for near the bottom of the text dump:

[ConfigurationErrorsException: The extension '.xalmx' is not registered with WCF/WF handler.

OTHER TIPS

From here:

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. To compile the C# expressions in a self-hosted XAMLX workflow service, first load the XAMLX file into a WorkflowService, and then pass the Body of the WorkflowService to the CompileExpressions method described in the previous Using C# expressions in code workflows section. In the following example, a XAMLX workflow service is loaded, the C# expressions are compiled, and then the workflow service is opened and waits for requests.

So you can:

// 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();

Option 2 - Use a custom host factory (probably easier and more straight-forward)

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

Now add the factory to your web.config:

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

C# expressions have to be compiled, whereas VB expressions don't.

From the docs:

Compiled Xaml

C# expressions are supported in compiled XAML workflows that are compiled to a type as part of a C# workflow project that targets .NET Framework 4.5. Compiled XAML is the default type of workflow authoring in Visual Studio, and C# workflow projects created in Visual Studio that target .NET Framework 4.5 use C# expressions.

Loose Xaml

C# expressions are supported in loose XAML workflows. The workflow host program that loads and invokes the loose XAML workflow must target .NET Framework 4.5, and CompileExpressions must be set to true (the default is false). To set CompileExpressions to true, create an ActivityXamlServicesSettings instance with its CompileExpressions property set to true, and pass it as a parameter to System.Activities.XamlIntegration.ActivityXamlServices.Load(System.IO.Stream).
If CompileExpressions Is not set to true, a NotSupportedException will be thrown with a message similar to the following: Expression Activity type 'CSharpValue`1' requires compilation in order to run. Please ensure that the workflow has been compiled.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top