带有c#表达式的XAMLX工作流
我正在vs2012/.Net 4.5/WF 4.5中开发一个自宿主工作流,很难理解下面的消息 表达式活动类型“CSharpValue”“1”需要编译才能运行。请确保已编译工作流 当我调用由服务引用生成的活动时会发生此错误(当您添加WCF服务引用时,端点上的每个操作都将成为活动) 环顾MSDN,我发现了以下文章:带有c#表达式的XAMLX工作流,c#,workflow-foundation-4,workflow-foundation,C#,Workflow Foundation 4,Workflow Foundation,我正在vs2012/.Net 4.5/WF 4.5中开发一个自宿主工作流,很难理解下面的消息 表达式活动类型“CSharpValue”“1”需要编译才能运行。请确保已编译工作流 当我调用由服务引用生成的活动时会发生此错误(当您添加WCF服务引用时,端点上的每个操作都将成为活动) 环顾MSDN,我发现了以下文章: 他们说 如果工作流服务托管在IIS或WAS中,则不需要执行其他步骤,但如果XAML工作流服务是自托管的,则必须编译C#表达式 所以,我终于开始问自己的问题:我应该怎么做才能点击F
但是,由于我仍然收到错误,我假设它不起作用…尽管文章提到了在IIS上运行,但我只是在实现fabric sugested时才设法运行工作流。。。这不是问题的答案。。。这更像是一个解决办法……老问题,但经过一天的拼凑各种信息后,我想我应该与大家分享一下,以防有人碰到这个问题 从C#表达式MSDN文档中: XAMLX工作流服务支持C#表达式如果工作流服务托管在IIS或WAS中,则不需要执行其他步骤,但如果XAML工作流服务是自托管的,则必须编译C#表达式 在添加自定义WorkflowHostFactory之前,这是正确的。在这种情况下,如果重写了错误的方法,则不会编译C#。以下代码不编译C#表达式,您将得到可怕的结果: 表达式活动类型“CSharpValue”“1”需要编译才能运行。请确保已编译工作流 或者,如果您没有查看跟踪消息,则更有用的方法是: System.ServiceModel.FaultException:无法执行该操作,因为工作流实例“5cfc33d1-b546-4ba8-a8ec-86d3cb16a68b”已中止 您可以通过覆盖其他factory方法,然后使用MSDN提供的代码编译活动来解决此问题: 以下是整个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);
}
}
莱昂纳多,你在这个问题上有没有进一步的运气?我似乎和你落入了同样的陷阱(@FryHard实际上没有…我最终回答了我自己的问题…这是一个简单的配置…取消指向?是的,但没关系…我甚至在将预编译的工作流网站发布到IIS后出现了此错误。似乎C#支持还不成熟…我现在终于明白了为什么会出现此错误:您能更精确地描述B吗我按照文章所说的做了:将提供的代码复制/粘贴到一个新类中,然后在工作流设置(web.config)中将该类设置为factory…很抱歉。在上述两篇文章中找不到任何关于将类用作工厂的内容。似乎我的问题与此无关。我忘记绑定一些使用
CSharpReference
的运行时元素。似乎我仍然可以使用有关您的解决方案的一些详细信息。我现在在决策节点中遇到了一个非常简单的问题这个答案太模糊了
protected override WorkflowServiceHost CreateWorkflowServiceHost(WorkflowService service, Uri[] baseAddresses)
{
CompileExpressions(service.Body);
return base.CreateWorkflowServiceHost(service, baseAddresses);
}
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);
}
}