如何使用TFS API 2013获取所有迭代路径 - c#

我已经使用TFS API库已有一段时间,并且在与TFS 2010交互以获取迭代路径时一直使用以下代码
(来自this page的代码)...

public IList<string> GetIterationPaths(Project project)
{
   List<string> iterations = new List<string>();
   foreach (Node node in project.IterationRootNodes)
      AddChildren(string.Empty, node, iterations);
   return iterations;
}

private void AddChildren(string prefix, Node node, List<string> items)
{
   items.Add(node.Path);
   foreach (Node item in node.ChildNodes)
      AddChildren(prefix + node.Name + "/", item, items);
}

当我希望在TFS 2013中获得所有迭代时,事情发生了变化。在TFS 2013中,迭代的概念略有变化,并且TFS 2013的API程序集没有IterationRootNodes

我已经使用以下代码获取团队迭代,但这是基于团队的,而不是针对项目的完整迭代...(目前正在获得第一团队,但可以进行编码以获取其他团队)

 var cred = new TfsClientCredentials(new WindowsCredential(), true);
 TfsTeamProjectCollection coll = new TfsTeamProjectCollection("{URI to SERVER}", cred);
 coll.EnsureAuthenticated();

 var teamConfig = coll.GetService<TeamSettingsConfigurationService>();
 var css = coll.GetService<ICommonStructureService4>();
 var project = css.GetProjectFromName(projectInfo.ProjectName);

 IEnumerable<TeamConfiguration> configs = teamConfig.GetTeamConfigurationsForUser(new[] { project.Uri.ToString() });
 TeamConfiguration team = configs.FirstOrDefault(x => x.ProjectUri == project.Uri.ToString());

 var iterations = BuildIterationTree(team, css);

BuildIterationTree看起来像...

 private IList<IterationInfo> BuildIterationTree(TeamConfiguration team, ICommonStructureService4 css)
    {
        string[] paths = team.TeamSettings.IterationPaths;

        var result = new List<IterationInfo>();

        foreach (string nodePath in paths.OrderBy(x => x))
        {
            var projectNameIndex = nodePath.IndexOf("\\", 2);
            var fullPath = nodePath.Insert(projectNameIndex, "\\Iteration");
            var nodeInfo = css.GetNodeFromPath(fullPath);
            var name = nodeInfo.Name;
            var startDate = nodeInfo.StartDate;
            var endDate = nodeInfo.FinishDate;

            result.Add(new IterationInfo
            {
                IterationPath = fullPath.Replace("\\Iteration", ""),
                StartDate = startDate,
                FinishDate = endDate,
            });
        }
        return result;
    }

我的问题是...如何获得完整的迭代树,而不是TFS 2013的特定于团队的迭代?

可以将特定于团队的迭代配置为通过Web门户显示或不显示该迭代复选框。

参考方案

您的问题回答了我有关如何获取特定于团队的迭代的问题,因此,我能做的至少是提供可获取完整迭代层次结构的代码段。我想我最初是在this blog上找到此代码的:

    public static void GetIterations(TfsTeamProjectCollection collection,
        ICommonStructureService4 css, ProjectInfo project)
    {
        TeamSettingsConfigurationService teamConfigService = collection.GetService<TeamSettingsConfigurationService>();
        NodeInfo[] structures = css.ListStructures(project.Uri);
        NodeInfo iterations = structures.FirstOrDefault(n => n.StructureType.Equals("ProjectLifecycle"));
        XmlElement iterationsTree = css.GetNodesXml(new[] { iterations.Uri }, true);

        string baseName = project.Name + @"\";
        BuildIterationTree(iterationsTree.ChildNodes[0].ChildNodes, baseName);
    }

    private static void BuildIterationTree(XmlNodeList items, string baseName)
    {
        foreach (XmlNode node in items)
        {
            if (node.Attributes["NodeID"] != null &&
                node.Attributes["Name"] != null &&
                node.Attributes["StartDate"] != null &&
                node.Attributes["FinishDate"] != null)
            {
                string name = node.Attributes["Name"].Value;
                DateTime startDate = DateTime.Parse(node.Attributes["StartDate"].Value, CultureInfo.InvariantCulture);
                DateTime finishDate = DateTime.Parse(node.Attributes["FinishDate"].Value, CultureInfo.InvariantCulture);

                // Found Iteration with start / end dates
            }
            else if (node.Attributes["Name"] != null)
            {
                string name = node.Attributes["Name"].Value;

                // Found Iteration without start / end dates
            }

            if (node.ChildNodes.Count > 0)
            {
                string name = baseName;
                if (node.Attributes["Name"] != null)
                    name += node.Attributes["Name"].Value + @"\";

                BuildIterationTree(node.ChildNodes, name);
            }
        }
    }

改造正在返回一个空的响应主体 - java

我正在尝试使用Retrofit和Gson解析一些JSON。但是,我得到的响应机构是空的。当我尝试从对象中打印信息时,出现NullPointerException。我确保URL正确,并且我也确保POJO也正确。我正在使用jsonschema2pojo来帮助创建POJO类。这是我要解析的JSON{ "?xml": { "@versi…

Google Analytics API - php

我正在实施Google Analytics(分析)Api。授权完成没有问题。成功授权后,我得到403 return code并得到消息:User does not have sufficient permissions for this profile。我的帐户具有Google Analytics(分析)数据,可以跟踪多个网站,并且我可以从网络浏览器访问它而…

我需要帮助将此REST API Curl命令转换为Python请求 - python

我在这里是新手,老实说对所有编码都是新手。我正在尝试创建一个Pyton脚本,以使用REST API从Request Tracker资产数据库中搜索项目。到目前为止,我得到了以下Curl命令:curl -X POST \ -H "Content-Type: application/json" \ -d '[{ "fiel…

通过Rest API C#在Jira中设置自定义单选按钮字段 - c#

我正在尝试设置具有3个可能选项的自定义单选按钮字段的值:是,否或无。我正在使用Dapplo c#Jira SDK。我已经尝试了从使用“名称”到“值”再到“ id”的所有方法,但似乎无济于事,我总是回来“在Parent Option对象中找不到有效的'id'或'value'”。请注意,我想使用选项集值的ID设置字段值,而不是文本值(例如“是”或“否”)来设置字…

从代码和网站调用Web API - c#

首先,我使用C#4.0作为编码语言。我相信我看到了一些答案,其中4.5引入了一些可以使此操作变得容易得多的方法,但这不是我要求更改框架。我正在创建一个MVC4 WebApi,它将同时被网站和C#代码使用(在另一个项目中)。通常,当从JavaScript调用时,我会这样做:$.ajax({ dataType: 'text', url: &#…