— New online course!  Getting Started with Azure DevOps — Special launch price 50% off —

Programmatically Set AreaPath on a WorkItem

by

I wanted to be able to programmatically change the AreaPath on one of my Team Foundation Server (TFS) Work Items but I kept getting validation errors from the WorkItem object.  The idea was to download the list of Areas from TFS and then change an existing work item’s area to one of the other values.   I found some code for accessing the TFS Common Structure Service (ICommonStructureService) and was able to get a list of all the Areas in my team project.  Here’s my version of the method:

// Sample call to the method –> GetNodes(projectName, “ProjectModelHierarchy”)
// “ProjectModelHierarchy” retrieves the list of Areas
// and “ProjectLifecycle” retrieves the list of Iterations
//
private void GetNodes(string projectName, string structureType)
{
  ICommonStructureService structureService =
    this.Server.GetService(typeof(ICommonStructureService)) as ICommonStructureService;

  ProjectInfo project = structureService.GetProjectFromName(projectName);

  NodeInfo[] nodes = structureService.ListStructures(project.Uri);

  int index = 0;

  foreach (NodeInfo node in nodes)
  {
    if (node.StructureType == structureType)
    {
      XmlElement element = structureService.GetNodesXml(new string[] { nodes[index].Uri }, true);
      // element contains the complete list of Areas in the team project in Xml format       
    }
  } 
}

The area data comes back as a bunch of XML and each area comes back as a <Node> that looks like this:

<Node
  NodeID=”vstfs:///Classification/Node/6477228e-2c44-453b-9e81-b051847df740″
  Name=”Area 0.1″
  ParentID=”vstfs:///Classification/Node/5a7d0a28-d436-4ee2-ada9-5df1a333def9″
  Path=”Agile Team ProjectAreaArea 0Area 0.1″
  ProjectID=”vstfs:///Classification/TeamProject/ae5f78db-6ff2-4e09-b371-4b11ec1ec9a9″
  StructureType=”ProjectModelHierarchy” />           

You’d think that you could take the value from the Path attribute on that Node element and set it onto the AreaPath property on a WorkItem object.  Nope.

Microsoft.TeamFoundation.WorkItemTracking.Client.ValidationException: TF26202: Validation failed. Field ‘Area Path’ not supported.

Turns out that the work item object is a little bit picky about the format.  The common structure service prefixes all of the area paths with \team_project_name\Area\.  The work item hates that.  It wants you to remove the leading “\” and that extra “Area” so that it looks like “team_project_name\Area 0\Area 0.1\”.

Here’s a method that will format it for you:

/// <summary>
/// This method takes a path as returned by the common structure service and
/// formats it so that you can assign it to the WorkItem.AreaPath property.
/// </summary>
/// <param name=”input”></param>
/// <param name=”projectName”></param>
/// <returns></returns>
public static string FormatPath(string input, string projectName)
{
  // This is valid — “Agile Team Project\Area 0\Area 0.1\”
  // This is invalid — “\Agile Team Project\Area\Area 0\Area 0.1”   

  string formatted = input;

  formatted = formatted.TrimStart(new char[] { ‘\’ });
  formatted = formatted.Replace(String.Format(“{0}\Area\”, projectName), String.Format(“{0}\”, projectName));

  if (formatted.EndsWith(“\”) == false)
  {
    formatted += “\”;
  }

  return formatted;
}

-Ben

 

— Need help setting up and configuring Team Foundation Server (TFS)?  Need some classroom training on how to use Visual Studio Team System (VSTS)?  Want some help on how to adopt and effectively use VSTS and TFS?  Contact me via http://www.benday.com


One Response to "Programmatically Set AreaPath on a WorkItem"

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: