Click to Rate and Give Feedback
Related Articles
Here the author introduces SQL Server Data Services, which exposes its functionality over standard Web service interfaces.

By David Robinson (July 2008)
Here the author answers questions regarding the Entity Framework and provides an understanding of how and why it was developed.

By Elisa Flasko (July 2008)
Here we present techniques for programmatic and declarative data binding and display with Windows Presentation Foundation.

By Josh Smith (July 2008)
Systems that handle failure without losing data are elusive. Learn how to achieve systems that are both scalable and robust.

By Udi Dahan (July 2008)
More ...
Articles by this Author
Learn how to add check-in notes and check-in policy support to a Word add-in, in this fifth and final installment of an ongoing discussion.

By Brian A. Randell (Launch 2008)
Team Foundation Server provides APIs that let you create check-in notes (categorized string data) and custom check-in policy implementations. These features combine to give project administrators better control over the group development process.

By Brian A. Randell (November 2007)
Add support for work items to the Team Foundation Server version control add-in.

By Brian A. Randell (September 2007)
In this column, Brian Randell explains how to build a simple Work Item explorer and demonstrates the core operations needed to add work item support when building your own add-in.

By Brian A. Randell (April 2007)
Here Brian Randell presents everything you need to know to get started with Visual Studio 2005 Team Edition for Database Professionals.

By Brian A. Randell (February 2007)
In this new column, Brian Randell begins his long look at how to extend and enhance Visual Studio Team System.

By Brian A. Randell (January 2007)
The Express Editions of Visual Basic and SQL Server 2005 have lots of the features of the full-sized versions, but with a lot less of the overhead. Professional developer features such as full IntelliSense support, local debugger, Add Web Reference, and the improved Visual Data Tools will all be available in the Express products, so you don't have to leave your favorite features behind. In this article the author introduces you to these express editions and builds a sample app to get you started.

By Brian A. Randell (September 2004)
Microsoft is introducing a new suite of tools (code-named "Whitehorse") that will make it easier for you to design and implement systems that conform to a service-oriented architecture. Two of these tools -- the SOA Design Suite and the Class Designer -- support the graphical design of systems and components with support for code generation and support for bi-directional synchronization which lets you ensure that your diagram always represents your system design. This article introduces these tools and shows you how they'll improve your design and development efforts.

By Brian A. Randell and Rockford Lhotka (July 2004)
More ...
Popular Articles
Systems that handle failure without losing data are elusive. Learn how to achieve systems that are both scalable and robust.

By Udi Dahan (July 2008)
Here we present techniques for programmatic and declarative data binding and display with Windows Presentation Foundation.

By Josh Smith (July 2008)
With custom form regions in Outlook you can pull in data from designated data sources and truly customize your users' Outlook 2007 experience.

By Steve Fox (Launch 2008)
Jamie Laflen extols the benefits of TDD when applied to database development—and supplies some useful techniques along the way.

By Jamie Laflen (Launch 2008)
More ...
Read the Blog
There are many things called threat modeling. Rather than argue about which is "the one true way," a good practice is to consider your needs and what your skills, abilities, and schedules are, and then work with a method that's best for you. In the July 2008 issue of MSDN Magazine, ...
Read more!
Want to develop games for Xbox Live? Want to get paid for it, too? Click on over to the XNA Team Blog to learn more about their initial rollout of the XNA Creators Club for XNA Game Studio. ...
Read more!
The Microsoft Entity Data Model (EDM), based on Dr. Peter Chen's Entity Relationship (ER) model, is the driving force behind the ADO.NET Entity Framework. The EDM is also the feature that most significantly differentiates the Entity Framework from other ORM-style technologies in the marketplace. In the July 2008 issue of MSDN ...
Read more!
System.IO.File is a handy helper class for reading and writing data, but its methods support only synchronous operation. Is there an easy way to provide File’s functionality for asynchronous file I/O? In the July 2008 issue of MSDN Magazine, Stephen Toub walks through several ...
Read more!
Remember .NET Terrarium, the interactive game meant to introduce .NET development techniques? Well, the Windows SDK team has released the source code for .NET Terrarium 2.0 on CodePlex. You can read more about this release on the Windows SDK blog and at Microsoft ...
Read more!
The Enumerable class plays an important role in every LINQ query you create. Because the Enumerable class's extension methods can process many other classes—including Array and List—you can use methods of the Enumerable class not only to create LINQ queries, but also to manipulate the behavior of arrays and other data structures. In the July 2008 issue of MSDN ...
Read more!
More ...
Team System
Team Foundation Server Event Service
Brian A. Randell

Code download available at: TeamSystem2008_05.exe (177 KB)
Browse the Code Online
Microsoft built Team Foundation Server (TFS) as a collection of major and minor services including version control, work item tracking, and the EventService service. I classify EventService as a minor or, better yet, supporting service. EventService exposes a set of events that, when fired, can perform actions such as sending e-mail or making a SOAP-based Web service call.
In this column, I'll examine what's available out of the box via the Visual Studio® user interface, what events are exposed by EventService, how you can create and manage subscriptions, and how you can create your own Web service to receive and process events. While I will be using Visual Studio 2008 and TFS 2008, most of this column applies equally to TFS 2005.

Project Alerts
If you start up Visual Studio 2008 with Team Foundation Client (TFC) installed and connect to an existing team project, you'll be able to access the Team menu on the main menu bar. Once you do, you will see a menu item labeled Project Alerts. If you choose this menu item, Visual Studio will open the Project Alerts dialog, which allows you to create e-mail subscriptions for up to four events (see Figure 1). TFS will format the body of the message as either plain text or HTML depending upon your preferences.
Figure 1 Project Alerts for TFC (Click the image for a larger view)
Visual Studio exposes four events: artifacts are checked-in, a build completes, a build status changes, and someone else changes work items assigned to you. For each event, you can enter one or more e-mail addresses separated by semicolons. You choose the format of the e-mail message (HTML or plain text) on an event-by-event basis. Note that there are more events raised by TFS than those listed in the Project Alerts dialog. (More on this a bit later.)

Controlling E-Mail Message Formatting
TFS controls the formatting of the alert e-mail messages via a set of XSL transforms. You'll find 28 files stored in the folder C:\Program Files\Microsoft Visual Studio 2008 Team Foundation Server\Web Services\Services\v1.0\Transforms. There are four categories of files: eMailTemplate, plantextXsl, XSD, and XSL. Microsoft defines the data layout for its exposed events using the XSD files. The event service uses the XSL and the plaintextXsl files to transform the XML data into the e-mail message body. Microsoft created XSL files for the four events surfaced by the Project Alerts dialog. Note that, in TFS 2008, Microsoft enhanced the Build Completion event and thus created new XSL files suffixed with the numeral 2.
Finally, the eMailTemplate files refer to a set of five additional events that are available via EventService. However, Microsoft is no longer using or supporting these files. Instead, you'll use the DataChangedEvent.xsl file. The Project Alerts dialog doesn't expose these events, so in order to subscribe to them and receive an e-mail notification, you'll need to either use a command-line tool provided by Microsoft (BisSubscribe.exe) or write some code yourself.
To control the format of the notification e-mail messages, you need to edit the appropriate transform files. For the events exposed via the Project Alerts dialog box, you'll want to edit one or more of the respective XSL files. For HTML-formatted e-mail messages, you'll find the core layout for all events stored in TeamFoundation.xsl. You should make a backup copy of any files you intend to change first, and then test your changes. Once you've made your changes, TFS will use the modified transform the next time it raises the event.

Available Events
Microsoft designed the EventService service to be flexible and extensible. There are a couple of techniques you can use to figure out the list of exposed events. I discussed the first mechanism already: just examine the XSD files stored in the Transforms folder.
Programmatically, you can access another support service, the Registration Service, to get a list of services and the events they expose. Figure 2 shows you the code needed to do that and offers an example of the output.
Note that the WorkItemTracking system doesn't expose an event. Yet, if you look in the Transforms folder, you see there is, in fact, a WorkItemChangedEvent.xsd file. In addition, between Visual Studio 2005 and Visual Studio 2008, Microsoft modified how it raises certain events related to Group Security Service (GSS), Authorization, and the Common Structure Service (CSS). Figure 3 provides the current list of events you'll find exposed by EventService. You should consider those events not listed in Figure 3 to be obsolete.
The new DataChangedEvent, defined in DataChangedEvent.xsd, replaces the events exposed via the vstfs service listed in Figure 2. When TFS fires a DataChangedEvent, you'll find it's one of three subtypes: Structure, Security, or Identity. You'll then need to call the appropriate Web service to get the details related to those events. TFS 2008 fires the BuildCompletionEvent2 event for all new subscriptions that you create for build completion. If you've upgraded your server, TFS will continue to fire the BuildCompleteEvent for any subscriptions that existed at the time of your upgrade.

Creating Subscriptions
If you want to create a subscription for an event not available in the Visual Studio Project Alerts dialog, you have two choices. The first choice is to use the BisSubscribe.exe command-line tool installed with TFS at C:\Program Files\Microsoft Visual Studio 2008 Team Foundation Server\TF Setup. Note that this tool is also available as a part of the Visual Studio Team Server (VSTS ) SDK, which is, in turn, a part of the larger Visual Studio SDK. However, the version in the SDK is out of date, and so you should verify that the version you are using is the same as the one provided with your TFS installation.
BisSubscribe.exe supports two commands: subscribe and unsubscribe. Subscribe is implicit. It supports up to six parameters for subscribe and two for unsubscribe. Figure 4 lists the parameters as provided by the tool's help command.
For example, if you want to subscribe to the check-in event for the entire server, you could issue this command (all on one line):
bissubscribe /eventType CheckinEvent 
/address brianr@tfs.local /deliveryType EmailHtml 
/server tfsrtm08
When you execute this command, BisSubscribe returns a message similar to the following:
TF50001:  Created or found an existing subscription. 
The subscription ID is 7.
Using this subscription ID, you can unsubscribe:
bissubscribe unsubscribe /id 7 /server tfsrtm08
Note that you need to manually track the ID returned from your subscribe commands if you don't plan on writing code. There's no way to get a list of subscriptions from the command line. While you can poke around inside the SQL Server® 2005 databases, that is neither recommended nor supported.
Of course, you might not want e-mail for every event. Thus, you can add a bit of filtering:
bissubscribe /eventType CheckinEvent /address brianr@tfs.local 
  /deliveryType EmailHtml /server tfsrtm08 
  /filter "'Artifacts/Artifact[@TeamProject = MSFAgile]' <> null"
What this filter will do is tell TFS that you're only interested in getting an e-mail notification whenever a check-in occurs in the MSFAgile team project.
While BisSubscribe works, it isn't the most intuitive tool. It also does not provide a way to get a list of your existing subscriptions. Therefore, your second choice—to write some of your own code—looks more promising.
I've created a simple app that you can download. It builds on code from earlier columns on work items that provide the UI and framework for connecting to a TFS 2008 installation. To get the list of subscriptions for your user account, you need to connect to EventService by using the TeamFoundationServer object's GetService method and retrieve an IEventService reference. IEventService exposes an EventSubscriptions method that accepts a user ID in the form of User Domain Name and User ID and returns an array of zero or more Subscription instances:
Dim es As IEventService = _ 
  DirectCast(mtfs.GetService( _ 
    GetType(IEventService)), IEventService)

Dim userSubs As Subscription() = _
  es.EventSubscriptions( _ 
  Environment.UserDomainName & _
  "\" & Environment.UserName)

For Each usersub As Subscription In userSubs
  ' Do something
Next
The Subscription object provides a number of properties, including the all-important ID necessary to unsubscribe a user from an event. Using the ID property, you simply execute the UnsubscribeEvent method on a valid IEventService reference and you're finished.
Creating a new subscription is just as easy, with one caveat. IEventService exposes a SubscribeEvent method. It accepts a number of parameters just like BisSubscribe.exe. The hard work is that you need to create a good user experience for defining the filter expression and you also have to write code to ensure expression correctness. You'll find a community project available on the CodePlex site (codeplex.com/tfseventsubscription) that provides sample code for defining event filters.

Creating a Custom Event Listener
While e-mail notifications are useful, you might also want to execute code in response to a particular event. The EventService service supports SOAP-based notifications, allowing you to catch and process events from just about any type of code you prefer. An easy way to get started is by looking at existing code.
For Team Foundation Server 2005, Microsoft released a sample showing how you could implement Continuous Integration using EventService and some code. There's an article at msdn2.microsoft.com/ms364045 and a code download available. This sample is no longer necessary (and it won't work correctly out of the box) with TFS 2008. However, it provides an example of how you can create your own ASMX-based Web service using just a little bit of C#. Using the Microsoft example for inspiration, I've created a simple Web service that catches the WorkItemChanged event.
The first step requires creating a Web service project. To test this code, I used the Virtual PC image provided by Microsoft—you really want to try this stuff out first before you mess with a production server. You can download the image from go.microsoft.com/fwlink/?LinkId=114644.
You'll want to use the ASP.NET Web Service Application template for Visual Basic®. Set the name to MSDNMagTFSEvents and place it at C:\Program Files\Microsoft Visual Studio 2008 Team Foundation Server\Web Services\. Also, make sure to uncheck the "Create directory for solution" option.
After Visual Studio has created the project, adjust the project's properties so that the project URL uses port 8080 (do this via the Web tab in the Project designer). Then, using the IIS management tools, create an IIS application for your project under the Team Foundation Server Web. Ensure that you put your IIS application in the Microsoft® Team Foundation Server Application Pool. After you've done this, try to debug your service to make sure you got the configuration correct.
Now, rename Service1.asmx to ProcessEvents.asmx. Change the backing class name from Service1 to ProcessEvents. Finally, if you feel so inclined, update the Web service namespace to something appropriate. Replace the existing HelloWorld WebMethod with the prototype shown in Figure 5.
The first parameter represents the XML document containing the event information. Think of it as being equivalent to the EventArgs parameter in regular Microsoft .NET Framework events. The second parameter identifies the TFS server raising the event.
At this point, you have all you need to get going. When TFS raises an event, EventService will call your Web service. What you do in the method is up to you and your creativity. Figure 6 provides a simple example that writes to the Windows® event log. The code first checks to verify that the event Xml parameter has data. If not, it exits. Assuming there is data to parse, the code uses LINQ to XML to see whether the collection of changed fields includes the Title. If it does, the code grabs the old and new values, as well as the work item's ID, and writes the data out.
Note that the code to create the event log's event source is defined in the sample client application and needs to run first; otherwise, calls to write to the event log will fail. In a real application, you would have your installer define the event source.
To have TFS call your Web service, you will need to create an event subscription for it. You can do that using BisSubscribe with the following command line:
bissubscribe /eventType WorkItemChangedEvent 
  /address http://localhost:8080/MSDNMagTFSEvents/ProcessEvents.asmx 
  /deliveryType Soap 
  /server tfsrtm08
To create an event subscription in code, you would need to write something like the example in Figure 7, also defined in the sample client application.

Final Details
As with other event-related code, you need to connect to the EventService service using a valid TFS reference. You then create a DeliveryPreference instance and define its properties. The sample code for this column uses the TFS reference to acquire the name and port for the TFS application tier where it assumes you installed the sample Web service. If this is not the case, you'll need to change this in your deployment.
The code sets the delivery schedule to be immediate; however, you can choose either daily or weekly as alternative intervals. You'll want to ensure you use the DeliveryType.Soap option when configuring Web service subscriptions.
Next, you can define a filter string. The sample code provides an option to restrict the notifications to a particular team project, reading the names from the form's combobox of team project names. After you've defined the parameters, you call the Subscribe method. If successful, EventService returns the ID for the new subscription.
There are a few things you need to consider when building your own Web services. If you followed the instructions in this column to configure the service on the application tier, the service runs using the tfsservice account's security context. You did this so that, if necessary, the service can access additional privileged TFS services. If this is not necessary, feel free to use a different deployment model (machine or account) for your own solution.
A second issue you need to be aware of relates to creating event subscriptions. TFS only allows users who are members of the TFS Administrators or the TFS Services security groups to create subscriptions that call Web services.
The TFS EventService service provides lots of hidden power and flexibility just waiting for you to employ in your own applications. Using the code provided here, as well as additional code you can access on Internet sites such as CodePlex, you can mold TFS to fit perfectly in your organization.
Special thanks, as always, to the VSTS Team for answering questions. In particular, Bill Essary from Microsoft provided invaluable information.

Send your questions and comments to mmvsts@microsoft.com.


Brian A. Randell is a Senior Consultant with MCW Technologies LLC. He spends his time speaking, teaching, and writing about Microsoft technologies. Brian is the author of Pluralsight's Applied Team System course and is a Microsoft MVP. Contact Brian via his blog at mcwtech.com/cs/blogs/brianr.

Page view tracker