I recently did a blog post describing how to enable the jQuery UI drag effects. In this post I showed how to get the draggable effect to work on an iPad. While that works just fine it isn’t the end of the story. Microsoft has shipped Windows 8 and Internet Explorer 10 and the jQuery UI draggable effect doesn’t work there as is.
The solution
Fortunately the solution is a lot simpler and doesn’t require an additional plug-in. It turns out that Internet Explorer 10 has quite a good support for pointer and gesture events. What we need to do is take control of the action IE10 performs on touch. By default the browser takes care of things and in this case we don’t want that and take control ourselves using jQuery UI.
It turns out this is rather simple. There is an IE10 specific CSS settings called -ms-touch-action. Setting its value to 'none' is all we need to do. This will suppress the default IE10 behavior and pass the gestures on to the jQuery event handler.
1: $("#draggable").css('-ms-touch-action', 'none');
Try for yourself
I have enhanced my small demo page here. You can toggle the support for touch events using the button to try both with and without support for touch.
Enjoy!
One of the really important new features in Windows Workflow Foundation 4.5 is the capability to version workflows and workflow instances. You get to choose what you want to do, either keep running existing instances with their original workflow definition or upgrade them to the latest workflow definition.
In the previous blog post I described how to upgrade existing workflow instances to run with the last version. However there are cases where that is not what you want, instead you want to deploy multiple version of the same workflow side by side and use the original version for each instance. For example if your business contract conditions change it makes sense to keep the older workflow instances with the original workflow definition and start new new workflows with the new definition.
The basic steps
- Create your initial workflow definition.
- Start one or more instances using this workflow definition.
- Save the original workflow definition so existing instances can keep using their original definition.
- Make some changes to the workflow definition.
- Start one or more instances using the new workflow definition.
Create your initial workflow definition
This is the simple step as anyone that has been using Windows Workflow Foundation 4 has already been doing this. For this example I am using a real simple workflow service that returns the workflow version. The workflow keeps on looping around so you can call the same instance as often as you want.
Just like before I am using a WorkflowIdentity with a version of 1.0, this time defined in the WorkflowService.

Start one or more instances using this workflow definition
Again no big deal here, just call the workflow service.

Save the original workflow definition so existing instances can keep using their original definition
This is the new part. In the previous post we upgraded the workflow instances, in this case we are going to keep the original workflow 1.0 definition available.
First create the special App_Code ASP.NET folder. Inside this folder create another folder with the same name as the workflow service, TheService in this case. Finally drop a copy of the original workflow definition in this folder. The actual XAMLX file name is not important, in this case I renamed it to TheService_v1.xamlx so I can keep multiple versions as needed.
Make some changes to the workflow definition
The change in this case is trivial but you can do whatever you want. First I updated the WorkflowIdentity to reflect a Version of 2.0. Next I updated the return from the WCF request to show that this is an instance of workflow version 2.

Start one or more instances using the new workflow definition
Now we can update the client to call the previously saved workflow instance with the original version as well as a new instance with the updated workflow definition.

The cool thing is that the WorkflowServicehost keeps track of which workflow definition to use based on the workflow version. So all we need to do is make sure each workflow definition has a unique version. In fact the WorkflowServicehost will enforce this. If you try and run with two workflow definition with the same identity you will see an InvalidOperationException with a message like:
WorkflowService with (TheWorkflow; Version=1.0) DefinitionIdentity already exists.
Enjoy!
One of the really important new features in Windows Workflow Foundation 4.5 is the capability to version workflows and workflow instances. You get to choose what you want to do, either keep running existing instances with their original workflow definition or upgrade them to the latest workflow definition.
What should you do, upgrade exiting instances or run multiple definitions side by side?
Both the upgrade to latest and keep running with the original definition make sense in different scenarios. If you find a bug in your workflow definition the update scenario is probably what you are looking for. However if your business contract conditions change it makes sense to keep the older workflow instances with the original workflow definition and start new new workflows with the new definition. Both make sense, it’s just a matter of the requirements.
In this blog post I am going to explain how to do an upgrade of an existing workflow instance. In a future blog post I will go into side by side execution.
The basic steps
When upgrading a workflow instance we are always concerned with the following basic steps”
- Create your initial workflow definition.
- Start one or more instances using the this workflow definition.
- Prepare the original workflow definition for update.
- Make some changes to the workflow definition.
- Create an update map between the original workflow definition and the new one.
- Update exiting workflow instances to reflect the new workflow definition.
Create your initial workflow definition
This is the simple step as anyone that has been using Windows Workflow Foundation 4 has already been doing this. For this example I am using a real simple workflow that prints the version number it was started with and the current version.
One thing that is new here is associating a version with this workflow. When I create an instance of the WorkflowApplication I am using a WorkflowIdentity with a version of 1.0.
1: private static WorkflowApplication CreateWorkflowApplication()
2: {
3: var identity = new WorkflowIdentity
4: {
5: Version = new Version(1, 0)
6: };
7:
8: var workflow = new TheWorkflow();
9: var app = new WorkflowApplication(workflow, identity);
10: app.InstanceStore = CreateSqlWorkflowInstanceStore();
11: app.PersistableIdle = e => PersistableIdleAction.Persist;
12: app.OnUnhandledException = e =>
13: {
14: Console.WriteLine(e.UnhandledException.Message);
15: return UnhandledExceptionAction.Abort;
16: };
17:
18: return app;
19: }
Start one or more instances using the this workflow definition
Again no big deal here, just run the workflow application.
1: private static void StartNewWorkflow()
2: {
3: WorkflowApplication app = CreateWorkflowApplication();
4: app.Run();
5: }
Prepare the original workflow definition for update
In this step we prepare the workflow definition, the XAML file, for update using the DynamicUpdateServices.PrepareForUpdate() on an ActivityBuilder. This step adds a copy of the workflow definition in a DynamicUpdateInfo.OriginalActivityBuilder element so we can see the differences later when we are done. Right now we can use the workflow to run a workflow and everything would appear unchanged.
1: private static void PrepareWorkflowForUpdate()
2: {
3: ActivityBuilder builder = LoadWorkflowDefinition();
4: DynamicUpdateServices.PrepareForUpdate(builder);
5:
6: SaveWorkflowDefinition(builder);
7: }
8:
9: private static ActivityBuilder LoadWorkflowDefinition()
10: {
11: ActivityBuilder builder;
12: using (var xamlReader = new XamlXmlReader(FileName))
13: {
14: var builderReader = ActivityXamlServices.CreateBuilderReader(xamlReader);
15: builder = (ActivityBuilder)XamlServices.Load(builderReader);
16: }
17: return builder;
18: }
19:
20: private static void SaveWorkflowDefinition(ActivityBuilder builder)
21: {
22: using (var writer = File.CreateText(FileName))
23: {
24: var xmlWriter = new XamlXmlWriter(writer, new XamlSchemaContext());
25: using (var xamlWriter = ActivityXamlServices.CreateBuilderWriter(xmlWriter))
26: {
27: XamlServices.Save(xamlWriter, builder);
28: }
29: }
30: }
Make some changes to the workflow definition
In the workflow I am going to make a small change to reflect that it is workflow definition is version 1.1 and in the code I am going to use the same version 1.1.
If I try to resume the previously saved workflow definition this results in an VersionMismatchException.
Unhandled Exception: System.Activities.VersionMismatchException: The WorkflowIdentity ('; Version=1.0') of the loaded instance does not match the WorkflowIdentity ('; Version=1.1') of the provided workflow definition. The instance can be loaded using a different definition, or updated using Dynamic Update.
Create an update map between the original workflow definition and the new one
In order to upgrade the saved workflow instance we first need to create an update map. In this step we use the DynamicUpdateServices.CreateUpdateMap() function to create a map of the changes made since DynamicUpdateServices.PrepareForUpdate() was called. There is no way to create an update map based on anything else then the internal DynamicUpdateInfo. This means if you forgot to call DynamicUpdateServices.PrepareForUpdate() and save the workflow but instead just started making changes you are going to experience some problems. My first expectation was I could create an update map by comparing and older version of the workflow, for example from the TFS history, but that just isn’t possible using DynamicUpdateServices.CreateUpdateMap(). One solution here might be to use DynamicUpdateInfo.SetOriginalActivityBuilder().
Another slightly surprising thing is there is no native save functionality for a DynamicUpdateMap. In this case I am using a DataContractSerializer to save the update map in a way I can load it again.
1: private static void CreateWorkflowUpdateMap()
2: {
3: ActivityBuilder builder = LoadWorkflowDefinition();
4: DynamicUpdateMap updateMap = DynamicUpdateServices.CreateUpdateMap(builder);
5:
6: SaveUpdateMap(updateMap);
7: }
8:
9: private static void SaveUpdateMap(DynamicUpdateMap updateMap)
10: {
11: var fileName = Path.ChangeExtension(FileName, "map");
12: var serializer = new DataContractSerializer(typeof(DynamicUpdateMap));
13: using (var stream = File.Open(fileName, FileMode.Create))
14: {
15: serializer.WriteObject(stream, updateMap);
16: }
17: }
Update exiting workflow instances to reflect the new workflow definition
With the update map in place we can finally go and update workflow instances saved in the instance store. The code isn’t hard, just load the workflow instance using WorkflowApplication.Load() passing in the DynamicUpdateMap to use, make sure to unload the workflow again and you are good to go.
As you can see the workflow state still contains the reference to version 1.0 from when it started but the current workflow definition used is 1.1.
Of course there are changes that might be impossible to make, for example deleting the currently executing activity would leave the workflow in an invalid state. Using the WorkflowApplicationInstance.CanApplyUpdate() function you can check if an update is actually possible before doing so.
Enjoy!