用于向 Team Foundation Server 提交问题的 Web 表单






4.53/5 (23投票s)
本文介绍如何创建一个基于 Web 的界面来提交和跟踪 Team Foundation Server 中的问题。
引言
我们的开发团队一直在使用 Microsoft Team Foundation Server (TFS),到目前为止,他们对此都非常满意。然而,我们确实遇到了一个主要问题:对于客户来说,没有基于 Web 的界面来使用工作项跟踪系统提交缺陷。起初,我们的选择似乎非常有限;我们可以让客户通过电子邮件将缺陷发送给我们,但这样很容易丢失。我们可以使用不同的缺陷跟踪系统供客户使用,然后将其录入 TFS,但这会导致重复录入,更不用说保持缺陷状态的最新了。我们可以放弃 TFS 的缺陷跟踪,但我们的团队已经在使用它了。这些解决方案我们都无法接受。经过一番研究,我们开始探索 TFS API,发现将自定义应用程序与 TFS 集成非常简单,几乎是小菜一碟。因此,我们选择实现几个 Web 表单,允许客户向 TFS 提交缺陷。这使我们能够创建一个非常简单的界面,向客户隐藏了工作项跟踪的复杂性和工作流程,同时为我们的内部使用保留了该系统的所有好处。
在本简短的教程中,我将引导您完成在 TFS 中创建自己的基于 Web 的工作项跟踪界面的步骤。
实现
首先,您需要找到 Team Foundation Server API 的程序集。它们应该位于:%PROGRAM FILES%\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies。
您需要引用 Microsoft.TeamFoundation.WorkItemTracking.Client
程序集。
我们创建了一个简单的类作为工作项数据存储的钩子。在我们的示例中,我们将创建两个 static
属性;一个用于获取项目句柄,另一个用于获取 Bug
类型的工作项。这提供了一种方便的机制来获取项目或 Bug 类型引用。
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"];
}
}
}
下一步是创建一个简单的界面来提交 Bug。图 1 显示了我们的初始界面。同样,我们的想法是创建一个极其简单的东西,客户无需培训就能理解。

要获取允许的严重程度列表,我们只需将下拉列表绑定到严重程度字段的允许值属性即可。
Severity.DataSource = DataManager.BugType.FieldDefinitions["Severity"].AllowedValues;
Severity.DataBind();
提交时(当然,在验证输入字段后),创建新工作项、设置字段值并保存工作项即可轻松完成新问题的保存。
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();
当然,如果您允许他们提交 Bug,那么让他们查看 Bug 列表也是有益的。我们创建的列表界面如图 2 所示。我们遵循了样本原则——简单就是最好。

从 TFS 获取问题列表也很简单。我们只需对工作项存储执行查询,然后将结果绑定到网格。如果您不确定 SQL 查询的语法,可以尝试在 TFS 客户端中使用 GUI 创建一个查询,然后复制查询的语法。您还需要使用名称值集合(我们选择了 Hashtable)将参数集合添加到查询中。对项目的工作项存储执行查询。生成的 WorkItemCollection
可以直接绑定到您的网格。
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();
最后,我们需要创建一个基本界面来查看问题详细信息。同样,我们创建了一个非常简单的界面,以一种客户容易理解的方式显示问题详细信息。此屏幕如图 3 所示。

要显示问题详细信息,我们只需使用通过查询字符串传递的工作项 ID 从项目的工作项数据存储中获取工作项。我们要显示的每个字段都从工作项中读取。我们还显示工作项的历史记录。回想起来,我们应该使用 Repeater 来显示此信息,以便将显示与控件逻辑适当地分开。(我将使用这个非常简单的界面将它记录为一个问题!)
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();
基本上就是这样。通过三个简单的 Web 表单和一些简单的代码,我们能够为用户创建提交和查看问题的基于 Web 的界面。由于整体简单性,我们的用户比我们以前完全基于 Web 的问题跟踪系统更喜欢这个系统。
结束注释
关于连接到服务器
在与 Team Foundation Server 集成时,您可能会遇到一些问题。
- 连接到服务器 – 虽然使用服务器名称足以让我们的开发人员连接到 Team Foundation Server,但在我们部署到生产环境时,我们需要使用以下语法连接到服务器:http://[server name]:8080。
- 连接凭据 – 在开发 Web 表单时,我们的开发人员只需要提供服务器名称,而无需提供凭据。这在生产环境中无效,因为运行应用程序的帐户没有访问 Team Foundation Server 的权限。使用
NetworkCredential
类,并提供一个可访问服务器的可配置用户名和密码,这样就可以正常工作。使用带有模拟的 Windows 身份验证也应该有效。 - 运行应用程序的 Network Service 帐户无权访问 Team Foundation 工作项缓存目录。可以通过以下方式解决此问题:
- 授予 Network Service 对该目录的读/写访问权限
- 使用有权访问该服务的帐户运行应用程序
- 将应用程序配置为使用 Network Service 具有读/写访问权限的另一个目录作为工作项缓存
关于源代码
源代码依赖于自定义配置节来存储 Team Foundation Server 的连接信息。我们这样做是为了可以根据需要加密连接数据。在 Web.Config 文件中,编辑 TeamFoundationIntegration
配置节以提供您自己的凭据。
源代码是使用 Visual Studio 2005 中的“Web 应用程序”项目类型编写的。此项目类型不随 Visual Studio 2005 一起安装,但可以从 Microsoft 免费下载。
源代码旨在为您提供创建自己的 TFS Web 界面的起点,并非“开箱即用”的解决方案。请根据您和客户的重要程度决定字段,并根据需要修改代码。
关于 Team Foundation Server 许可
您和您的组织识别您的许可需求非常重要。我唯一能做的建议是研究“Device CAL”。除此之外,我无法为您提供任何许可建议。如果您有关于许可问题的疑问,请联系 Microsoft。我可以告诉您,我的组织就许可问题联系了 Microsoft,并且对结果非常满意。