Windows Workflow Foundation 3


Rule Conditions against custom activities and XAML activation - how should I achieve this?


If I have a simple custom activity and I generate a XAML only workflow with a rule condition that references the activity then how can I use XAML activation to execute the workflow?
Here's the workflow
<SequentialWorkflowActivity x:Name="xyz" xmlns:ns0="clr-namespace:ABC.Workflow.Common.ActivityLibrary;Assembly=ABC.Workflow.Common.ActivityLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
<ns0:ConsoleWritelineActivity Message="test" x:Name="consoleWritelineActivity1" />
<IfElseActivity x:Name="ifElseActivity1"> <IfElseBranchActivity x:Name="ifElseBranchActivity1"> <IfElseBranchActivity.Condition> <RuleConditionReference ConditionName="isATest" /> </IfElseBranchActivity.Condition> </IfElseBranchActivity> <IfElseBranchActivity x:Name="ifElseBranchActivity2" /> </IfElseActivity>
</SequentialWorkflowActivity>
I am using XAML activation to execute the workflow, catching WorkflowValidationFailedException, and have added the custom activity's assembly to a type provider thus, (which is inadequate, I suspect),
TypeProvider typeProvider = new TypeProvider(workflowRuntime);typeProvider.AddAssembly(typeof(ConsoleWritelineActivity).Assembly);workflowRuntime.AddService(typeProvider);
My workflow gets terminated with this message
Unable to validate Condition \"isATest\" as there are validation errors
if the rule is (this.consoleWritelineActivity1.Message == "test")
i.e.
<RuleDefinitions xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow"> <RuleDefinitions.Conditions> <RuleExpressionCondition Name="isATest"> <RuleExpressionCondition.Expression> <ns0:CodeBinaryOperatorExpression Operator="ValueEquality" xmlns:ns0="clr-namespace:System.CodeDom;Assembly=System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <ns0:CodeBinaryOperatorExpression.Left> <ns0:CodePropertyReferenceExpression PropertyName="Message"> <ns0:CodePropertyReferenceExpression.TargetObject> <ns0:CodeFieldReferenceExpression FieldName="consoleWritelineActivity1"> <ns0:CodeFieldReferenceExpression.TargetObject> <ns0:CodeThisReferenceExpression /> </ns0:CodeFieldReferenceExpression.TargetObject> </ns0:CodeFieldReferenceExpression> </ns0:CodePropertyReferenceExpression.TargetObject> </ns0:CodePropertyReferenceExpression> </ns0:CodeBinaryOperatorExpression.Left> <ns0:CodeBinaryOperatorExpression.Right> <ns0:CodePrimitiveExpression> <ns0:CodePrimitiveExpression.Value> <ns1:String xmlns:ns1="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">test</ns1:String> </ns0:CodePrimitiveExpression.Value> </ns0:CodePrimitiveExpression> </ns0:CodeBinaryOperatorExpression.Right> </ns0:CodeBinaryOperatorExpression> </RuleExpressionCondition.Expression> </RuleExpressionCondition> </RuleDefinitions.Conditions></RuleDefinitions>
and my workflow gets terminated with this message
An item with the same key has already been added
if the rule is (((ABC.Workflow.Common.ActivityLibrary.ConsoleWritelineActivity)this.GetActivityByName("consoleWritelineActivity")).Message == "test")
i.e.
<RuleDefinitions xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow"> <RuleDefinitions.Conditions> <RuleExpressionCondition Name="isATest"> <RuleExpressionCondition.Expression> <ns0:CodeBinaryOperatorExpression Operator="ValueEquality" xmlns:ns0="clr-namespace:System.CodeDom;Assembly=System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <ns0:CodeBinaryOperatorExpression.Left> <ns0:CodePropertyReferenceExpression PropertyName="Message"> <ns0:CodePropertyReferenceExpression.TargetObject> <ns0:CodeCastExpression> <ns0:CodeCastExpression.Expression> <ns0:CodeMethodInvokeExpression> <ns0:CodeMethodInvokeExpression.Parameters> <ns0:CodePrimitiveExpression> <ns0:CodePrimitiveExpression.Value> <ns1:String xmlns:ns1="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">consoleWritelineActivity</ns1:String> </ns0:CodePrimitiveExpression.Value> </ns0:CodePrimitiveExpression> </ns0:CodeMethodInvokeExpression.Parameters> <ns0:CodeMethodInvokeExpression.Method> <ns0:CodeMethodReferenceExpression MethodName="GetActivityByName"> <ns0:CodeMethodReferenceExpression.TargetObject> <ns0:CodeThisReferenceExpression /> </ns0:CodeMethodReferenceExpression.TargetObject> </ns0:CodeMethodReferenceExpression> </ns0:CodeMethodInvokeExpression.Method> </ns0:CodeMethodInvokeExpression> </ns0:CodeCastExpression.Expression> <ns0:CodeCastExpression.TargetType> <ns0:CodeTypeReference ArrayElementType="{p11:Null}" BaseType="ABC.Workflow.Common.ActivityLibrary.ConsoleWritelineActivity" Options="0" ArrayRank="0" xmlns:p11="http://schemas.microsoft.com/winfx/2006/xaml" /> </ns0:CodeCastExpression.TargetType> </ns0:CodeCastExpression> </ns0:CodePropertyReferenceExpression.TargetObject> </ns0:CodePropertyReferenceExpression> </ns0:CodeBinaryOperatorExpression.Left> <ns0:CodeBinaryOperatorExpression.Right> <ns0:CodePrimitiveExpression> <ns0:CodePrimitiveExpression.Value> <ns1:String xmlns:ns1="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">test</ns1:String> </ns0:CodePrimitiveExpression.Value> </ns0:CodePrimitiveExpression> </ns0:CodeBinaryOperatorExpression.Right> </ns0:CodeBinaryOperatorExpression> </RuleExpressionCondition.Expression> </RuleExpressionCondition> </RuleDefinitions.Conditions></RuleDefinitions>
In a code only workflow there is a private variable created for each activity added to the workflow allowing you to do this.activityName to access the activities in the workflow, this will only work for code only workflows.  When you are working with xoml workflow, code separation or xoml only, you need to use GetActivityByName to have access to the activity since no variables are created. 
 
Which build are you using?  Can you post the StackTrace for the “An item with the same key has already been added” exception you are getting when you use GetActivityByName?
Writing a special type provider will not work.  The variables don't exist in the workflow so there is nothing to resolve.  A type provider is use to resolve types not variables.  This is a known issue with using XAML activation that will not be fixed in V1.  We are looking into make it easier in a future version.
Go with your second option since "this" is going to refer to a sequential workflow activity and not a new workflow type. 
In order to get this to work, you need to edit one line of your rules file in order to qualify the type name.  What is happening is that the rule validation code is not finding your type in the referenced assembly so it is trying to add it into the collection. 
Change this:
<ns0:CodeTypeReference ArrayElementType="{p11:Null}" BaseType="ABC.Workflow.Common.ActivityLibrary.ConsoleWritelineActivity" Options="0" ArrayRank="0" xmlns:p11="http://schemas.microsoft.com/winfx/2006/xaml" />
to this (Assuming an assembly name of ABC.Workflow.Common.ActivityLibrary):
<ns0:CodeTypeReference ArrayElementType="{p11:Null}" BaseType="ABC.Workflow.Common.ActivityLibrary.ConsoleWritelineActivity,ABC.Workflow.Common.ActivityLibrary" Options="0" ArrayRank="0" xmlns:p11="http://schemas.microsoft.com/winfx/2006/xaml" />
This should work for you. 
Matt
Thanks Matt.
Editing the rules xaml moves me onto another error "Cannot evaluate property \"Message\" because its target object is null".
Ignoring that, for the moment, I have two other issues.
1. This xaml was serialized by my rehosted designer control which obviously knew enough about the activity in order to sucessfully create the rule. Not sure why this would be wrong.
2. I want the first style of rule because the second is too complex for customers who are going to be editing our xoml workflows. Can you set me on the right track to get this working? (I guess that I may still have an issue with the rules xaml generated by the designer, but that's another problem).
The problem is that when you are editing a default XOML workflow, "this" points to the type SequentialWorkflowActivity.  This type does not have any properties, nor can you get typed access to the child activities directly, as the XOML has no "fields" defined which point to those activities. I haven't dug into the rules editor in much detail yet, but it seems very code/type focused so you might run into some problems there when trying to write rules for XOML workflows. 
One solution is to create a base workflow type that derives from the sequential type and then build your XOML workflows for this type.  Then you can have methods on your base type that will help people build rules like a method that makes it easy to reference child activities. 
As for your item 1, when I did this my XOML was created from the VS hosted designer, but it still didn't work until I put the assembly name in there.  I'm not sure if this is technically a bug but it causes problems. 
Matt
In a code only workflow there is a private variable created for each activity added to the workflow allowing you to do this.activityName to access the activities in the workflow, this will only work for code only workflows.  When you are working with xoml workflow, code separation or xoml only, you need to use GetActivityByName to have access to the activity since no variables are created. 
 
Which build are you using?  Can you post the StackTrace for the “An item with the same key has already been added” exception you are getting when you use GetActivityByName?
Stack trace below. (using WinFx beta 2)
I believe, from other posts, that I can use the first approach but would have to write some kind of custom type provider. I cannot expect customers to write rules using GetActivityByName and casting etc. Unfortunately, I don't know how I should go about writing such a type provider. Can you help?
" at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)\r\n at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)\r\n at System.Workflow.Activities.Rules.SimpleRunTimeTypeProvider.get_RemainingAssemblies()\r\n at System.Workflow.Activities.Rules.SimpleRunTimeTypeProvider.GetType(String name, Boolean throwOnError)\r\n at System.Workflow.Activities.Rules.RuleValidation.FindType(String typeName)\r\n at System.Workflow.Activities.Rules.RuleValidation.ResolveType(CodeTypeReference typeRef)\r\n at System.Workflow.Activities.Rules.CastExpression.System.Workflow.Activities.Rules.IRuleExpression.Validate(RuleValidation validation, Boolean isWritten)\r\n at System.Workflow.Activities.Rules.RuleExpressionWalker.Validate(RuleValidation validation, CodeExpression expression, Boolean isWritten)\r\n at System.Workflow.Activities.Rules.PropertyReferenceExpression.System.Workflow.Activities.Rules.IRuleExpression.Validate(RuleValidation validation, Boolean isWritten)\r\n at System.Workflow.Activities.Rules.RuleExpressionWalker.Validate(RuleValidation validation, CodeExpression expression, Boolean isWritten)\r\n at System.Workflow.Activities.Rules.BinaryExpression.System.Workflow.Activities.Rules.IRuleExpression.Validate(RuleValidation validation, Boolean isWritten)\r\n at System.Workflow.Activities.Rules.RuleExpressionWalker.Validate(RuleValidation validation, CodeExpression expression, Boolean isWritten)\r\n at System.Workflow.Activities.Rules.RuleValidation.ValidateConditionExpression(CodeExpression expression)\r\n at System.Workflow.Activities.Rules.RuleExpressionCondition.Validate(RuleValidation validation)\r\n at System.Workflow.Activities.Rules.RuleConditionReference.Evaluate(Activity activity, IServiceProvider provider)\r\n at System.Workflow.Activities.IfElseActivity.Execute(ActivityExecutionContext executionContext)\r\n at System.Workflow.ComponentModel.ActivityExecutor`1.Execute(T activity, ActivityExecutionContext executionContext)\r\n at System.Workflow.ComponentModel.CompositeActivityExecutor`1.Execute(T activity, ActivityExecutionContext executionContext)\r\n at System.Workflow.ComponentModel.ActivityExecutor`1.Execute(Activity activity, ActivityExecutionContext executionContext)\r\n at System.Workflow.ComponentModel.ActivityExecutionFilter.Execute(Activity activity, ActivityExecutionContext executionContext)\r\n at System.Workflow.ComponentModel.FaultAndCancellationHandlingFilter.Execute(Activity activity, ActivityExecutionContext executionContext)\r\n at System.Workflow.ComponentModel.ActivityExecutorOperation.Run(IWorkflowCoreRuntime workflowCoreRuntime)\r\n at System.Workflow.Runtime.Scheduler.Run()"
Writing a special type provider will not work.  The variables don't exist in the workflow so there is nothing to resolve.  A type provider is use to resolve types not variables.  This is a known issue with using XAML activation that will not be fixed in V1.  We are looking into make it easier in a future version.

Related Links

Workflow Designer
How do you load XOML only State Workflow in WFPad for WWFBeta 2.2 (with namespace for codebehind assembly, and activities)?
invoke sub StateMachine workflow
Using WWF to model and support "Tech Trees" in RTS games
RuleConditionDialog and intellisense
Workflow Persistence & Event Arguments
PersistenceService - Transaction Timeout
SimpleExpenseReport
SQLTrackingQuery from Workflow
CreateWorkflow failing validation
xbox live mic help
download code samples of Microsoft press' windows workflow foundation step by step - Kenn Scribner
Advantage and disadvantage of ASP.NET WorkFl
When do activities CANCEL and How do i force activities to cancel state?
Windows workflow 4.0 persistent issues
Windows Workflow 4

Categories

MSDN
Visual Studio Languages
Windows Desktop Develo...
SharePoint
.NET Framework
SQL Server
Windows Embedded Compact
SQL Server (Pre-release)
WebsitePanel
Bing Maps
Other Forums
Archived Forums #
Archived Forums V
Archived Forums Visual...
Archived Forums
Microsoft R
Suggestions and Feedba...
Visual C++
C++ Standards, Extensi...
Visual Studio Editor
Application Insights (AI)
Developing Universal W...
XboxLiveDevelopment
Developing Windows Des...
Windows Desktop Search...
Windows Desktop SDK
Windows Desktop Ribbon...
Windows Hardware Testi...
Hardware Development B...
Open XML Format SDK
SharePoint 2013 - Search
SharePoint 2010 - Deve...
SharePoint 2010 - Search
SharePoint 2010 - Setu...
SharePoint Legacy Vers...
SharePoint Legacy Vers...
SharePoint Legacy Vers...
Azure Storage
Azure SQL Database
Pricing & Billing
Service Bus
Azure Multi-Factor Aut...
Azure Networking (DNS,...
Azure Virtual Machines
Azure Cache
Azure Data Factory
Azure Mobile Engagement
Cognitive Services
Azure Security Center
Windows Presentation F...
Team Foundation Server...
Team Foundation Server...
BizTalk Server RFID
LINQ to SQL
JScript Native
SyncFx - General [Read...
SyncFx - SyncToy-File ...
Windows Mobile Develop...
SQL Server Tools
SQL Server Notificatio...
SQL Server Samples and...
SQL Server 2012 Integr...
SQL Server 2012 Master...
SQL Server 2012 Databa...
Windows Live Writer: D...
CRM
MSDN Subscriptions Fee...
MSDN, TechNet and Expr...
Known Issues for Windo...
Bing Maps Web Controls
Open Specifications Qu...
Microsoft Unified Comm...
Getting Started with S...
Silverlight 4
Accessing Web Services...
WCF RIA Services with ...
Expression Web and Sup...
Surface Application De...
Windows Performance To...
.NET Framework 4: Wind...
Announcements about pr...
AppFabric Service and ...
Building Windows Store...
AppFabric Caching
Chart Controls for .NE...
Game Technologies: Gen...
Game Technologies: XNA...
(Retired) Exchange Pre...
Face Tracking – Kinect...
Git, Mercurial and Dro...
LightSwitch in Visual ...
JScript for the .NET F...
Managed Extensibility ...
Microsoft adCenter: De...
Microsoft Security Dev...
Microsoft Security Dev...
Network Quality of Ser...
Office Live Small Busi...
Office Live Small Busi...
patterns & practices: ...
Regular Expressions
POS for .NET
Search Server: Federation
Search, Organize, and ...
Security for Azure
Share your How to samp...
SQL Server 2014 High A...
Team Foundation Server...
Transactions Programming
Visual Basic Interop a...
Visual Basic Power Packs
Visual C# Express Edition
Visual C++ Express 200...
Visual Studio 2008 (Pr...
Visual Studio Code Ana...
Visual Studio Guidance...
Visual Studio Source C...
Visual Studio Online "...
Web Gadget Development
Windows MultiPoint Mou...
Building Windows Store...
OneDrive Development (...
Microsoft Partner Cent...

Resources

Encrypt Message



code
soft
python
ios
c
html
jquery
cloud
mobile