|
|
Browse by Tags
All Tags » Windows Workflow (RSS)
-
Several peolple have gotten a "The root activity type is invalid" error when using the Custom Activity Designer sample that can be found at http://wf.netfx3.com/files/folders/activity_behavior/entry840.aspx . I created an update project that should resolve the problem, which can be downloaded from the link below. Read More...
|
-
The Windows Workflow Foundation (WF) team is asking for your assistance in prioritizing our efforts going forward. If you’re interested in helping out, please take the time to fill in the survey at https://live.datstat.com/MSCSD-Collector/Survey.ashx?Name=WF_Activities_Survey_blog on your current and future usage of WF Activities, and the areas where you would like to see us invest going forward. Your feedback will be extremely helpful in shaping the future of WF. Read More...
|
-
Being able to have a StateMachineWorkflow hold state across multiple different web service calls can be very useful. This example will show you how to get start. The first step is to create your interface. For this example I will be using the following: public interface IOrderService { string CreateOrder( string id); string UpdateOrder( string id); string ProcessOrder( string id); void CancelOrder( string id); string ShipOrder( string id); string GetOrderStatus(); } To implement one of the methods add a WebServiceInputActivity, which is an IEventActivity, into an EventDriven on the state machine workflow or any of the states contained within it. After setting the InterfaceType and the Method name the input parameters will appear in the property browser. Bind them to workflow level variables so that you can use them across the workflow. Add any activities needed to do the work for the method followed by a WebServiceOutputActivity. After setting the InputActivityName the out parameters for the method are displayed so that you can bind to the variables containing the results. After implementing all the methods you need right click on the project and choose Publish as Web Service to create the web service project. In order to make multiple calls to the same web service you need to make sure that you have added a CookieContainer like below: localhost. StateMachineWorkflow_WebService webservice = webservice = new localhost. StateMachineWorkflow_WebService (); webservice.CookieContainer Read More...
|
-
If you have your own custom ActivityCondition you are only going to be able to use it with your custom activities, not out of the box activities like While or IfElseBranch. First start by creating your custom ActivityCondition like the following: [ DisplayName ( "Custom Activity Condition" )] public class CustomActivityCondition : ActivityCondition { public override bool Evaluate( Activity activity, IServiceProvider provider) { return ( this .customCondition.Equals( "foo" , StringComparison .CurrentCultureIgnoreCase)); } private string customCondition = string .Empty; public string CustomCondition { get { return this .customCondition; } set { this .customCondition = value ; } } } Next create a custom TypeConverter that will add your activity condition to the list of available activity conditions for your user to select like below: public class CustomActivityConditionTypeConverter : TypeConverter { private Hashtable conditionDecls = new Hashtable (); public CustomActivityConditionTypeConverter() { AddTypeToHashTable( typeof ( RuleConditionReference )); AddTypeToHashTable( typeof ( CodeCondition )); AddTypeToHashTable( typeof ( CustomActivityCondition )); } private void AddTypeToHashTable( Type typeToAdd) { string key = typeToAdd.FullName; object [] attributes = typeToAdd.GetCustomAttributes( typeof ( DisplayNameAttribute ), false ); if (attributes != null && attributes.Length > 0 && attributes[0] is DisplayNameAttribute ) key = (( DisplayNameAttribute )attributes[0]).DisplayName; Read More...
|
-
The Switch activity I created is based on the switch statement in C# or the Select Case statements in VB . You have an expression and one or more case statements, one of which can be the default. To model within workflow the case becomes a property that must be on the children of the Switch activity, which you can do this a couple of ways. One would be to have a Case activity with a Cases property that would be a required child. Another would be to have an attached Cases property that would be added to all children of the Switch. I chose to use an attached property because I think it gives a better user experience and it makes for a better sample since I don’t think there are that many out there for advance attached property scenarios. When you use have an attached property it will not be displayed in the property browser until you create an IExtenderProvider and implement the CanExtend method like the following: bool IExtenderProvider .CanExtend( object extendee) { return (extendee is Activity ) && ((( Activity )extendee).Parent is Switch ); } Along with the CanExtend method you also need to implement methods used for getting and setting the value of the property. The naming convention that must be followed is the “Get” / “Set” followed by the name of the property. For the switch activity I have the following: [ TypeConverter ( typeof ( ActivityBindTypeConverter ))] [ CategoryAttribute ( "Switch" ), ] [ DescriptionAttribute ( "If any of the values in Cases equals the Read More...
|
-
If you have used a custom type for an activity / workflow property you have probably ran into a few issues. You might have had problems trying to get it serialized correctly or to be able to set the value in the property browser. With this post I will try and shed some light on some of the basics. I will be working with the following custom type: [ Serializable ()] public class MyType { string paramOne; string paramTwo; public MyType( string paramOne, string paramTwo) { ParamOne = paramOne; ParamTwo = paramTwo; } public string ParamOne { get { return paramOne; } set { paramOne = value ; } } public string ParamTwo { get { return paramTwo; } set { paramTwo = value ; } } } The default workflow serialization works pretty good for types that have a default constructor. However, if your type is like the one above, which doesn’t, you aren’t going to get what you expect is you use the activity in a code only workflow. If the property has a default value other than null in the designer.cs file you will see something like the following: this .activity11.MyTypeProperty = (( MyType )(resources.GetObject( "activity11.MyTypeProperty" ))); And if you are using code separation it will look like the following: < ns0:Activity1 x:Name = " activity11 " > < ns0:Activity1.MyTypeProperty > < ns0:MyType ParamTwo = "" ParamOne = "" /> </ ns0:Activity1.MyTypeProperty > </ ns0:Activity1 > The code separation version looks good, but when you do anything that causes deserialization, Read More...
|
-
The InvokeWorkflowActivity that ships with WF requires you to set the type of the target workflow at design time. If you won’t know which workflow to invoke until runtime you need to write a custom activity. To invoke a workflow need to use the IStartWorkflow service that you can get from the ActivityExecutionContext , like the following: IStartWorkflow startWorkflow = executionContext.GetService( typeof ( IStartWorkflow )) as IStartWorkflow ; Guid instanceId = startWorkflow.StartWorkflow( this .TargetWorkflow, this .Parameters); Since the parameters won’t be known until runtime you can’t use the WorkflowParameterBindingsCollection because you wouldn’t be able to change in at runtime. Instead I have have a parameters property that is type Dictionary < string , object >. Read More...
|
-
When start another process from your workflow you can’t just not return from the Execute method until the process completes. This would block the entire workflow from receiving any other events and would hold onto the thread. Instead you need to use a queue to get notification when the process completes. Read More...
|
-
Sometime you might want to create an input form for your user to set properties on your custom activity. Unfortunately when you set the properties directly on the activity from the input form the values don’t always get reflected on your activity. To resolve this you need to set the value on the PropertyDescriptor for the property instead, like the following: PropertyDescriptor firstPropDescr = TypeDescriptor .GetProperties( this .activity)[ "FirstName" ]; firstPropDescr.SetValue( this .activity, txtFirstName.Text); Below is a link to a sample employee activity that when you double click in it a input form pops up to enter the first and last name. Clicking the OK button sets the values on the activity. Read More...
|
-
Sometimes you need to send data to a workflow from the host. To do this you need create an interface that is decorated with the ExternalDataExchange attribute and contains an event delegate like the following: [ ExternalDataExchange ] public interface IMyService { event EventHandler < CompletedEventArgs > Completed; } In your workflow add a HandleExternalEventActivity and set its InterfaceType to the interface that contains the event delegate. Next select the EventName for the event that you want to handle. To raise the event from the host you need to implement the interface like the following: public class MyService : IMyService { public void RaiseEvent( CompletedEventArgs args) { EventHandler < CompletedEventArgs > completed = this .Completed; if (completed != null ) completed( null , args); } public event EventHandler < CompletedEventArgs > Completed; } Then after creating the workflow runtime you need to add your custom service to the ExternalDataExchangeService and it needs to be added to the workflow runtime. ExternalDataExchangeService dataExchange = new ExternalDataExchangeService (); workflowRuntime.AddService(dataExchange); MyService myService = new MyService (); dataExchange.AddService(myService); Below is a link to a simple sample that just traces out the string that is passed into the workflow. Read More...
|
-
If you work with XAML activation from time to time and like being able to debug your workflow using a console application you should install these templates. However, you don’t like having to modify the default console application template each time. I created sequential and state machine console application project templates for both Visual Basic and C#. This posting is provided "AS IS" with no warranties, and confers no rights. Read More...
|
-
When you are working with ASP.NET you may have the need to persistence and / or tracking. I have put together two examples, one with shared databases and the other with separate, and included the command scripts to create the databases for you. The sample is written using Windows Workflow Foundation Beta 2.2 and will not work on prior versions. When you run the project you will start on Default.aspx. If there are no existing orders that have not been completed you are redirected to Order.aspx. If there are any existing orders there will be a link for each existing order. Click on the link to start processing the order from its current state. You can click on the enabled button to move the order through the order process. This posting is provided "AS IS" with no warranties, and confers no rights. Read More...
|
-
When you are working with ASP.NET you may have the need to persistence and / or tracking. I have put together two examples, one with shared databases and the other with separate, and included the command scripts to create the databases for you. The sample is written using Windows Workflow Foundation Beta 2.2. When you run the project you will start on Default.aspx. If there are no existing orders that have not been completed you are redirected to Order.aspx. If there are any existing orders there will be a link for each existing order. Click on the link to start processing the order from its current state. You can click on the enabled button to move the order through the order process. This posting is provided "AS IS" with no warranties, and confers no rights. Read More...
|
-
If you want to use XAML activation in ASP.NET you will need to be using Windows Workflow Foundation Beta 2.2, that can be found here . The reason for this is that although XAML activation works in most cases with Beta 2 it isn’t officially supported in that build because it was added as a feature at the last minute and was not fully test yet. Below is a sample that uses XAML activation to start a StateMachineWorkflow in ASP.NET. This posting is provided "AS IS" with no warranties, and confers no rights. Read More...
|
-
You could use a SynchronizationScope Activity, but this would block execution all together in the other branches since the thread is locked until the activity is done executing. If that is not the behavior you are looking for here are two options. First, WaitFor, will block the branch that it is in until a selected activity in another branch is Closed or Executing. With this activity in the execute method you find out the execution status for the activity you are waiting for and if it is not status you subscribe for the StatusChanged event. Once the activity changes to the correct status the WaitFor is closed and the next child in that branch will execute. protected override ActivityExecutionStatus Execute( ActivityExecutionContext context) { ActivityExecutionStatus status; Activity activity = GetExecutableActivity( this .Activity); switch (activity.ExecutionStatus) { case ActivityExecutionStatus .Executing: if ( this .Status == "Closed" ) { activity.StatusChanged += this .OnStatusChangeHandler; status = ActivityExecutionStatus .Executing; } else { status = ActivityExecutionStatus .Closed; } break ; case ActivityExecutionStatus .Closed: status = ActivityExecutionStatus .Closed; break ; default : activity.StatusChanged += this .OnStatusChangeHandler; status = ActivityExecutionStatus .Executing; break ; } return status; } The other, SynchronizeActivity, you put one or more, must be equal, in each branch. When the activity executes is checks the other synchronize activities at the Read More...
|
|
|
|