Team Foundation Server 和 Exchange

使用 Exchange 和 Team Foundation Server 创建票证系统

Mohammad Jalloul

下载代码示例

Team Foundation Server (TFS) 提供了很好的机制,用于创建和管理通过其功能强大的工作项跟踪功能的票证。 此类跟踪通常通过两种方式之一完成。 在第一个 (称为工作组系统 Web 访问权限或 TSWA) 的 Web 界面访问 TFS 支持代表创建自定义工作项类型的支持工作单,输入所需的详细信息。 在第二个方法中,环绕的工作项功能并简化对它的访问,对于不需要知道有关 TFS 的外部用户创建的接口。 工作项然后通常会分派给由跟踪和管理工作项,从 Visual Studio 中的软件工程师。 这两种方法的目的是将票证创建从电子邮件或专用数据库系统移动到 TFS,由于对其很多优点 — — 特别是 TFS 工作项具有定义一个票证的生命周期的工作流。 任何人都可以跟踪的票证通过监视对工作项的更改并查看工作项历史记录。 TFS 数据仓库与的集成提供了额外的好处,SQL Server 报告服务 (SSRS) 或 Excel Services 的功能强大的报告功能,您可以利用。

尽管这种方法,通常获取发送电子邮件周围,以进一步解释问题,或添加更多详细信息。 此附加的电子邮件线程信息有时会丢失,并且其他时间手动复制到工作项历史记录保持尽可能完整的工作项的上下文。 此手动干预的情况下失去了意义的工作项,并可以中止工作效率项目旨在提供的工作。

我将在本文中采用这两个领域的最佳介绍第三种方法: 发送电子邮件和工作项。 这种方法启动与电子邮件 — 一样支持代表做了很长时间。

Exchange Web 服务

我将介绍该过程使用电源的 Microsoft Exchange Web 服务 (EWS) 订阅通知发送到 Exchange 2007/2010年通讯组列表的电子邮件。 监听 Web 服务创建基于接收到任何新的电子邮件的工作项。 与在同一线程相关的任何后续电子邮件被附加到工作项历史记录,使用 Microsoft Exchange Server,因此镜像中的工作项的电子邮件线程的对话跟踪功能。 工作项还维护工作流。 这样用户 — 支持代表,没有做任何更改以适应新的技术 ; 他们习惯 相反,技术采用其过程并自动执行它。

图 1显示了如何将通常流程。

Process Flow for the Support Ticket Work Item

图 1支持票证工作项的工作流程

以下示例说明了详细的流程:

  1. 流程启动时对某一产品问题通知给支持代表。
  2. 支持销售代表发送电子邮件在 Exchange 说明该问题是通讯组列表 (DL)。 DL 包括需要了解的有关此问题的人,可以将其分配给合适的开发人员解决它。 DL 还包含仅用于通知而"监视"电子邮件帐户。 观察程序帐户注册进行交换,以便它将接收通知在特定的 Web 服务地址。
  3. Exchange 处理电子邮件,到 DL 的所有成员并将通知发送到指定的电子邮件帐户中收到这些注册任何 Web 服务。
  4. 支持票证 Web 服务通过其 Web 服务界面,从 Exchange 收到通知。
  5. 在 Web 服务处理通知和请求的电子邮件地址相关的附加信息。 然后,它在 TFS,从电子邮件中提取信息填充创建支持要求工作项。
  6. DL 成员还会收到电子邮件,它们可能响应的方法是提出有关详细信息,它会将支持代表。 因为包含 DL 或电子邮件中,观察程序电子邮件帐户的抄送字段已意识到这和通知 Web 服务接收线程中发生的所有电子邮件的通知。 TFS 更新支持要求工作项的其他信息。
  7. 票证分配给开发人员使用分配给字段支持要求工作项的只是创建。
  8. 开发人员开始从事问题、 进行中更改工作项的状态。 包含此修复程序的代码是检查、 测试并完成,它将签入。 生成变更集是与支持请求工作项相关联。 现在,此工作项跟踪电子邮件会话和变更集相关的修补程序。
  9. 如果支持代表有权访问 TFS,支持请求可以被分配给他用于关闭。 否则,可以通过电子邮件通知 DL。 通常情况下,项目经理和潜在顾客将设置 TFS 警报以便它们得知时支持要求工作项已解决。 工作项更改为正在进行从完成时,这会发生。

是什么通常发生在现实方案中涉及支持问题实际上类似 — 除外,在实际生活中,电子邮件线程和票务系统通常是两个完全不同且相互独立的系统。

支持工作单通知 Web 服务

支持票证通知 Web 服务使用 EWS 托管 API,从而使管理。NET 应用程序与使用有案可稽的接口,熟悉基于 SOAP 的消息传递通过 EWS 进行通信。 您会发现在 EWS 托管 API 的详细的说明bit.ly/jGKRgG

EWS 典型安装的一部分 Microsoft Exchange,并不在很多 IT 系统,它安装在单独的 Exchange 客户端访问服务器上。 若要可重复使用,必须安装并配置了 Microsoft Exchange 服务。 您将需要从您的 Exchange 管理员,这会如下所示 https:// 获得的 EWS Web 服务 URL的主机名/EWS/Exchange.asmx。 请注意,这些 Web 服务通常设置 SSL 终结点。

在撰写本文时 EWS 托管 API 的最新版本为 1.1。 此版本支持通过 Exchange Server 2010 SP1 的 Microsoft Exchange Server 2007 SP1。 您可以下载它从bit.ly/mkb7Is

默认情况下安装程序将文件复制到 [程序] \Microsoft\Exchange\Web Services\1.1。 API 被打包到单个程序集名为 Microsoft.Exchange.WebServices.dll。 安装文件夹包括两个重要的文件,应检查之前开始使用该 API: 参见文件和 GettingStarted.doc。

通过 EWS 进行交互的第一步是创建 Web 服务来侦听来自 Exchange 的通知。 创建此 Web 服务后,必须注册它交换以开始接收通知。

Microsoft Exchange Server 2010 SP1 Web 服务 SDK 简化了创建此类的 Web 服务。 您可以下载到 2010 年 10 月发布 (在撰写本文时的最新版本) 在bit.ly/kZtjLq

SDK,使得更容易生成第一个 Web 服务。 它包含探索由 API 针对不同领域的四个示例。 您可以访问这些示例之后安装的 SDK 通过导航到开始菜单 |所有程序 |Exchange Server 2010 SP1 Web 服务 SDK |10 月 2010年 |Exchange Server 2010 SP1 Web 服务 SDK 示例目录。 特别感兴趣的是该示例是 PushNotification,它演示了推式通知 Web 服务来侦听并处理传入通知从交换。 此示例还包含可用于创建 Web 服务以换取订阅客户端应用程序。 使用此示例为基实现便于了解 EWS 的方式工作,并验证所有必需的部件正常工作。

订阅进行交换

您将需要与 Exchange 创建通知订阅 Exchange 帐户。 订阅将设置路由,以便对该帐户的邮箱发送任何电子邮件会在 Exchange 打电话通知服务注册为该帐户。 请注意可以注册为任何给定帐户的多个通知。 事实上,它是甚至可以创建多个订阅相同的 Web 服务终结点。 从交换和 EWS 的角度看,这是完全合法的。

EWS 中注册的 Web 服务的唯一要求是实现特定接口,INotificationServiceBinding,具有以下签名:

public interface INotificationServiceBinding {
  SendNotificationResultType SendNotification(
    SendNotificationResponseType sendNotification);
}

唯一的要求是 Web 服务包含 SendNotification 方法的实现。 这是接收电子邮件匹配预订属性,Exchange 将调用 Web 方法。

退回到 PushNotification 示例,并且,特别是 PushNotificationSubscriber 控制台应用程序,它将成为清除订阅的需要。 图 2显示了从 PushNotificationSubscriber.cs 文件中获取的 SubscribeForPushNotification 方法。

图 2PushNotification 示例中的订阅代码

public static void SubscribeForPushNotifications()
{
  System.Net.ServicePointManager.ServerCertificateValidationCallback =
    delegate(Object obj, X509Certificate certificate, X509Chain chain,
    SslPolicyErrors errors)
  {
      // Replace this line with code to validate server certificate.
return true; 
  };

  // Create the bindings and set the credentials.
ExchangeServiceBinding esb = new ExchangeServiceBinding();
  esb.Url = "https://CAS01.contoso.com/EWS/exchange.asmx";
  esb.Credentials = new NetworkCredential("username", "password", "domain");

  // Create a new subscription.
SubscribeType subscribeRequest = new SubscribeType();
  PushSubscriptionRequestType pushSubscription = 
    new PushSubscriptionRequestType();

  // Subscribe to events in the inbox folder.
BaseFolderIdType[] folders = new BaseFolderIdType[1];
  DistinguishedFolderIdType folderId = new DistinguishedFolderIdType();
  folderId.Id = DistinguishedFolderIdNameType.inbox;
  folders[0] = folderId;
  pushSubscription.FolderIds = folders;

  // Subscribe to all events.
NotificationEventTypeType[] eventTypes = 
    new NotificationEventTypeType[6];
  eventTypes[0] = NotificationEventTypeType.NewMailEvent;
  eventTypes[1] = NotificationEventTypeType.CopiedEvent;
  eventTypes[2] = NotificationEventTypeType.CreatedEvent;
  eventTypes[3] = NotificationEventTypeType.DeletedEvent;
  eventTypes[4] = NotificationEventTypeType.ModifiedEvent;
  eventTypes[5] = NotificationEventTypeType.MovedEvent;
  pushSubscription.EventTypes = eventTypes;

  // Receive push notifications every 1 minutes.
pushSubscription.StatusFrequency = 1;

  // Identify the location of the client Web service.
pushSubscription.URL = "http://clientWebService/Service.asmx";

  // Form the subscribe request.
subscribeRequest.Item = pushSubscription;

  // Send the subscribe request and get the response.
SubscribeResponseType subscribeResponse = 
    esb.Subscribe(subscribeRequest);

  // Check the result.
if (subscribeResponse.ResponseMessages.Items.Length > 0 &&
    subscribeResponse.ResponseMessages.Items[0].ResponseClass ==
      ResponseClassType.Success)
  {
    SubscribeResponseMessageType subscribeResponseMessage =
      subscribeResponse.ResponseMessages.Items[0] as   
        SubscribeResponseMessageType;

      using (StreamWriter sw = new StreamWriter("MailboxEventLog.txt"))
      {
        sw.WriteLine("Subscribed for Push notifications: {0}", 
          subscribeResponseMessage.SubscriptionId);
      }
  }

  CreateXmlMessageTextFile(subscribeRequest, subscribeResponse);

}

我已经包含在代码图 2此处因为它介绍了关键功能可用时注册订阅。 特别是,请注意该示例将第一条信息,客户端访问服务器 URL 的方式:

esb.Url = "https://CAS01.contoso.com/EWS/exchange.asmx";

然后,它使用的电子邮件帐户的凭据通过 EWS 进行身份验证:

esb.Credentials = new NetworkCredential("username", "password", "domain");

此外请注意一旦您已经创建了一个订阅对象,您可以配置它,以便它仅订阅 (新邮件,复制、 移动、 删除、 修改,等等) 的某些事件或特定邮件文件夹。 这提供了极大的灵活性,则在可以委派 Exchange 而不是订阅的所有事件和更高版本的应用程序中的筛选筛选。

最后,请注意 StatusFrequency 属性。 这是一个数值,它定义了 Exchange 发送检测信号调用 Web 服务来确保已注册终结点处于活动状态的时间间隔,以分钟计)。 这有助于 Exchange 取消订阅不再有效,如移动到新的主机并因此有新的 URL 的 Web 服务终结点。 如果您忘记了在移动 Web 服务之前取消订阅,订阅可以无限期地,最后,Exchange 将不断发送通知不必要地到不存在的终结点。

现在让我们看一下要支持的支持请求 TFS 工作项创建的自定义实现。 显示功能的最佳方法是使用 Web 服务的演示来启动,然后深入讨论实施。

部署 Web 服务

本文附带的代码项目包含 Web 服务和其他支持的多个项目。 没有单独的控制台应用程序,譬如登记的因为它内置 Web 服务。

一旦建立,从 Visual Studio 到 2010年或通过将生成预编译的网站复制到主机,也可以部署 Web 服务。 您需要手动创建 Web 应用程序和相应的应用程序池。 观察程序用户帐户设置应用程序池的标识。 这是重要的因为 Web 服务可以模拟应用程序池的标识,并使用它来执行该订阅。 这样做有两个好处:

  1. 无需每次需要重新注册的 Web 服务必须重新输入凭据。
  2. 凭据不需要存储,它们可能无法访问要使用它们来重新订阅。

Web 服务需要两个文件夹具有写权限: 它可以向其写入日志和用作 TFS 高速缓存的文件夹的文件夹。 此外,您将需要在 web.config 文件中,配置下列设置,它们依赖于特定的环境使用的 Web 服务的位置:

  • EWSServiceUrl: Exchange 服务 URL。 Exchange 管理员可以让此 URL。.
  • TeamFoundationServerUrl: TFS 的 URL 项目的工作项的部署位置的集合 (例如: http://<servername>:8080/tfs/).
  • WorkItemTeamProject: 名称包含支持票证 TFS 团队项目的工作项类型 (例如: SupportWorkFlow).
  • WorkItemType: 支持票证的实际名称工作项类型 (例如: 支持请求)。 如果重命名工作项,或如果的 Web 服务用来支持某些其他工作项类型 (如本文后面将显示),您可以使用此设置新的工作项的名称。
  • RequestSupportTeamName: 工作项包含一个用于将定向到不同的支持任务的不同团队的"请求支持团队"字段。 这是由全局列表中的工作项定义名为团队驱动的。 要使用此功能,请将字段定义全局列表 (在本文中,"配置工作项"的下一节中包含的说明) 和创建一个全局列表的值指派给 RequestSupportTeamName 配置选项 (例如: 客户服务)。 如果没有,从工作项中删除字段和"必需"约束的全局列表,然后将 RequestSupportTeamName 关键字的值保留为空。

此时该 Web 服务就可以使用。 可以验证它是否设置正确的 Web 服务器上使用 IIS 管理器,以导航到 Web 应用程序文件夹 (请记住单击底部的内容视图选项卡上,如果使用 IIS 7 或更高版本)。 右键单击该 Service.asmx 文件,然后单击浏览,如中所示图 3。 您应该看到 Web 页中所示相同图 4

Browsing to the ASMX Page

图 3浏览 ASMX 网页

Default Web Service URL with localhost as the Host

图 4使用的主机的本地主机的默认 Web 服务 URL

您可以开始使用 Web 服务之前,您需要导入 TFS 的工作项。 本文假定您正在使用 TFS 2010 年,但 TFS 2008 中,可以使用同一个工作项和 Web 服务。

配置工作项

本文中的示例代码 (您可以在下载的code.msdn.microsoft.com/mag201108TFS) 包含示例支持票证工作项类型调用支持请求。 若要查看的工作项类型定义、 工作流和才能导入到 TFS 的布局,您需要安装 TFS 电源工具,可从bit.ly/hyUNqo。 当您安装 TFS 电动工具时,调用进程编辑器的新菜单将被添加到 Visual Studio 的 IDE,在工具菜单下。 双击 (位于下面示例解决方案中的工作项文件夹) 的支持 Request.xml。 工作项编辑器窗口将加载有三个选项卡: 字段、 布局和工作流程,如中所示 图 5.

Workflow for the Support Ticket Work Item
(单击进行缩放)

图 5支持票证工作项的工作流

工作流的工作项显示了支持该工作项的不同状态: 新的工作项第一次创建时; 执行过程中,当问题记录在工作项实际上正在处理; 并完成后,当有关问题的工作结束。

如果您决定配置请求技术支持人员字段中,如前文所述,找到字段选项卡下的请求技术支持人员字段,请双击它以打开字段定义对话框中,然后单击规则选项卡上。 如果您不打算使用此字段,只需删除两个列出的规则 (ALLOWEDVALUES 和必需)。 如果您想要使用的字段,但希望将其配置为使用不同的全局列表,请双击 ALLOWEDVALUES 规则,然后上存在的唯一一项: GLOBALLIST: 团队。 在编辑列表项目对话框中,选择一个全局列表,然后单击确定。

如果您没有尚未设置全局列表,则可以创建一个 (您需要具有 TFS 管理员权限):

  1. 在 Visual Studio IDE 中,转到工具 |进程编辑器 |全局列表,然后单击打开来自服务器的全局列表。
  2. 您将看到一个对话框。 选择团队项目集合,然后单击连接。
  3. 在全局列表对话框中,用鼠标右键单击任何项目,然后单击新全局列表上的。
  4. 输入全局列表的名称。 您可以保留在工作项中为相同的名称:团队。
  5. 用鼠标右键单击新全局列表,然后单击新的项目。 根据需要输入团队名称的多个时间重复此步骤。
  6. 单击确定以保存新的全局列表。

请注意是否您已经指定新全局列表一个不同的名称,您需要编辑工作项和全局列表名称更新其定义。

在这种情况下,剩下的就是向 TFS,导入工作项如下:

  1. 在 Visual Studio IDE 中,转到工具 |进程编辑器 |工作项类型,然后单击导入 WIT (WIT 代表的工作项类型) 上。
  2. 单击浏览按钮,然后定位到支持 Request.xml 文件的位置。
  3. 在要导入到列表项目中,单击您要向其中导入工作项,然后单击确定 TFS 团队项目的名称。

您可以验证从该团队项目团队资源管理器中右键单击工作项节点,然后展开新工作项窗口中的工作项已成功导入到 TFS。 您应该看到支持要求作为可用选项之一。 如果您没有看到它,用鼠标右键单击工作项节点,然后单击刷新。

创建订阅

如中所示 图 4, Web 服务有三种方法: 检查状态、 SendNotification 和订阅。 订阅 Web 方法用于创建通知订阅。

订阅过程将创建的订阅将被设置为 Web 服务应用程序池的标识的用户帐户。 若要有效地使用通知,该帐户 — 观察程序帐户 — 应为进行监视,如中所示的 DL 的一部分图 6

Adding the Watcher E-mail Account to a Distribution List

图 6添加到通讯组列表的观察程序电子邮件帐户

要创建订阅,请单击显示在 Web 页上的订阅链接图 4。 然后单击生成 Web 页上的调用按钮。 一旦成功,您将看到一个订购 id。 这也会记录到 web.config 文件中定义的日志文件夹。

订阅的详细信息将登录到这两个文件。 第一个记录发送到 EWS 进行订阅请求,并有窗体 SubscribeType-<timestamp>.xml。 第二个文件中记录响应来自 EWS 确认订阅,并且窗体 SubscribeResponseType-<timestamp>.xml。 一个名为 SubscriberEventLog.txt 的第三个文件记录从交换,包括信号状态事件,Web 服务接收的所有事件,每分钟和新邮件事件时它们所触发。

订阅的状态可验证的任何一点,通过调用 CheckStatus Web 方法,这将产生类似于中所示的结果图 7,其中显示收到的最后一个检测信号事件的时间和 Web 服务预订的状态。 如果没有有效的订阅,您将看到"状态: 订阅,"图中所示。

Sample Output from the CheckStatus Web Method

图 7CheckStatus Web 方法的输出示例

整个过程所示的序列图中图 8

The Subscription and Notification Process

图 8的订阅和通知过程

使用票证发放系统

要开始使用票证发放系统的最简单方法是模拟实际情况并向 DL 包含的观察程序帐户发送电子邮件。 图 9 显示电子邮件示例所示 DL 图 6,和 图 10显示支持要求工作项从交换的通知 Web 服务发送的通知的结果生成的。

The First E-mail in a Mail Thread

图 9邮件线程中的第一个电子邮件

The Work Item Generated as a Result of the First E-mail
(单击进行缩放)

图 10作为第一个电子邮件的结果而生成的工作项目

图 11显示为在同一个电子邮件线程和方式的转换为工作项历史记录的一部分发送其他电子邮件的结果。 第一个线程获取以不同颜色的标头。 其余的线程获取另一种不同的颜色 (在这种情况下,黄色,但可以在 web.config 中配置颜色)。

The Work Item After a Second E-mail
(单击进行缩放)

图 11后第二个电子邮件的工作项

自定义代码

现在让我们看一下不同的代码段,使系统运行。 本文中的代码示例包含一个名为 Email2Workitem.sln 的 Visual Studio 2010年解决方案。 当加载 Visual Studio 是此解决方案时,您将看到结构分为四个解决方案文件夹: 图、 订阅存储库、 Web 服务和工作项。

大多数情况下,Web 服务基于 PushNotification SDK 示例。 但是,我进行某些更改以使通用且易于使用的解决方案。 我会介绍的更改和对示例变成一个票证发放解决方案所做的自定义设置。

第一个很大的更改是允许订阅过程集成到 Web 服务的功能。 这是至关重要的因为它允许 Web 服务订阅而无需管理的帐户凭据。 有时需要续订,如承载 Web 服务的服务器例如经历一些维护活动,当订阅。 当出现这种情况时,通常停止应用程序池和 Exchange 取消订阅,因为信号事件获取没有响应。 自动续订的订阅是通过 Web 服务构造函数中调用 InitializeTimer 方法来实现的。 InitializeTimer,以显示图 12,与在 web.config 中指定的时间间隔创建一个计时器。 续订订购服务中断后的,例如负责此计时器。

图 12InitializeTimer 方法

private void InitializeTimer()
{
  int autoSubscribeTimeoutThresholdInMinutes = Convert.ToInt32(
    ConfigurationManager.AppSettings["AutoSubscribeTimeoutThresholdInMinutes"]);
 
    lock (_pollingTimerSyncLock)
    {
      if (autoSubscribeTimeoutThresholdInMinutes > 0)
      {
        // Seed the timer with the polling interval specified in config.
if (_pollingTimer == null)
        {
          TimerCallback timerCallback = OnTimedEvent;
          _pollingTimer = new Threading.Timer(timerCallback, null, 0, 
          _pollingIntervalInMilliseconds); // Enable the timer.
}
      }
      else
      {
        // Dispose of the timer.
if (_pollingTimer != null)
        {
          _pollingTimer.Dispose();
          _pollingTimer = null;
        }
      }
    }
}

第二个重要的更改已与检查传入的消息以确定它是否在一个线程中的第一个电子邮件。 图 13显示了此功能。

图 13确定线程中的第一个电子邮件

// Get either the folder or item identifier for a 
// create/delete/new mail event.
if (bocet.Item is ItemIdType)
{
  // Get the item identifier.
ItemIdType itemId = bocet.Item as ItemIdType;
 
  //
  // Get the message using the ItemIdType.
//
 
  // From web.config
  string ewsServiceUrl = 
    ConfigurationManager.AppSettings["EWSServiceUrl"];
 
  ExchangeService esb = 
    new ExchangeService(ExchangeVersion.Exchange2010);
  esb.Url = new Uri(ewsServiceUrl);
  // From Web service App Pool identity.
esb.UseDefaultCredentials = true;
 
  EmailMessage message = EmailMessage.Bind(esb, new ItemId(itemId.Id));
  ConvertEmailToRequestItem(message);
}

请注意该代码如何利用这一事实的 Web 服务应用程序池标识的邮件帐户,这意味着 Web 调用以检索电子邮件详细信息而无需输入任何凭据,才能进行。

ConvertEmailToRequestItem 方法完成大部分工作。 若要确定电子邮件的第一个电子邮件或串接的组成部分,它利用 ConversationIndex EmailMessage 实例的属性。 ConversationIndex 
byte 数组的长度为 22 时的第一个电子邮件。 在一个线程中的后续电子邮件获取更多字节为单位) 添加到 ConversationIndex。 ConvertEmailToRequestItem 利用它来确定是否视为一封新邮件的电子邮件并创建新的工作项,或作为现有的线程,在这种情况下它查找现有的工作项,并将邮件消息的线程特定部分附加到工作项的修订历史记录。 Exchange 公开特定于通过 EmailMessage UniqueBody 属性的线程中的当前电子邮件的电子邮件的一部分。 若要获得完整的线程,可以使用正文属性。 这是非常强大,因为它允许生成电子邮件线程中的工作项的修订历史记录中,如中所示图 11

值得一提的一个特殊情况是当邮件到达时的线程的但没有相应的工作项才可更新的一部分。 这通常发生如果票证发放系统已落实到位之前启动该线程。 在这种情况下,都会创建一个新的工作项。

为了确定电子邮件是否已存在为工作项目的 Web 服务,它依赖的一条首次创建工作项时它存储在工作项的信息: ConversationIndex. Web 服务查询工作项的基础以了解是否存在工作项的值。 查询使用可执行 TFS 工作项查询语言 (WIQL),下面的代码所示:

private const string QUERY_BY_CONVERSATION_INDEX_WIQL =
  "SELECT [System.Id] FROM WorkItems WHERE [System.TeamProject] = '{0}'  AND
    [System.WorkItemType] = 'Support Request' AND
    [MsdnMag.SupportTicket.ConversationIndex] = '{1}' ORDER BY [System.Id] desc";

WIQL 为您提供了一个工作项查询而无需加载对象和枚举集合的一种简单而功能强大的方法。

Web 服务还提供了一种方法,以方便地跟踪其 TFS 活动日志中。 TFS 活动日志 (tbl_Command 和 tbl_Parameter) 的两个 SQL Server 表中存储在数据库中为团队项目集合。 检查 tbl_Command 让 TFS 管理员确定请求的源中的用户代理列。

通知 Web 服务以清楚地标识它通过使用下面的语句,自定义用户代理数据:

TfsConnection.ApplicationName = string.Format(
  TFS_APPLICATIONNAME_TEMPLATE, WindowsIdentity.GetCurrent().Name);

在此特定情况下,用户代理将类似"MsdnMagSubscribeSvc – Contoso\JDoe。"

ConvertEmailToRequestItem 的另一种可能有用的功能是能够过滤电子邮件,根据特定前缀中的主题行中,下面的代码所示:

// First check if prefix-based filtering is turned on, and if so, 
// if the e-mail subject line matches the defined prefix.
string subjectPrefix = 
  ConfigurationManager.AppSettings["SubjectPrefix"];
if (!string.IsNullOrWhiteSpace(subjectPrefix))
{
  if (!title.StartsWith(subjectPrefix, 
    StringComparison.InvariantCultureIgnoreCase))
  {
    WriteEventToLog(
      string.Format(SUBJECT_DOES_NOT_MATCH_PREFIX_TEMPLATE,
      subjectPrefix, title));
 
    return;
  }
}

您可以使用此功能来限制只有某些电子邮件 ; 对该服务的功能 例如,对代码检查电子邮件前缀可以定义位置为"代码审阅。

Other Use Cases:代码审阅

此处提供的用例是支持工作单。 但是,本文中介绍的方法的灵活性可以轻松地将相同的技术应用于其他使用情形,如跟踪代码审查。 代码评审用例的流程所示图 14

Process Flow for the Code Review Work Item

图 14代码评审工作项的工作流程

开发组织倾向于进行代码审核通过电子邮件。 已集成到 TFS 的代码审查,通过创建代码评审工作项并生成外接程序以允许管理代码评审的过程从 Visual Studio 中的许多尝试。 但是,采用支持票证的相同技术可以,可以方便地集成到 TFS 工作项跟踪系统的代码检查电子邮件线程。 以下步骤概述了通知基础结构使用代码检查建议的过程:

  • 首先创建代码评审工作项类似于支持要求工作项。
  • 设置 DL 中观察程序帐户,以监视 DL 收到的电子邮件。
  • 使用上文定义前缀将作为代码检查电子邮件的电子邮件区分开来的 SubjectPrefix 功能。 通常通过电子邮件发送的代码审阅请求必须遵循此模式的主题行:"代码检查: 我搁置集名称。"

如中所示图 14,在实际的签入的搁置集内容关联的工作项提供可追溯性到的生命周期中时进行时发送进行代码评审,当它获得批准为签入并,最后,当它被签入, 代码的代码。 此关联是提供了很好了解通过源代码管理签入的任何代码的 TFS 的强大功能。 它是特别有用的资产,审核原因,需要可追溯性的组织。

接下来怎么办

这篇文章的主要目标是展示结合起来以便提高生产力和效率使用 TFS 和交换的许多可能方式之一。 尤其是在 TFS 2010 年,有关工作项、 善之一是它们如何集成内部 TFS。 可以将工作项链接到更改集。 它们可以表示和跟踪测试计划。 他们可以方便地报告,使用 Excel 或 SSRS,并且还可与 Microsoft Project 同步它们。

掌握的用例和本文中介绍的技术,您应该能够利用通知 Web 服务和许多其他特定于您自己的环境的情况下的工作项的自定义。

Mohammad Jalloul 是在 Myspace Inc.,他是负责将 TFS 集成到不同的业务流程,并利用它来提高效率和生产率社会娱乐网站的软件工程师。之前,他工作在雷蒙德在 Microsoft 开发人员分部称为直布罗陀内部工具。他可以通过在其博客mohammadjalloul.com

衷心感谢以下技术专家对本文的审阅: Bill Heys