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!