Ode to Solution Explorer expand and collapse

July 12, 2007 by bukovics

I’ve been using various versions of Visual Studio for a very, very long time. As each new version is released by Microsoft, I look in vain for the one feature that I really want. I want the ability to expand or collapse all projects within the Solution Explorer! Some of my solutions contain 100 or so individual projects. Do you know what a pain it is to manually collapse 100 projects individually? Why is it so difficult to implement this seemingly simple feature? Maybe I’m the only one who would like this, but I think not.

Orcas Beta 1

June 23, 2007 by bukovics

I realize this isn’t exactly the latest ground-break news, but the Orcas beta 1 is now available here.  I’ve downloaded and installed the beta but haven’t had the chance to really get into it yet.  I’m looking forward to trying out some of the new WF features, including the WCF/WF integration.

Persistence and Tracking together

May 23, 2007 by bukovics

A reader of my workflow book recently wrote me with a question about the standard persistence and tracking services. Their question concerned how to use both of these standard services at the same time. Specifically, they wanted to know how to specify two different database connection strings in the App.config.

There’s really two separate questions there. First, how do you specify two different connection strings for the services, presumably pointing to two different databases. Second, is that how you should use these two services together?

To answer the first question, you can specify the connection string in either the CommonParameters section of the App.Config, or inline as an attribute of the service itself.

For example, here is an App.Config that provides two different database connection strings, one for each service:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="WorkflowRuntime"
      type="System.Workflow.Runtime.Configuration.WorkflowRuntimeSection,
        System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral,
        PublicKeyToken=31bf3856ad364e35" />
  </configSections>
  <WorkflowRuntime>
    <Services>
      <add type="System.Workflow.Runtime.Tracking.SqlTrackingService,
        System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral,
        PublicKeyToken=31bf3856ad364e35"
           ConnectionString="Initial Catalog=WorkflowTracking;
             Data Source=localhostSQLEXPRESS;
             Integrated Security=SSPI;" />
      <add type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService,
        System.Workflow.Runtime, Version=3.0.00000.0,
        Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        UnloadOnIdle="true" LoadIntervalSeconds="5"
          ConnectionString="Initial Catalog=WorkflowPersistence;
             Data Source=localhostSQLEXPRESS;
             Integrated Security=SSPI;" />
    </Services>
  </WorkflowRuntime>
</configuration>

That answers the first question. However, that’s not the recommended way to use the standard persistence and tracking services at the same time. Instead, you should use the same database for persistence and tracking. One database means one connection string. And WF provides a special service named SharedConnectionWorkflowCommitWorkBatchService that you should also load. This service is optimized for use with the standard persistence and tracking services. It uses the same database connection for both services, avoiding the use of MSDTC that would otherwise be needed.

Here’s a revised App.config that loads the special commit work batch service and uses the same database for persistence and tracking. Since a single connection string is used for both services, it is moved back to the CommonParameters section of the App.config.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="WorkflowRuntime"
      type="System.Workflow.Runtime.Configuration.WorkflowRuntimeSection,
        System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral,
        PublicKeyToken=31bf3856ad364e35" />
  </configSections>
  <WorkflowRuntime>
    <CommonParameters>
      <add name="ConnectionString"
           value="Initial Catalog=Workflow;
             Data Source=localhostSQLEXPRESS;
             Integrated Security=SSPI;" />
    </CommonParameters>
    <Services>
      <add type="System.Workflow.Runtime.Hosting.SharedConnectionWorkflowCommitWorkBatchService,
            System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral,
            PublicKeyToken=31bf3856ad364e35" />
      <add type="System.Workflow.Runtime.Tracking.SqlTrackingService,
        System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral,
        PublicKeyToken=31bf3856ad364e35" />
      <add type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService,
        System.Workflow.Runtime, Version=3.0.00000.0,
        Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        UnloadOnIdle="true" LoadIntervalSeconds="5" />
    </Services>
  </WorkflowRuntime>
</configuration>

Exposing Nullable fields to .NET 1.1 Web Service Clients

March 23, 2007 by bukovics

I recently ran into an interesting problem exposing a set of WCF services to .NET 1.1 web service clients. I was able to correctly generate the web service proxy class using the 1.1 version of the wsdl.exe utility. However at runtime, I ran into Xml serialization errors when I tried to access my WCF service from a .NET 1.1 web service client.

The problem was that the service method was returning an object that contain several nullable properties (System.Nullable<>). Specifically, they were nullable DateTime fields that were defined similar to this in my .NET 3.0 source:

private System.DateTime? _myTimestamp;
[DataMember]
public System.DateTime? MyTimestamp
{
get { return this._myTimestamp; }
set { this._myTimestamp= value; }
}

In a .NET 3.0 web service client, this isn’t a problem since the wsdl.exe utility generates the web service proxy class using System.Nullable<>. But this is a problem with .NET 1.1 clients since nullable types are not supported in .NET 1.1. The generated proxy class actually included two fields:

public DateTime MyTimestamp;
public bool MyTimestampSpecified;

The second xxxxSpecified field is generated when there is the possibility that the value for the field may not be transmitted. The xxxSpecified field is normally set to true, but it should be set to false for one of these nullable fields when it contains null. So the generated proxy class at least looks like it should support the concept of nullable fields. But it chokes when it actually tries to handle a DateTime that doesn’t contain a real value (a System.Nullable<> field without a real value in the .NET 3.0 world).

Although I searched for a solution to this problem, I didn’t find a direct answer. I finally stumbled upon the EmitDefaultValue property of the DataMember attribute. By default, EmitDefaultValue is true, meaning that even if a field contains the default value for that data type, it is transmitted. This means that an Int32 will transmit a value of zero (it’s default value) and so on. My System.Nullable<DateTime> field had a default value of null so null was transmitted. By setting EmitDefaultValue to false for my nullable fields, my problems were solved. My DateTime property now looks like this:

[DataMember(EmitDefaultValue = false)]
public System.DateTime? MyTimestamp
{
get { return this._myTimestamp; }
set { this._myTimestamp= value; }
}

Now when this field has a default value of null, it is not emitted to the caller. However, the MyTimestampSpecified field is correctly set to false in this case, indicating that the underlying field doesn’t contain a real value. All is good again and I can access my WCF services from .NET 1.1 and 3.0 web service clients.

I don’t know if this is the best approach to this problem, but so far, it does seem to work for me.

Sample Workflow Persistence chapter

March 19, 2007 by bukovics

Apress has made Chapter 8 of my Pro WF book available for download in PDF format. This is the chapter that covers workflow persistence. You can obtain this sample chapter from the Apress page for this book, or directly from this site.

They’re Here!

February 14, 2007 by bukovics

The official ship date of my WF book is next Monday (Feb 19), so I’ve been eagerly awaiting arrival of my copies of the book. The wait is now finally over. My wife called this afternoon to tell me that there were two rather heavy boxes that UPS dropped off in our driveway. As soon as I got home (yes, I did work the full day), I immediately opened the boxes to see the result of my almost-year-long project.

When you’re working on the book, writing, testing, editing and reviewing, you do get a sense of accomplishment. But it’s much different to actually hold a physical copy of the book in your own two hands. It looks great!

I checked Amazon and B&N, and it looks like it’s now in stock at both outlets. I’ll have to make a trip to the local B&N and see if they have it on the shelf.

XAML Workflow Schema

February 1, 2007 by bukovics

As I demonstrated in chapter 16 of my WF book, one of the authoring modes that you can use to define the workflow model is the no-code (markup-only) mode. Using this authoring mode, you define the workflow model in an XML file using XAML syntax.

If you try to do this manually in Visual Studio without the aid of a designer, it is fairly tedious and it can be error prone since there’s no Intellisense support. At least until now. Microsoft has now released a workflow XAML schema that makes this process a little easier.

After downloading the file, you unzip it into the default location:

%ProgramFiles%\Microsoft Visual Studio 8\Xml\Schemas

Once the schema file (XamlWorkflow2006.xsd) is installed into the correct directory, Visual Studio will provide Intellisense within it’s XML editor when you edit workflow markup files (.xoml).

Keep in mind that this won’t work for any custom workflow types that you’ve defined and wish to reference. This schema only has knowledge of the standard workflow types provided by MS. However, if there are types that you frequently use, you can modify this schema file yourself in order to provide Intellisense.

New version of WFPad

January 24, 2007 by bukovics

I just noticed that Mark Schmidt has a new version of WFPad available. If you’ve never tried WFPad, you should download it immediately and give it a try. It is the WF equivalent of XamlPad (for WPF). It hosts the WF designers to visually let you work with workflow markup files. But it has two features that I really like:

  1. It shows you the workflow model in the WF designer and as markup (xaml) in two separate, sync-able windows. This is a great way to learn WF markup. You can use the designer to change the WF model and then view the results as markup.
  2. It lets you load and view an existing workflow from a .xoml file OR from an assembly (exe, dll). This is a great way to gain visibility into your compiled workflows without warming up Visual Studio.

In chapter 17 of my WF book, I present a custom designer that allows you to create and maintain markup-only (no-code) workflows. While I obviously recommend taking a look at my designer, I must admit that there is much to like in WFPad as well.

Atlanta code camp

January 21, 2007 by bukovics

I attended the Atlanta code camp on Saturday and thoroughly enjoyed it. The organizers did a great job of bringing in some interesting speakers and providing a good variety of subject matter. Now that my WF book is all but complete, it was nice to have a free weekend to attend something like this.

I will definitely plan on attending this event again next year. Perhaps next year I’ll try to present something on WF.

Welcome

January 18, 2007 by bukovics

I completed my first book .NET 2.0 Interoperability Recipes back in March of 2006. At the time, I planned on posting to this blog with interesting information related to .NET interop. However, instead, I immediately embarked on another book, ProWF: Windows Workflow in .NET 3.0. Now that this book is in the final stages (available Feb 19, 2007), I’m ready to give this blog a go once again.

The focus of this blog will now include Windows Workflow Foundation (WF) as well as .NET interop.