Ошибка «Значение не может быть нулевым: имя_узла» при создании новой итерации

Я получаю сообщение об ошибке при попытке создать новую итерацию с помощью клиентского SDK:

Значение не может быть нулевым. Имя параметра: nodeName

В качестве теста я попытался создать его с помощью Postman и REST API, как было предложено здесь, и это удалось.

Я успешно использую это уже довольно давно, чтобы заглушить свою иерархию спринтов на год. Это первый подобный случай этой ошибки — прошлые годовые пробеги прошли без сучка и задоринки. Я ничего не изменил (из того, что знаю) с прошлогоднего успешного пробега.

Как мы видим, свойство Name итерации установлено правильно. Я пробовал Overloads вместо Shadows, но это не помогло.

Как я могу устранить эту проблему, чтобы узнать, что такое nodeName и как заполнить его с помощью Client SDK?

Вот мой код:

Module Main()
  Private Sub AddYear(Year As Integer, Client As WorkItemTrackingHttpClient)
    Dim oIterationYear As Classifications.Iteration
    Dim dFinishDate As Date
    Dim dStartDate As Date

    Console.WriteLine($"Year:{vbTab}{vbTab}{Year}")

    dFinishDate = New Date(Year, 12, 31)
    dStartDate = New Date(Year, 1, 1)

    oIterationYear = New Classifications.Iteration(Client, TeamProject, Year, dStartDate, dFinishDate)
    oIterationYear.Save()

    ...

  End Sub
End Module

Public Class Iteration
  Inherits Base

  Public Sub New(Client As WorkItemTrackingHttpClient, TeamProject As TeamProjects, Name As String, StartDate As Date, FinishDate As Date)
    Me.New(Client, TeamProject, Name, StartDate, FinishDate, Nothing)
  End Sub

  Public Sub New(Client As WorkItemTrackingHttpClient, TeamProject As TeamProjects, Name As String, StartDate As Date, FinishDate As Date, Parent As Iteration)
    MyBase.New(Client, TeamProject, Parent)

    Me.StructureType = TreeNodeStructureType.Iteration
    Me.FinishDate = FinishDate
    Me.StartDate = StartDate
    Me.Name = Name
  End Sub

  ...

End Class

Public MustInherit Class Base
  Inherits WorkItemClassificationNode

  Public Sub New(Client As WorkItemTrackingHttpClient, TeamProject As TeamProjects, Parent As Base)
    Me.ProjectName = TeamProject.ToDescription
    Me.Parent = Parent
    Me.Client = Client
  End Sub

  Public Sub Save()
    If Me.Parent.IsNothing Then
      Me.Node = Me.Client.CreateOrUpdateClassificationNodeAsync(Me, Me.ProjectName, Me.StructureType).Result <-- Error
    Else
      Me.Node = Me.Client.CreateOrUpdateClassificationNodeAsync(Me, Me.ProjectName, Me.StructureType, path:=Me.Path).Result
    End If
  End Sub

  ...

  Public Shadows Property Name As String
    Get
      If Me.Node.IsNothing Then
        Name = Me._Name
      Else
        Name = Me.Node.Name
      End If
    End Get
    Set(Value As String)
      Me._Name = Value
    End Set
  End Property
  Private _Name As String
End Class

Примечание: это вопрос, не зависящий от языка, поэтому я намеренно опустил тег VB.NET. Ответ может прийти либо на VB.NET, либо на C# — меня устраивает любой из них.

-- РЕДАКТИРОВАТЬ --

Основываясь на предложениях по дизайну, найденных в принятом ответе, я придумал это решение, которое работает:

Public MustInherit Class Base
  Public Sub New(Client As WorkItemTrackingHttpClient, TeamProject As TeamProjects, Parent As Base)
    Me.Node = New WorkItemClassificationNode With {
      .StructureType = StructureType,
      .Name = Name
    }

    Me.ProjectName = TeamProject.ToDescription
    Me.Parent = Parent
    Me.Client = Client
    Me.Name = Name
  End Sub

  Public Sub Save()
    If Me.Parent.IsNothing Then
      Me.Node = Me.Client.CreateOrUpdateClassificationNodeAsync(Me.Node, Me.ProjectName, Me.StructureType).Result
    Else
      Me.Node = Me.Client.CreateOrUpdateClassificationNodeAsync(Me.Node, Me.ProjectName, Me.StructureType, path:=Me.Path).Result
    End If
  End Sub

  ...

  Public Property Name As String
    Get
      Return Me.Node.Name
    End Get
    Private Set(Value As String)
      Me.Node.Name = Value
    End Set
  End Property
End Class

По сути, все, что я сделал, это удалил наследование базового класса от WorkItemClassificationNode и во всех случаях сохранил внутреннюю ссылку на узел. Я также упростил реализацию свойства Name.

Что касается того, почему он внезапно перестал работать без изменений в моем коде, единственное, о чем я могу думать, это отдаленная возможность того, что в компиляторе было изменение, которое повлияло на то, как SDK оценивает ключевые слова Shadows и Overloads. Я знаю, что это далеко не так, но иначе я в полной растерянности.

Суть в том, что теперь это работает.

Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
Создание ресурсов API Laravel: Советы по производительности и масштабируемости
Создание ресурсов API Laravel: Советы по производительности и масштабируемости
Создание API-ресурса Laravel может быть непростой задачей. Она требует глубокого понимания возможностей Laravel и лучших практик, чтобы обеспечить...
Как создать простое погодное приложение на Python с API OpenWeatherMap
Как создать простое погодное приложение на Python с API OpenWeatherMap
Этот учебник проведет вас через процесс создания простого погодного приложения с помощью Python и OpenWeatherMap API.
Пакеты Java
Пакеты Java
Пакет java - это группа классов, интерфейсов и подпакетов схожего типа. Думайте об этом как о папке в каталоге файлов. Мы используем пакеты, чтобы...
Как использовать API парсинга квитанций с помощью JavaScript за 5 минут?
Как использовать API парсинга квитанций с помощью JavaScript за 5 минут?
В этом руководстве вы узнаете, как использовать API парсинга квитанций за 5 минут с помощью JavaScript. Eden AI предоставляет простой и удобный для...
0
0
404
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Я могу создать новую итерацию, используя Microsoft.TeamFoundation.WorkItemTracking.WebApi в Azure DevOps Services .NET SDK.

Пожалуйста, ознакомьтесь с приведенным ниже примером:

 class Program
    {
        static void Main(string[] args)
        {
           
            Uri accountUri = new Uri("https://dev.azure.com/org/");
            string personalAccessToken = "pat";
           
            VssConnection _connection = new VssConnection(accountUri, new VssBasicCredential(string.Empty, personalAccessToken));
            WorkItemTrackingHttpClient workItemTrackingHttpClient = _connection.GetClient<WorkItemTrackingHttpClient>();

            Iteration iteration = new Iteration(workItemTrackingHttpClient,2021, "projectName");
            iteration.SaveNode();
        }
          
    }

public class Iteration
    {
        WorkItemTrackingHttpClient client;
        WorkItemClassificationNode node;
        string project;
        string path;
        public Iteration(WorkItemTrackingHttpClient client, int Year, string project, string path=null) {
            this.client = client;
            node = new WorkItemClassificationNode();
            this.project = project;
            this.path = path;
            IDictionary<string, object> DateAttr = new Dictionary<string, object>();
            DateAttr.Add("startDate", new DateTime(Year, 1, 1));
            DateAttr.Add("finishDate", new DateTime(Year, 12, 31));
            node.Attributes = DateAttr;
            node.Name = Year.ToString();
            node.StructureType = TreeNodeStructureType.Iteration;

        }

        public void SaveNode()
        {
            var res = client.CreateOrUpdateClassificationNodeAsync(node, project, TreeStructureGroup.Iterations, path).Result;
            Console.WriteLine(res.Id);
        }
    }

См. ниже результат:

Я могу воспроизвести вышеуказанную ошибку Value cannot be null. Parameter name: nodeName. Если я намеренно не установил node.Name = null; Вы можете отладить свой код, чтобы проверить, почему не было задано имя узла.

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

InteXX 17.12.2020 14:03

@InteXX У вас была возможность проверить приведенный выше пример. Как прошло?

Levi Lu-MSFT 22.12.2020 03:24

Спасибо, что заглянули — это в списке на завтра (вторник).

InteXX 22.12.2020 05:26

Ваш код работает. Мой нет. Что странно, поскольку мы видим, что я устанавливаю свойство Name в конструкторе класса Iteration. Единственная принципиальная разница между вашим кодом и моим заключается в том, что ваш создает экземпляр нового WorkItemClassificationNode объекта в SaveNode() методе. Мой базовый класс наследует WorkItemClassificationNode напрямую. Эта конструкция исправно служит мне уже по крайней мере четыре года — эта новая неудача очень внезапна и неожиданна. Очевидно, что-то изменилось, я просто не знаю что, за исключением того, что это был не мой код.

InteXX 23.12.2020 02:30

Мне пришлось бы выдергивать кишки из всего приложения, если бы я принял вашу концепцию, а там тонна кода. Я в тупике. Есть ли способ проверить JSON, отправленный в API?

InteXX 23.12.2020 02:30

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

InteXX 23.12.2020 16:21

Я все еще в этом, и я делаю хорошие успехи, но я внезапно зациклился на том, что должно быть второстепенным моментом. Я не могу добавить существующую область в существующую команду (stackoverflow.com/q/65472137). Вы можете помочь?

InteXX 28.12.2020 03:05

@InteXX. Как вы решили вышеуказанную проблему создания итерации? Не могли бы вы поделиться своим решением? Что касается добавления существующей области в команду. Вы можете проверить метод UpdateTeamFieldValuesAsync.

Levi Lu-MSFT 28.12.2020 06:59

К вашему сведению, я обновил свой вопрос, включив в него свое окончательное решение. Спасибо вам за вашу помощь.

InteXX 29.12.2020 10:43

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