Task 5: Create a Tracking Profile

Download sample

Tracking profiles are used to control the type of tracking information that the Windows Workflow Foundation runtime engine generates. By default, tracking information is saved for every workflow and activity event when you use a default profile.

In this task, you create a custom tracking profile that tracks all the workflow events and activity events, but only for the CodeActivity activities. Any other activities in the workflow do not generate any tracking information when this profile is used.

Note

Although you are encouraged to follow the exercises in a linear manner, it is not required. You can start this exercise by opening the sample project and proceeding to the steps in the following section.

To import the namespaces

  1. In the Program source file, add the following directives to import the types that you must have for tracking profiles.

    using System.IO;
    using System.Globalization;
    using System.Workflow.ComponentModel;
    using System.Workflow.Activities;
    

To create the tracking profile

  1. In the Program class of your project, create a static method named CreateTrackingProfile.

    Private Shared Sub CreateTrackingProfile()
    End Sub
    
    static void CreateTrackingProfile()
    {
    }
    
  2. In the CreateTrackingProfile method that you created in step 1, create a TrackingProfile object named profile and an ActivityTrackPoint object named trackPoint. Additionally, set the Version property of the TrackingProfile object equal to a new instance of a Version object, passing the string "1.0.0.0" as a parameter to the constructor.

    TrackingProfile profile = new TrackingProfile();
    ActivityTrackPoint trackPoint = new ActivityTrackPoint();
    profile.Version = new Version("1.0.0.0");
    
  3. Create an ActivityTrackingLocation object named location, passing in the Type of the CodeActivity activity as a parameter to the constructor.

    // track CodeActivity activities only
    ActivityTrackingLocation location = new ActivityTrackingLocation
        (typeof(CodeActivity));
    
  4. Enumerate through the values in the ActivityExecutionStatus enumerated data type, and add those values to the ExecutionStatusEvents collection that is defined in the ActivityTrackingLocation object.

    // add all activity tracking events
    foreach (ActivityExecutionStatus s in
        Enum.GetValues(typeof(ActivityExecutionStatus)))
    {
        location.ExecutionStatusEvents.Add(s);
    }
    
  5. Add the ActivityTrackingLocation object to the MatchingLocations collection that is defined in the ActivityTrackPoint object.

  6. Add the ActivityTrackPoint object to the ActivityTrackPoints collection that is defined in the TrackingProfile object.

    trackPoint.MatchingLocations.Add(location);
    profile.ActivityTrackPoints.Add(trackPoint);
    
  7. Create a new WorkflowTrackPoint object named wtp and a WorkflowTrackingLocation object named wtl.

    WorkflowTrackPoint wtp = new WorkflowTrackPoint();
    WorkflowTrackingLocation wtl = new WorkflowTrackingLocation();
    
  8. Enumerate through the TrackingWorkflowEvent enumerated data type, and add each value to the Events collection that is defined in the WorkflowTrackingLocation object.

    // add all workflow tracking events
    foreach (TrackingWorkflowEvent s in
        Enum.GetValues(typeof(TrackingWorkflowEvent)))
    {
        wtl.Events.Add(s);
    }
    
  9. Set the MatchingLocation property that is defined in the WorkflowTrackPoint object to the WorkflowTrackingLocation object.

  10. Add the WorkflowTrackPoint object to the WorkflowTrackPoints collection that is defined in the TrackingProfile object.

    wtp.MatchingLocation = wtl;
    profile.WorkflowTrackPoints.Add(wtp);
    
  11. Create a new TrackingProfileSerializer object named serializer and a StringWriter object named writer.

    // serialize tracking profile and save to SQL
    TrackingProfileSerializer serializer = new TrackingProfileSerializer();
    StringWriter writer = new StringWriter(new StringBuilder(),
        CultureInfo.InvariantCulture);
    
  12. Serialize the TrackingProfile object by calling the Serialize method that is defined in the TrackingProfileSerializer class.

    Pass the StringWriter and TrackingProfile objects as parameters to that method.

    serializer.Serialize(writer, profile);
    
  13. Call the InsertTrackingProfile method, passing writer.ToString() as a parameter to that method.

    Note

    You create the InsertTrackingProfile method in the next procedure.

    InsertTrackingProfile(writer.ToString());
    
  14. In the Main method of the Program class, call the CreateTrackingProfile method you just created. This method should be called before you create the WorkflowRuntime object.

    CreateTrackingProfile();
    

To save the tracking profile to a SQL database

  1. In the Program class of your project, create a new static method named InsertTrackingProfile that takes a String named profile as a parameter.

    Private Shared Sub InsertTrackingProfile(ByVal profile As String)
    End Sub
    
    static void InsertTrackingProfile(string profile)
    {
    }
    
  2. In the InsertTrackingProfile method, create a new SqlCommand object named cmd.

    SqlCommand cmd = new SqlCommand();
    
  3. Using the SqlCommand object that you created in the previous step, set the CommandType property to CommandType.StoredProcedure, set the CommandText property to "dbo.UpdateTrackingProfile".

  4. Create a new SqlConnection object, passing Program.connectionString as a parameter to the constructor, and assign this object to the Connection property that is defined in the SqlCommand object.

    cmd.CommandType = CommandType.StoredProcedure;
    cmd.CommandText = "dbo.UpdateTrackingProfile";
    cmd.Connection = new SqlConnection(Program.connectionString);
    
  5. Create a new try block and put the code for steps 6 through 15 in that block.

  6. Create a new SqlParameter object named typFullName, and set its properties as shown in the following table.

    Property Name Property Value

    ParameterName

    "@TypeFullName"

    SqlDbType

    SqlDbType.NVarChar

    SqlValue

    typeof(Microsoft.Samples.Workflow.Tutorials.Hosting.HostingWorkflows).ToString();

  7. Add the SqlParameter object to the Parameters collection that is defined in the SqlCommand object.

    Your code for the typFullName object appears similar to the following code.

    SqlParameter typFullName = new SqlParameter();
    typFullName.ParameterName = "@TypeFullName";
    typFullName.SqlDbType = SqlDbType.NVarChar;
    typFullName.SqlValue = typeof(HostingWorkflows).ToString();
    cmd.Parameters.Add(typFullName);
    
  8. Create a new SqlParameter object named assemblyFullName, and set its properties as outlined in the following table.

    Property Name Property Value

    ParameterName

    "@AssemblyFullName"

    SqlDbType

    SqlDbType.NVarChar

    SqlValue

    typeof(Microsoft.Samples.Workflow.Tutorials.Hosting.HostingWorkflows).Assembly.FullName

  9. Add the SqlParameter object to the Parameters collection that is defined in the SqlCommand object.

    Your code for the assemblyFullName object appears similar to the following code.

    SqlParameter assemblyFullName = new SqlParameter();
    assemblyFullName.ParameterName = "@AssemblyFullName";
    assemblyFullName.SqlDbType = SqlDbType.NVarChar;
    assemblyFullName.SqlValue = typeof(HostingWorkflows).Assembly.FullName;
    cmd.Parameters.Add(assemblyFullName);
    
  10. Create a new SqlParameter object named versionId, and set its properties as shown in the following table.

    Property Name Property Value

    ParameterName

    "@Version"

    SqlDbType

    SqlDbType.VarChar

    SqlValue

    "1.0.0.0"

  11. Add the SqlParameter object to the Parameters collection that is defined in the SqlCommand object.

    Your code for the versionId object appears similar to the following code.

    SqlParameter versionId = new SqlParameter();
    versionId.ParameterName = "@Version";
    versionId.SqlDbType = SqlDbType.VarChar;
    versionId.SqlValue = "1.0.0.0";
    cmd.Parameters.Add(versionId);
    
  12. Create a new SqlParameter object named trackingProfile, and set its properties as shown in the following table.

    Property Name Property Value

    ParameterName

    "@TrackingProfileXml"

    SqlDbType

    SqlDbType.NVarChar

    SqlValue

    profile

  13. Add the SqlParameter to the Parameters collection that is defined in the SqlCommand object.

    Your code for the trackingProfile object appears similar to the following code.

    SqlParameter trackingProfile = new SqlParameter();
    trackingProfile.ParameterName = "@TrackingProfileXml";
    trackingProfile.SqlDbType = SqlDbType.NVarChar;
    trackingProfile.SqlValue = profile;
    cmd.Parameters.Add(trackingProfile);
    
  14. Call the Open method that is defined in the Connection property of the SqlCommand object.

  15. Call the ExecuteNonQuery method that is defined in the SqlCommand object to run the stored procedure and save your tracking profile.

    cmd.Connection.Open();
    cmd.ExecuteNonQuery();
    
  16. Create a new catch block for the SqlException exception following the try block that you created in steps 5 through 15.

  17. In the catch block, use the WriteLine method to display the Message property that is defined in the SqlException object.

    Additionally, add a message that explains the steps that are required to update the tracking profile with a new version number whenever the tracking profile is changed.

    catch (SqlException e)
    {
        Console.WriteLine(e.Message);
        Console.WriteLine("The Tracking Profile was not inserted. " +
            "if you want to add a new Tracking Profile, modify the version " +
            "string in the profile by specifying a higher version number.");
        return;
    }
    
  18. Create a finally block, and call the Close method followed by the Dispose method defined in the Connection property of the SqlCommand object.

    finally
    {
        if ((null != cmd) && (null != cmd.Connection) &&
            (ConnectionState.Closed != cmd.Connection.State))
        {
            cmd.Connection.Close();
            cmd.Connection.Dispose();
        }
    }
    
  19. Build your project and run it.

    Your output appears similar to the following illustration.

    Output after finishing Task 5

Compiling the Code

For information about compiling your code, see Compiling the Code.

For a completed tutorial, see Completed Windows Workflow Foundation Runtime Hosting Tutorial.

See Also

Reference

System.Workflow.Runtime.Tracking
TrackingProfile
ActivityTrackPoint
ActivityExecutionStatus
ActivityTrackingLocation
WorkflowTrackPoint
WorkflowTrackingLocation
TrackingProfileSerializer

Concepts

Creating Custom Tracking Services
Creating and Using Tracking Profiles

Other Resources

Simple Tracking Example
Query Using SQLTrackingService
Tracking Using User Track Points
EventArgs Tracking Sample
ConsoleTrackingService Sample

Copyright © 2007 by Microsoft Corporation. All rights reserved.
Last Published: 2010-03-04