Azure DevOps API 问题:新创建的区域路径无法立即识别

问题描述 投票:0回答:1

我正在使用 Azure DevOps API 在项目中创建嵌套区域路径。我的代码创建一个子项,然后立即尝试在其下添加一个子项,依此类推,以创建一个多层结构。

我面临的问题是,在创建第一个子项之后,当我尝试创建子项时,API 会抛出错误,指出路径不存在。但是,如果我重新运行代码或稍等一下再试一次,路径就在那里,并且子级会被很好地创建。

Azure DevOps 完全提交新创建的区域路径似乎存在延迟,这导致下一个 API 调用失败,因为它还找不到新添加的父路径。

public async Task<WorkItemClassificationNode> CreateAreaPath(WorkItemTrackingHttpClient client, string projectName, WorkItemClassificationNode currentNode, string areaPath)
{
    string[] areaParts = areaPath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
    string[] fullAreaParts = new string[areaParts.Length + 1];
    fullAreaParts[0] = projectName; // Add project name as the root
    Array.Copy(areaParts, 0, fullAreaParts, 1, areaParts.Length);
    int matchIndex = Array.FindIndex(fullAreaParts, part => part.Equals(currentNode.Name, StringComparison.OrdinalIgnoreCase));

    if (matchIndex >= 0)
    {
        string cleanedPath = CleanePath(currentNode.Path);
        string[] remainingParts = fullAreaParts.Skip(matchIndex + 1).ToArray();
        
        foreach (string part in remainingParts)
        {
            var newNode = new WorkItemClassificationNode()
            {
                Name = part,
                StructureType = TreeNodeStructureType.Area,
            };

            var resultNode = await client.CreateOrUpdateClassificationNodeAsync(newNode, projectName, TreeStructureGroup.Areas, cleanedPath);
            
            currentNode = resultNode;
            cleanedPath += $"/'{part}'";
        }

        return currentNode;
    }
    else
    {
        Console.WriteLine($"Deepest Node '{currentNode.Name}' not found in '{areaPath}'");
        return null;
    }
}

像这样的 Main()

WorkItemClassificationNode deepestNode = await helper.CreateAreaPath(workItemTrackingClient, projectName2, furthestChild, "Child1/ChildChild/ChildChildChild");

因此,如果我最远的Child是Child1,该函数应该添加ChildChild,然后添加ChildChildChild。

所以第一次调用该方法后,只创建了ChildChild,然后创建ChildChildChild时出现错误。

再次运行该方法后,该方法成功创建了ChildChildChild。所以现在只能向现有节点添加一级子节点。

azure azure-devops azure-functions
1个回答
0
投票

我添加了一些输出进行检查,对您的代码做了轻微的更改,

ChildChild
ChildChildChild
分层区域路径已成功创建。

请检查以下脚本:

using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models;
using Microsoft.VisualStudio.Services.WebApi;
using System.Collections.Generic;
using Microsoft.VisualStudio.Services.Common;

public class AreaPathHelper
{
    public async Task<WorkItemClassificationNode> CreateAreaPath(WorkItemTrackingHttpClient client, string projectName, WorkItemClassificationNode currentNode, string areaPath)
    {
        string[] areaParts = areaPath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
        string[] fullAreaParts = new string[areaParts.Length + 1];
        fullAreaParts[0] = projectName; // Add project name as the root
        Array.Copy(areaParts, 0, fullAreaParts, 1, areaParts.Length);

        Console.WriteLine("Full Area Parts: " + string.Join(", ", fullAreaParts));

        int matchIndex = Array.FindIndex(fullAreaParts, part => part.Equals(currentNode.Name, StringComparison.OrdinalIgnoreCase));

        Console.WriteLine("Match Index: " + matchIndex);

        if (matchIndex >= 0)
        {
            string cleanedPath = CleanPath(currentNode.Path);
            string[] remainingParts = fullAreaParts.Skip(matchIndex + 1).ToArray();

            foreach (string part in remainingParts)
            {
                var newNode = new WorkItemClassificationNode()
                {
                    Name = part,
                    StructureType = TreeNodeStructureType.Area,
                };

                var resultNode = await client.CreateOrUpdateClassificationNodeAsync(newNode, projectName, TreeStructureGroup.Areas, cleanedPath);

                currentNode = resultNode;
                cleanedPath += $"/{part}";
            }

            return currentNode;
        }
        else
        {
            Console.WriteLine($"Deepest Node '{currentNode.Name}' not found in '{areaPath}'");
            return null;
        }
    }

    private string CleanPath(string path)
    {
        // Implement your path cleaning logic here if needed
        return path;
    }
}

public class Program
{
    public static async Task Main(string[] args)
    {
        var workItemTrackingClient = new WorkItemTrackingHttpClient(new Uri("https://dev.azure.com/orgname"), new VssBasicCredential(string.Empty, "yourPAT"));
        var helper = new AreaPathHelper();
        string projectName2 = "project1";
        var furthestChild = new WorkItemClassificationNode { Name = "Child1", Path = "Child1" };

        WorkItemClassificationNode deepestNode = await helper.CreateAreaPath(workItemTrackingClient, projectName2, furthestChild, "Child1/ChildChild/ChildChildChild");

        if (deepestNode != null)
        {
            Console.WriteLine($"Deepest Node Created: {deepestNode.Name}");
        }
    }
}

确保将“https://dev.azure.com/orgname”、“yourPAT”、“ProjectName”、节点名称和路径名称分别替换为您的实际值。

我的原来区域路径:

enter image description here

执行的脚本:

enter image description here

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.