Проблема при создании рабочего элемента Azure DevOps с полями Microsoft.VSTS.Common.Priority и Microsoft.VSTS.Common.StackRank

У меня возникли проблемы с созданием нового рабочего элемента в Azure DevOps с помощью REST API. В частности, я хочу включить поля Microsoft.VSTS.Common.Priority и Microsoft.VSTS.Common.StackRank, но моя текущая реализация, похоже, работает неправильно.

Вот метод, который я использую для создания рабочего элемента:

public WorkItemDTO CreateWorkItem(WorkItemDTO workItem, string workItemType)
{
    string tokenFormat = $"{string.Empty}:{GetTokenConfig()}";
    string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(tokenFormat));

    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri($"{DEVOPS_ORG_URL}/{GetProjectNameConfig()}/");
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json-patch+json"));
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);

        string uri = $"_apis/wit/workitems/${workItemType}?api-version=7.1-preview.3";

        var patchDocument = new[]
        {
            new { op = "add", path = "/fields/System.Title", value = workItem.Title },
            new { op = "add", path = "/fields/System.Description", value = workItem.Description },
            new { op = "add", path = "/fields/Microsoft.VSTS.Common.Priority", value = workItem.Priority },
            new { op = "add", path = "/fields/Microsoft.VSTS.Common.StackRank", value = workItem.BusinessValue }
        };

        var jsonContent = JsonConvert.SerializeObject(patchDocument);
        var content = new StringContent(jsonContent, Encoding.UTF8, "application/json-patch+json");

        HttpResponseMessage response = client.PostAsync(uri, content).Result;

        if (response.IsSuccessStatusCode)
        {
            string responseBody = response.Content.ReadAsStringAsync().Result;
            var createdWorkItemEntity = JsonConvert.DeserializeObject<WorkItemEntity>(responseBody);
            var createdWorkItemDTO = _mapper.Map<WorkItemDTO>(createdWorkItemEntity);
            return createdWorkItemDTO;
        }
        else
        {
            Console.WriteLine("Error creating work item. Status code: " + response.StatusCode);
            string responseBody = response.Content.ReadAsStringAsync().Result;
            Console.WriteLine("Response body: " + responseBody);
        }
    }

    return null;
}

Что я пробовал:

Я использовал документ исправления JSON, чтобы включить поля Microsoft.VSTS.Common.Priority и Microsoft.VSTS.Common.StackRank. Я отправил запрос POST в REST API Azure DevOps с указанным выше документом исправления JSON. Чего я ожидал:

Новый рабочий элемент должен быть создан с полями Microsoft.VSTS.Common.Priority и Microsoft.VSTS.Common.StackRank, установленными в соответствии с предоставленными значениями. Что произошло на самом деле:

Рабочий элемент создан успешно, но поля Microsoft.VSTS.Common.Priority и Microsoft.VSTS.Common.StackRank не заполняются предоставленными значениями. Ответ API не предоставляет полезной информации о том, почему эти поля не устанавливаются. Вопросы:

Правильно ли указаны поля Microsoft.VSTS.Common.Priority и Microsoft.VSTS.Common.StackRank в документе исправления? Может ли быть проблема с API версии 7.1-preview.3 или именами полей? Есть ли что-то особенное, что мне не хватает в формате запроса или использовании API?

Rest API должен поддерживать настройку полей Priority и StackRank. Проблема может быть связана с определением понятия patchDocument. Вы можете обратиться к моему ответу, внести изменения в определение patchDocument и проверить, может ли оно работать.

Kevin Lu-MSFT 19.07.2024 11:32
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я могу воспроизвести аналогичную проблему при использовании примера кода.

Причиной проблемы может быть проблема с контентом patchDocument. Если мы используем то же определение, что и ваше, поля Priority и StackRank требуют ввода строкового типа.

Чтобы решить эту проблему, вы можете использовать следующий формат для определения patchDocument:

   var patchDocument = new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchDocument();
   patchDocument.Add(
    new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
    {
        Path = "/fields/System.Description",
        Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
        Value = workItem.Description
    });
   patchDocument.Add(
    new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
    {
        Path = "/fields/System.Title",
        Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
        Value = workItem.Title
    });
   patchDocument.Add(
      new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
      {
          Path = "/fields/Microsoft.VSTS.Common.Priority",
          Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
          Value = workItem.Priority
      });
   patchDocument.Add(
      new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
      {
          Path = "/fields/Microsoft.VSTS.Common.StackRank",
          Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
          Value = workItem.BusinessValue
      });

Вот полный образец:

using Newtonsoft.Json;
using System.Net.Http.Headers;
using System.Text;

public WorkItemDTO CreateWorkItem(WorkItemDTO workItem, string workItemType)
{
    string tokenFormat = $"{string.Empty}:{GetTokenConfig()}";
    string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(tokenFormat));

    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri($"{DEVOPS_ORG_URL}/{GetProjectNameConfig()}/");
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json-patch+json"));
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);

        string uri = $"_apis/wit/workitems/${workItemType}?api-version=7.1-preview.3";

        var patchDocument = new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchDocument();
        patchDocument.Add(
         new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
         {
             Path = "/fields/System.Description",
             Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
             Value = workItem.Description
         });
        patchDocument.Add(
         new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
         {
             Path = "/fields/System.Title",
             Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
             Value = workItem.Title
         });
        patchDocument.Add(
           new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
           {
               Path = "/fields/Microsoft.VSTS.Common.Priority",
               Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
               Value = workItem.Priority
           });
        patchDocument.Add(
           new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
           {
               Path = "/fields/Microsoft.VSTS.Common.StackRank",
               Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
               Value = workItem.BusinessValue
           });

        var jsonContent = JsonConvert.SerializeObject(patchDocument);
        var content = new StringContent(jsonContent, Encoding.UTF8, "application/json-patch+json");

        HttpResponseMessage response = client.PostAsync(uri, content).Result;

        if (response.IsSuccessStatusCode)
        {
            string responseBody = response.Content.ReadAsStringAsync().Result;
            var createdWorkItemEntity = JsonConvert.DeserializeObject<WorkItemEntity>(responseBody);
            var createdWorkItemDTO = _mapper.Map<WorkItemDTO>(createdWorkItemEntity);
            return createdWorkItemDTO;
        }
        else
        {
            Console.WriteLine("Error creating work item. Status code: " + response.StatusCode);
            string responseBody = response.Content.ReadAsStringAsync().Result;
            Console.WriteLine("Response body: " + responseBody);
        }
    }

    return null;
}

Класс WorkItemDTO:

public class WorkItemDTO
{
    public int Id { get; set; }
    public int Rev { get; set; }
    public string Type { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string State { get; set; }
    public string Url { get; set; }
    public int Priority { get; set; }  // Add Priority property
    public double BusinessValue { get; set; }  // Add BusinessValue propert
}

Результат:

Другие вопросы по теме