Click here to Skip to main content
Click here to Skip to main content

Web Forms for Submitting Issues to Team Foundation Server

, 19 Jul 2006
Rate this:
Please Sign up or sign in to vote.
This article describes how you can create a Web based interface to the Team Foundation Server for the purpose of submitting and tracking issues.

Introduction

Our development teams have been using the Microsoft Team Foundation Server (TFS) and, thus far, have been happy with it. We did, however, have one major problem: there is no Web interface to the work item tracking system for our customers to use to submit defects. At first our options seemed somewhat limited; we could have our customer’s email defects to us, but they have a funny way of getting lost that way. We could use a different defect tracking system for our customers and then enter them into the TFS, but the double entry is a pain not to mention keeping the defect status up to date. We could scrap the TFS defect tracking, but our teams are using it effectively. None of these solutions was palatable to us. After a bit of research, we began to explore the TFS API and found that integrating custom applications with TFS was simple, almost trivial. So we chose to implement a few Web forms to allow customers to submit defects to the TFS. This allowed us to create a very simple interface that hid the complexity and workflow of the work item tracking from our customers while keeping all the benefits of the system for our internal use.

In this brief tutorial, I will walk you through the steps toward creating your own Web based interface for work item tracking in TFS.

Implementation

First, you'll need to locate your assemblies for the team foundation server API. They should be located in: %PROGRAM FILES%\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies.

You'll need to reference the Microsoft.TeamFoundation.WorkItemTracking.Client assembly.

We created a simple class to serve as a hook to the work item data store. For our example, we will be creating two static properties; one to get a handle to the project and one to get a work item of type Bug. This provides a convenient mechanism for grabbing a project or bug type reference.

internal class DataManager
{
    internal static Project DevelopmentProject
    {
        get
        {
            NetworkCredential account = 
                new NetworkCredential([account],[password],[domain]);
            TeamFoundationServer server = new TeamFoundationServer(ServerName,account);
            server.Authenticate();
            WorkItemStore store = new WorkItemStore(server);
            return store.Projects[ProjectName];
        }
    }
    
    internal static WorkItemType BugType
    {
        get
        {
            return DevelopmentProject.WorkItemTypes["Bug"];
        }
    }
}

The next step was to create a simple interface to submit bugs. Figure 1 shows our initial interface. Again, the idea was to make something remarkably simple that our customers could understand without needing training.

Simple web form for submitting issue
Figure 1: Submit a Bug

To get the list of allowed severities, we simply needed to bind the drop down list to the allowed values property of the severity field:

Severity.DataSource = DataManager.BugType.FieldDefinitions["Severity"].AllowedValues;
Severity.DataBind();

Upon submit (after validating the input fields, of course), saving the new issue is a simple matter of creating a new work item, setting the field values, and saving the work item.

WorkItem newBug = new WorkItem(DataManager.BugType);
newBug.Title = Title.Text;
newBug.Fields["Symptom"].Value = Description.Text;
newBug.Fields["Severity"].Value = Severity.SelectedItem.Text;
newBug.Fields["Steps to Reproduce"].Value = Reproduce.Text;
newBug.Save();

Of course, if you're going to let them submit a bug, you may as well let them view the list of bugs. The list interface we created is illustrated in Figure 2. We followed the sample principle – simple is better.

Simple issues list
Figure 2: Issue List

Getting the issues list from the TFS is also trivial. We simply needed to execute a query against the work item store and bind the results to a grid. If you aren't sure about the syntax of the SQL query, you may want to create a query using the GUI in the TFS client and then copy the syntax of the query. You will also need to use a name value collection (we chose a Hashtable) to add your parameter collection to the query. Execute the query against the work item store of the project. The resulting WorkItemCollection can be bound directly to your grid.

Hashtable parameters = new Hashtable();
parameters.Add("project", [TFS Project Name]);
string query = "SELECT [System.Id], [System.WorkItemType], 
    [System.AssignedTo], [System.CreatedBy], [Microsoft.VSTS.Common.Priority], 
    [System.Title] FROM WorkItems WHERE [System.TeamProject] = @project 
    AND [System.WorkItemType] = 'Bug' 
    ORDER BY [System.WorkItemType], [System.Title], 
    [Microsoft.VSTS.Common.Priority], [System.Id]";
WorkItemCollection items = DataManager.DevelopmentProject.Store.Query(query,parameters);
Defects.DataSource = items;
Defects.DataBind();

Finally, we needed to create a basic interface for viewing the issue details. Again, we created a very simple interface that displayed the issue details in a manner that would be simple for our customers to understand. This screen is illustrated in Figure 3.

Sample screenshot
Figure 3: Issue Detail

To display the issue detail, we simply need to get the working item from the project’s work item data store using the work item ID passed via the query string. Each field that we want to display is read from the work item. We also display the history of a work item. In hind sight, we should have used a repeater to display this information to appropriately separate the display from the control logic. (I'll log that as an issue using this very simple interface!)

int id = int.Parse(Request.QueryString["IssueID"]);
WorkItem bug = DataManager.DevelopmentProject.Store.GetWorkItem(id);
title.Text = bug.Title;
status.Text = (string) bug.Fields["State"].Value;
triage.Text = (string) bug.Fields["Triage"].Value;
description.Text = (string) bug.Fields["Symptom"].Value;
reproduce.Text = (string) bug.Fields["Steps To Reproduce"].Value;
StringBuilder versionHistory = new StringBuilder();
foreach (Revision issue in bug.Revisions)
{
    versionHistory.Insert(0,
    string.Format("By:{0}<br>On: {1}<br>{2}<br><hr>",
    issue.Fields["Changed By"].Value,
    issue.Fields["Changed Date"].Value,
    issue.Fields["History"].OriginalValue));
}
history.Text = versionHistory.ToString();

That’s really all there is to it. With three simple Web forms and some trivial code, we were able to create a Web based interface for our users to submit and view issues. Because of the overall simplicity, our users like this system more so than our previous, completely Web based, issue tracking system.

End Notes

About Connecting to the Server

When integrating to the team foundation server, you may experience a couple of issues.

  1. Connecting to the server – While using the server name was sufficient for our developers to connect to the team foundation server, when we rolled out to production, we needed to connect to the server using the following syntax: http://[server name]:8080.
  2. Connection credentials – While developing the Web forms, our developers needed to only supply the server name, and not the credentials. This did not work in production because the account running the application did not have access to the team foundation server. Using the NetworkCredential class with a configurable user name and password that could access the server worked. Using Windows Authentication with impersonation should also work.
  3. The Network Service account running the application did not have access to the team foundation work item cache directory. This can be fixed by:
    1. Granting read/write access to the directory to the Network Service
    2. Running the application using an account that does have access to the service
    3. Configuring the application to use a different directory for the work item cache to which the Network Service does have read/write access

About the Source Code

The source code relies on a custom configuration section to store the connection information for the team foundation server. We do this so that the connection data can be encrypted if need be. In the Web.Config file, edit the TeamFoundationIntegration configuration section to supply your own credentials.

The source code is written using the “Web Application” project type in Visual Studio 2005. This project type does not ship natively with Visual Studio 2005, but may be downloaded free of charge from Microsoft.

The source code is intended to provide you with a starting point for creating your own Web interface to TFS and is not intended to be a “shrink-wrapped” solution. Decide which fields are important to you and your customers and modify the code as necessary.

About Team Foundation Server Licensing

It is important that you and your organization identify your licensing needs. The only recommendation I can make is to look into the "Device CAL". Beyond that, I cannot make any licensing recommendations for you. If you have questions about licensing issues, contact Microsoft. I can tell you that my organization contacted Microsoft with licensing questions and were very happy with the results.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Jim Conigliaro
Web Developer
United States United States
Jim Conigliaro is the director of Online Operations and Technology at the Milwaukee Journal Sentinel.

Jim holds a Masters degree in Electrical and Computer Engineering with a specialty in computational intelligence. He has been developing software professionally for 10 years.

Jim can be contacted at jconigliaro@ieee.org.

Home Page:www.jimconigliaro.com

Comments and Discussions

 
QuestionThanks Pinmembercar_fax27-Jun-12 8:01 
QuestionNTLM - Single Sign-On Pinmembertomasscott18-Nov-08 8:13 
GeneralTeamFoundationDefectTracking.sln Pinmemberctsvenky16-Sep-08 3:36 
Questiongetting error Pinmemberviperfish_018-Nov-07 10:21 
AnswerRe: getting error PinmemberPatrick Goldbach21-Jul-08 6:57 
GeneralRe: getting error Pinmemberctsvenky18-Sep-08 1:27 
GeneralRe: getting error PinmemberChad Fairbanks19-Nov-08 11:59 
QuestionNeed help with selecting a workitemstore from multiple workitemstore PinmemberPalak Jain1-Aug-07 8:27 
QuestionWhy no CoreFields? Pinmemberpdluke30-Jul-07 22:00 
AnswerRe: Why no CoreFields? PinmemberJim Conigliaro31-Jul-07 2:35 
GeneralWorkItem related classes [modified] Pinmemberjorgensen.ian25-Sep-06 23:15 
QuestionCode Pinmemberdanielj24-May-06 7:43 
AnswerRe: Code PinmemberJim Conigliaro24-May-06 8:42 
GeneralRe: Code PinmemberPeter Tewkesbury8-Jul-06 4:55 
GeneralRe: Code Pinmembergartho11-Jul-06 22:57 
GeneralRe: Code PinmemberJim Conigliaro19-Jul-06 10:45 
GeneralEULA Issue [modified] PinmemberAntC24-May-06 2:36 
GeneralRe: EULA Issue [modified] PinmemberJim Conigliaro24-May-06 3:42 
NewsRe: EULA Issue [modified] PinmemberScott ---5-Jun-06 12:29 
GeneralRe: EULA Issue [modified] PinmemberJim Conigliaro6-Jun-06 3:44 
GeneralRe: EULA Issue [modified] PinmemberScott ---6-Jun-06 7:50 
GeneralRe: EULA Issue Pinmembermattjb014-Sep-06 12:57 
GeneralRe: EULA Issue PinmemberScott ---14-Sep-06 13:16 
GeneralRe: EULA Issue PinmemberGrahamHarris3-Jan-07 5:28 
GeneralRe: EULA Issue Pinmemberspiegdon12-Aug-08 7:28 
GeneralRe: EULA Issue PinmemberMark Bible1-Mar-07 7:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140827.1 | Last Updated 19 Jul 2006
Article Copyright 2006 by Jim Conigliaro
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid