While learning ASP.NET for developing the RTE for MSDN Forums I had to interact with multiple teams and provide them with status reports on the work items. Some of them were not using TFS yet for that code base. So I wanted a way to easily write a TFS report, send the url to all these teams.
Given my earlier TFS background and the capabilities I learnt exist in ASP world thought why not leverage these two and thus began this exercise to write a TFS Data Source ASP.NET control which I can drop into any ASP.NET web page, bind it to any existing ASP.NET controls to create a simple TFS report.
TFS Data Source ASP.NET Control Snippet [ Build this as a dll ].
[This code snippet is provided under the Microsoft Permissive License.]
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Text;
using System.Web.Configuration;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation.WorkItemTracking;
using Microsoft.TeamFoundation.Server;
using System.Security.Permissions;
[assembly: SecurityPermission(SecurityAction.RequestMinimum)]
// TFS ASP.NET Controls
namespace TfsWebComponents
{
/// <summary>
/// TFS Data Source Component
/// </summary>
[ToolboxData("<{0}:TfsDataSource runat=server></{0}:TfsDataSource>")]
public class TfsDataSource : ObjectDataSource
{
public TfsDataSource()
{
this.TypeName = "TfsWebComponents.TfsServer";
}
}
/// <summary>
/// TFS Data Source Component Implementation.
/// </summary>
public class TfsServer
{
private readonly String tfsServerUrl;
/// <summary>
/// Tfs Server
/// </summary>
private TeamFoundationServer tfsServer;
/// <summary>
/// Tfs Work Item Store
/// </summary>
private WorkItemStore tfsWorkItemStore;
/// <summary>
/// Project service.
/// </summary>
private ICommonStructureService tfsProjectService;
/// <summary>
/// Security service
/// </summary>
private IGroupSecurityService tfsSecurityService;
/// <summary>
/// Tfs Server
/// </summary>
public TfsServer()
{
tfsServerUrl = WebConfigurationManager.ConnectionStrings["TfsServer"].ConnectionString;
tfsServer = TeamFoundationServerFactory.GetServer(tfsServerUrl);
tfsServer.Authenticate();
tfsProjectService = (ICommonStructureService)tfsServer.GetService(typeof(ICommonStructureService));
tfsSecurityService = (IGroupSecurityService)tfsServer.GetService(typeof(IGroupSecurityService));
tfsWorkItemStore = (WorkItemStore)tfsServer.GetService(typeof(WorkItemStore));
}
/// <summary>
/// Get Work items for a given team project using the given stored query name.
/// </summary>
/// <param name="teamProjectName">Name of the TFS team project</param>
/// <param name="storedQueryName">Name of the stored query in TFS</param>
/// <returns>ReadOnlyCollection of WorkItem</returns>
public ReadOnlyCollection<TfsWorkItem> GetWorkItemsByQuery(string teamProjectName, string storedQueryName)
{
Collection<TfsWorkItem> workItems = new Collection<TfsWorkItem>();
Hashtable h = new Hashtable();
h.Add("project", teamProjectName);
foreach (StoredQuery sq in tfsWorkItemStore.Projects[teamProjectName].StoredQueries)
{
if (string.Compare(sq.Name,
storedQueryName,
true,
System.Globalization.CultureInfo.CurrentCulture) == 0)
{
WorkItemCollection myWitems = tfsWorkItemStore.Query(sq.QueryText, h);
workItems = this.GetWorkItems(myWitems);
break;
}
}
h = null;
return new ReadOnlyCollection<TfsWorkItem>(workItems);
}
/// <summary>
/// Get collection of TfsWorkItem given the original WorkItemCollection from TFS.
/// </summary>
/// <returns>Collection of TfsWorkItem</returns>
private Collection<TfsWorkItem> GetWorkItems(WorkItemCollection myWitems)
{
Collection<TfsWorkItem> workItems = new Collection<TfsWorkItem>();
foreach (WorkItem itm in myWitems)
{
// TfsWorkItem is a wrapper for the real TFS work item
// It provides get methods to all work Item properties like AssignedTo, State etc.
TfsWorkItem tfswi = new TfsWorkItem(itm);
//If you want to do additional processing do it here.
workItems.Add(tfswi);
}
return workItems;
}
}
}
[This code snippet is provided under the Microsoft Permissive License.]
In my next post let’s see how to use this to create a simple nice looking TFS report!