Happy and honored to be going to TechEd Hong Kong again this year

I have to say – TechEd Hong Kong has been one of the best conferences I’ve ever been to.  The hospitality shown by the people from Microsoft is really second to none.  Hong Kong is a beautiful city to visit and the people (not just from Microsoft) were very accomodating.


 


This year, not only do I get to hang out with my old friend Bob Beauchemin – I also get to bring Shannon with me this year. I am sure we’ll have a blast.


And – I get to do talks on WF/WCF (one of my current favorite topics). BAM (always one of my favorite topics) – and its integration in BizTalk Server R2. Plus – I get to do two talks on new features in Orcas and ASP.NET!

Should be a great week in Hong Kong if you are in that area of the world – sign up!

On my way to Norway

To teach a Windows Workflow Foundation 5-day course.  Everyone says it will be beautiful.

 BTW – I don’t plan on updating the Atlas Workflow Designer until they release the next version of Atlas – read Biertand Roy’s blog about why –

Link to Atlas and more  – they are about to change from closures to prototypes.  This will be a great chance for me to re-architect the whole thing.  The next big feature will be HTML based rule editing.

Yes – I still love Atlas

I have to give kudos to the ASP.NET Team.  I really love the Atlas programming model.  I’d like to tell you that my Atlas based Workflow Designer is ready – but it isn’t.  But – I did re-build the WF WorkflowMonitor sample application tonight as an ASP.NET Atlas based application (oh – and I also did is as a non-Atlas based ASP.NET application for those of you that are still suck doing flicker-based PostBacks ;-) ).


What is Workflow Monitor?  Well the Windows Workflow Foundation runtime will take advantage of a TrackingService  – if one is found inside of the WF runtime.  The runtime ships with a SqlTrackingService – which by default tracks all Activity events.  See my post on the WF forums if you have never gotten tracking up and running for the steps I think people should go through to get the zen of WF tracking – http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=438583&SiteID=1.


One of the coolest steps is to use the Workflow Monitor sample that ships with the WF SDK.  It is a Windows Forms application that will (assuming you are using the SqlTrackingService and have added your workflow assembly as a reference or into the directory where Workflow Monitor is running) show you what has executed in terms of your Workflows.  If you set the SqlTrackingService.IsTransactional property to false, you can even see this in semi-realtime as the SqlTrackingService will write each event to the database as it happens rather than batch them (all writes are done transactionally regardless of the IsTransactional property BTW).


Why is this cool?  Well – to me it shows off one of the big features of using WF – visibility.  You can even show this to your pointy-haired bosses and they might start to see the advantage of WF.  Here is a screen shot of Workflow Monitor in action:


 



So what’s so cool here?  Well two of WF’s major features are being emphasized.  First – Visibility (sometimes referred to as Transparency – I like the simplier term).  At runtime and after runtime we can actually *see* what our processes have done.  The second major WF feature displayed is the designer re-hosting inside of another application other than Visual Studio. Although the designer really plays into visiblity – the fact that we can host the designer in any application royalty free I think is a huge bonus feature of WF.  Oh – not to mention tracking and the capabilities of the out-of-box SqlTrackingService.


So given my recent perseveration with Atlas and the WF designer I thought – wow wouldn’t that be a cool combination? Having the visibility into your WF processes for the masses – even those who don’t have the WF runtime on their machines – or those who you don’t want to have to deploy the Workflow Monitor sample (which could be made into a pretty deployable click-once application very easily).


So here we go – unlike last nights tease post – not only will I show you a Workflow Monitor application hosted in ASP.NET – I’ll post the code as well.


So here is my version of the Workflow Monitor in ASP.NET (which at the designer level borrows alot of code from the Workflow Monitor sample just to keep it consistent with what people have become used to).  First let’s look at the Atlas version.  Why an Atlas version?  Well first of all as I mentioned I think Atlas rocks.  But it rocks for a very good reason (and that reason isn’t that pointy-haired bosses know the term AJAX now and think they are so cool because of that).


Atlas and Ajax is cool because is gives the user the best browser experience possible.  Clearly the smart-client experience is going to be superior.  But if you have to go with a browser only application – why not make that application as easy as possible to use – and as nice as possible to look at.  I think AJAX browser applications do do that better than non-AJAX ones, and I think that Atlas is a great framework if you are building ASP.NET applications.


So in the spirit of cross-browser love – I am going to show you all the screen shots in Firefox.  :)


Here is my atlas/ajax based Workflow Monitor application in Firefox:


 



This is the ASP.NET Workflow Monitor in Firefox, before any workflow has been selected from the list of tracked workflows in the GridView on the right side of the page (to make this managable for more than a demo you’d want to restrict the time-frame of the query for these instances or give the use the ability to restirct the query – you can find how to do that from the Workflow Monitor sample itself).  Once I select an workflow from the list of tracked workflows on the left – I get the following (because it is using Atlas and an UpdatePanel there is no post-back flicker – only the workflow image itself is being updated:


 



Again – I have to tip my hat to the ASP.NET team on the job they did on Atlas, I never would have believed I could just write my ASP.NET page using the declarative ASP.NET model, add a few extra declarations and have a cross-browser AJAX application. But I have to say wow – they did it.  My contribution to this demo pretty much pales in comparison to theirs.


So how does this code work?  Well quite a while ago I posted about hosting the WF desinger in ASP.NET using a control and a handler to render a workflow as an pure image.  The worklow designer (WorkflowView actually) makes this option availlable as a public method.  The post I made last night about a WF Atlas based designer is also based on that code – as is this code (for honest disclosrure I borrowed much of the Workflow Monitor code directly for the worklfow drawing and use of the tracking API).


All that really happens is that each time you select a workflow from the list in the right-side GridView, a post-back is done to the server.  On the server-side some code in the page executes and retrieves the tracked workflow from the SqlTrackingService Query API (the same code that the Workflow Monitor example uses) based on its InstanceId. That information (the SqlTrackingServiceInstance)  is stored in ASP.NET session.  The HttpHandler – once it gets a request from the current session uses the SqlTrackingService instance to generate the image for the current workflow (the code from Workflow Monitor already decorated the current worklfow with special glyphs or images based on the execution status).


Just like the in Windows Forms version, this version loads the workflow into the Workflow Designer, but unlike that version which shows the results to the screen, this version captures an image (you can do this from the Workflow menu in Visual Stuiod 2005 as well when you are designing a workflow).


In the Atlas version there is no flicker and the browser app appears fairly close to Workflow Monitor.  With a Atlas timer – you could replicate the Workflow Monitor fucntionality almost completely and always hightlght and select the most recent workflow.


Again – if you are unlucky enough to be stuck doing ASP.NET without Atlas – I built a version that removes all the Atlas references and tags, and does work – just looks pretty bad since there is lots of post-backs and white screens in the browser.   You can download – either version (or hey download both versions and see the beauty of atlas – and remember you have to download and install the latest version of atlas for this to work – as well as beta 2.2 of WF) :


AtlasWorkflowMonitor.zip (697.68 KB)


NonAtlasWorkflowMonitor.zip (292.61 KB)


If you are stuck not using Atlas – this might a good time to introduce your pointy-haird boss to AJAX.  I am sure you’ll be using Atlas in a very short amount of time ;-)

Using WF to run a page-flow


There are many really great things about using workflow as the logic behind your application.  The one that really excites me is the visibility workflow gives you into what your application is doing.


 


Another great thing is that many types of applications are naturally workflows, and so using workflow for those applications is really a no-brainer.  One of the most-often cited examples is page flow in ASP.NET.   Moving a user from page to page in an ASP.NET application is really a workflow.


 


Now, until the ASP.NET team and WF team come out with something official in terms of integration, using WF as page-flow is going to be kind of ad hoc.  Here is my take on one way to do this.


 


Here are the goals I had in mind when I built this sample (which is based partly on other applications I have built already using WF and ASP.NET).


 


1)   The WF and the ASP.NET Pages should be unaware of each other.  ASP.NET shouldn’t know it is being run by a workflow, and the workflow shouldn’t know it is being called from ASP.NET.


 


2)  The ASP.NET model should be preserved.  What I mean by this is that ASP.NET pages should be written using a control-based, data-bound methodology.  I also am a big fan of ASP.NET 2.0 and all the work they have done to make building pages easier.  Some other examples of using WF with ASP.NET I’ve seen make the pages go out of the regular model.  IMO – there is a reason for the page model in ASP.NET and I wanted to try to preserve that model in my integration.  So this means using server-side controls and events, along with data-binding.


 


Here is an overview of this sample.  First – there is a state-machine based workflow.  Although a sequential workflow would work, state-machine is really more appropriate for this scenario (see Dave Green’s post here about the two different models).


 


The workflow takes as parameters an OrderedDictionary and a string.  The OrderedDictionary holds onto the real parameters.   The reason I use an OrderedDictionary is to make the ASP.NET model easier to use.  With declarative data sources in ASP.NET 2.0, generally the data source control takes care of processing the form data (and other data, like sessions or cookies) by using a ParameterCollection.  The ParameterCollection is made up of Parameter objects which are responsible for extracting data from controls, the session object, or other objects.   The data source control can then use this to actual perform CRUD operations.   The idea is that the page can be written using the normal model – and then the parameters are gathered by the data source control, and rather than have the parameters processed by the data source, the parameters are passed into the workflow.   My concept here is to let ASP.NET developers write pages using their regular model and then integrate with WF seamlessly.


 


So this could be done by using an existing datasource and extracting the parameters:


 


base._params = SqlDataSource1.SelectParameters.GetValues(HttpContext.Current, SqlDataSource1) as OrderedDictionary;


 


Or by manually packing up parameters into an OrderDictionary instance:


 


//manually create the parameters
this.Parameters = new OrderedDictionary();
this.Parameters.Add(TextBox1.ID, TextBox1.Text);
this.Parameters.Add(TextBox2.ID, TextBox2.Text);


  


The other parameter to the workflow is just a string.  This is what I call the “command”.   The concept is that the page will pass a “command” to the workflow, and then based on the way the workflow is written, the workflow will pass back to the page the next “command”.  Based on the next command value, the integration layer between the pages and the workflow will redirect to the next page.  The next page value is also based on configuration.   The idea is that the configuration mapping will control what page is next in the flow, and that the workflow will just be passing back the next “command” which will then be mapped in configuration to a page.   This keeps the workflow from knowing it is running a page flow and the page from knowing it is using a workflow.


 


After the workflow starts, it continues to live (placed in ASP.NET session) and then is invoked for the rest of the page flow.  The workflow instance then waits for communication from the host (which is really implemented in a single class called WorkflowWrapper).  These events (a custom activity based on HandleExternalEvent – generated using the wca.exe tool) also take an OrderedDictionary and a string.  The events also use correlation; this is why the external data exchange interface only needs on event.


 


 


The CallExternalMethod activity passes back to the host (through the local service implementation) a DataSet, and the “next” command.  The next command is used to redirect based on the configuration, and the DataSet is placed in ASP.NET Session.   When the next page is executed (after the redirect) the page can extract the DataSet from ASP.NET Session (all the operations of each page is actually wrapped in a BasePage class implementation).


 


 


The other interesting thing about each ASP.NET page is that none of them directly calls the workflow or handle control events.  The base page class does this.  Rather than limit the kind of controls that each derived class can use, the base class overrides OnBubbleEvent, and then just extracts the control as an IButtonControl, which means this will work with Button, LinkButton, or ImageButton (to handle other kinds of controls that post-back this method would have to be modified).


 


The local service and the event activities are separated into a separate library – as is the workflow.  To make this same example work with say a set of Windows Forms – there is just one line of code in the local service implementation that would need to be changed (the line that stores the result of the CallExternalMethod in the HttpContext.Items collection).


 


In this example – Default.aspx is the first page in the flow.  It has two text boxes, the values of which get passed to the workflow.  The next page is Page2.aspx and it gets two DataTables from the DataSet and uses it to bind a GridView and a DropDownList.    The rest of the pages just flow – there isn’t any really functionality going on with them.  If you go into the web.config – you can move pages around in the configuration and make the flow of the pages different.


 


I probably will have more to write about on this topic – so this is just the first post.  I am interested in ideas of comments anyone has on this topic, so feel free to critique my design – as I said this is just my beginning thoughts on how to use WF with ASP.NET – my next task is to create a custom datasource control for WF specifically.



aspnetwfpageflowexample.zip (127.88 KB)