Using the AJAX Workflow Monitor With .NET 3.5 Beta 2
Awhile back, Jon Flanders posted an excellent example of creating an AJAX enabled Workflow Monitor using ASP.NET AJAX 1.0. What's really cool is that you can very easily upgrade this sample to use with .NET 3.5 Beta 2 and use it without downloading the ASP.NET AJAX libraries since all of the ASP.NET AJAX goodness is rolled into the framework.
Using Windows Workflow Foundation, you can enable tracking for your application to gain visibility into your application's processing lifecycle. Just like you would add an entry in your config to persist the workflow, you also add entries in config to enable tracking.
<workflowRuntime name="WorkflowServiceHostRuntime" validateOnCreate="true" enablePerformanceCounters="true">
<services>
<add type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
connectionString="Server=(local);Database=SqlPersistenceService;Integrated Security=True"
UnLoadOnIdle="true" />
<add type="System.Workflow.Runtime.Tracking.SqlTrackingService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
connectionString="Server=(local);Database=Tracking;Integrated Security=True"/>
</services>
</workflowRuntime>
When you enable the tracking service, WF will automatically write entries into the tracking database that you specified in the config section. The AJAX Workflow Monitor sample then uses the APIs in the .NET Framework to query the tracking store and provide the UI rendering that you see in the screen shot below. The image you see is dynamically generated. This sample allows you to see the workflow instances as well as the ActivityExecutionStatus for each of its contained activities. For instance, here is a screen shot that shows a workflow that I am working on that uses the new ReceiveActivity in .NET 3.5.
There are some subtleties in the picture that you might not notice. The first is that there are checkmarks next to each of the activities that have already completed (in this case, all of them are checked). There is also an activity called "CreateTicket" that is highlighted, indicating the status that matches what I clicked in the list on the right. If you have wanted to use WF in your projects but just couldn't seem to convince your boss or teammates, this is one of those demos that gets everyone excited about WF. You can gain real visibility into your projects and see how your complex business logic is functioning. Just run your workflow and then pull up the Workflow Monitor to show where the workflow is at.
To use this with .NET 3.5 Beta 2, simply download the source and open the solution in Visual Studio 2008 Beta 2. In the web site AtlasWebSite1, upgrade your web.config to the following:
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
<appSettings/>
<connectionStrings>
<add connectionString="server=.;database=Tracking;trusted_connection=yes" name="WFTracking"/>
</connectionStrings>
<system.web>
<compilation debug="true">
<assemblies>
<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Data.DataSetExtensions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Workflow.ComponentModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</assemblies>
</compilation>
<authentication mode="Windows"/>
<pages>
<controls>
<add namespace="WorkflowVisibilityControl" assembly="WorkflowVisibilityControl" tagPrefix="wf"/>
<add namespace="WorkflowAtlasDesigner" assembly="__code" tagPrefix="wfa"/>
<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</controls>
</pages>
<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
</httpHandlers>
<httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</httpModules>
</system.web>
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" compilerOptions="/warnaserror-" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<providerOption name="CompilerVersion" value="v3.5"/>
</compiler>
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" compilerOptions="/optioninfer+" type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<providerOption name="CompilerVersion" value="v3.5"/>
</compiler>
</compilers>
</system.codedom>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules>
<add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</modules>
<handlers>
<remove name="WebServiceHandlerFactory-Integrated"/>
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</handlers>
</system.webServer>
</configuration>
Note that you might need to update the connection strings for each of the services for your environment. I could have trimmed the config down some (removing references to LINQ since it's not used, getting rid of the asmx extension handling since there's no ASMX in this project), that's an exercise left to the reader.
There's one other subtlety to this example that you shoudl realize. The monitor needs to find your assembly in order to render the workflow image. That means that you will either need to GAC the workflow assembly or deploy it to the web site's bin directory. For simplicity in debugging, I did the latter, adding a post build step to my workflow.
copy "$(TargetDir)*.*" "C:\Users\kirke\Documents\Visual Studio 2008\Projects\AtlasWorkflowMonitor\AtlasWebSite1\Bin\"
Once the workflow monitor web project can "see" your assembly, it will be able to query the tracking store and render dynamic images of your workflow.
Comments
Anonymous
September 17, 2007
In my last post, I showed how you can use Jon Flanders's AJAX Workflow Monitor example with Visual StudioAnonymous
December 11, 2008
This post will show how to create a simple console application that executes tracking queries in WindowsAnonymous
September 08, 2015
www.masteringbiztalk.com/.../PermaLink,guid,79f45d4d-6e5a-437b-a230-d7df13ae18e7.aspx above link is not working. Can you please re upload & share the new link ?Anonymous
September 08, 2015
I don't have it anymore. The old WF3.5 designer had the ability to provide your own glyphs, which is what I used to highlight the active and completed activities. It also had the ability to save a the designer as an image. The client side ASP.NET AJAX had an UpdatePanel that would make a JavaScript call to the server, and the server-side code would create an instance of the designer and save the image to the HTTP response. There was a WF Monitor example in the .NET 3.5 SDK (msdn.microsoft.com/.../ms741706(v=vs.90).aspx) that served as the majority of the sample.