Калибровка workItemTrackingHttpClient.CreateWorkItemAsync () вызывает различные исключения при развертывании в облаке - PullRequest
2 голосов
/ 08 марта 2019

Я пытаюсь создать рабочий элемент в DevOps Azure, используя клиентские библиотеки и используя OAuth в качестве механизма аутентификации.

Он отлично работает на моем локальном компьютере (когда я отлаживаю его локально), но выдает исключения при развертывании в облаке (в моем случае, в службе приложений Azure).

public string CreateWorkItemDemo(string accesstoken)
    {
        try
        {
            Uri _uri = new Uri("https://xyz.visualstudio.com");
            JsonPatchDocument patchDocument = new JsonPatchDocument();
            string project = "abcproject";
            patchDocument.Add(
                new JsonPatchOperation()
                {
                    Operation = Operation.Add,
                    Path = "/fields/System.Title",
                    Value = "Test item created through token two"
                });
            patchDocument.Add(
                new JsonPatchOperation()
                {
                    Operation = Operation.Add,
                    Path = "/fields/System.AreaPath",
                    Value = string.Format("{0}", project)
                });
            try
            {
                VssConnection connection = new VssConnection(_uri, new VssOAuthAccessTokenCredential(accesstoken));
                WorkItemTrackingHttpClient workItemTrackingHttpClient = connection.GetClient<WorkItemTrackingHttpClient>();
                try
                {
                    var result = workItemTrackingHttpClient.CreateWorkItemAsync(patchDocument, project, "Bug").Result; //This line of code throws exception
                    return result.Id.Value.ToString();
                }
                catch (Exception ex)
                {
                   //The exceptions is logged from here.
                }
            }
            catch (Exception ex)
            {
                 //Exception messages here
            }
        }
        catch (Exception exception)
        {
               //Exception messages here
        }

Исключение составляет:

Произошла одна или несколько ошибок. ex.stacktrace at System.Threading.Tasks.Task.ThrowIfExceptional (Boolean includeTaskCanceledExceptions) в System.Threading.Tasks.Task 1.GetResultCore(Boolean waitCompletionNotification) at System.Threading.Tasks.Task 1.get_Result ()

Этот метод вызывается непосредственно из ссылки, и вместе с ним передается маркер доступа. Ранее я вызывал этот метод через вызов ajax, так как думал, что вызовы ajax не ожидают асинхронного вызова. Но это бросило то же исключение.

Затем я изменил свой метод на async / await и вызвал его по ссылке. Вот код:

public async Task<string> CreateItem(string accesstoken)
    {
        string _uri = "https://xyz.visualstudio.com";
        Uri uri = new Uri(_uri);
        string project = "abcproject";
        JsonPatchDocument patchDocument = new JsonPatchDocument();
        patchDocument.Add(
            new JsonPatchOperation()
            {
                Operation = Operation.Add,
                Path = "/fields/System.Title",
                Value = "Test item created through code seven"
            });
        patchDocument.Add(
            new JsonPatchOperation()
            {
                Operation = Operation.Add,
                Path = "/fields/System.AreaPath",
                Value = string.Format("{0}", project)
            });
        try
        {
            VssConnection connection = new VssConnection(uri, new VssOAuthAccessTokenCredential(accesstoken));
            WorkItemTrackingHttpClient workItemTrackingHttpClient = connection.GetClient<WorkItemTrackingHttpClient>();
            try
            {
                var response = await workItemTrackingHttpClient.CreateWorkItemAsync(patchDocument, project, "Bug");

                return "Successfully created bug with Id" + response.Id.Value.ToString();
            }
            catch (Exception ex)
            {
                //Exceptions are logging here
                return ex.Message + " ," + ex.StackTrace + " One here";
            }
        }
        catch (Exception ex)
        {
            return ex.Message + " ," + ex.StackTrace + " 2 here";
        }
    }

Здесь я получаю такое исключение и с последней строкой:

d__52.MoveNext () --- Конец трассировки стека от предыдущего местоположения, где исключение было брошено --- в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Task задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task задача) в Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.d__50.MoveNext () --- Конец стека трассировки из предыдущего места, где было сгенерировано исключение --- в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Task задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task задача) в Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.d__47 1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.d__28 1.MoveNext () --- Конец стека трассировки из предыдущего места, где было сгенерировано исключение --- в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Task задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task задание)

Вы должны передать действительный патч-документ в теле запроса. , в Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.

Поскольку я использую механизм OAuth, маркеры доступа генерируются только в моем облачном приложении. Поэтому, чтобы запустить его локально, я создал отдельное веб-приложение Asp.net и запустил его локально, передав токен доступа, сгенерированный из моего облачного приложения.

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

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

Ответы [ 2 ]

0 голосов
/ 13 марта 2019

Редактировать:

Я серьезно не знаю как, но когда я развернул код, описанный выше, в облачной службе Azure, он работает.Но все равно отображаются исключения, когда я запускаю его в службе приложений Azure.Возможно, я использовал службу приложений Azure по бесплатному плану (без каких-либо ядер), так что это может быть именно так.Однако обратите внимание, что HttpClient работал в обоих случаях.Надеюсь, что этот ответ может сэкономить время.

Этот код работает нормально.Здесь вместо WorkItemHttpClient я использую HttpClient.


public async Task<string> CreateWorkItemUsingHttpClient(string accesstoken)
    {
        try
        {
            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json-patch+json"));
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accesstoken);
            WorkItemPostData wiPostData = new WorkItemPostData();
            wiPostData.op = "add";
            wiPostData.path = "/fields/System.Title";
            wiPostData.value = "Workitem created through cloud";
            List<WorkItemPostData> wiPostDataArr = new List<WorkItemPostData> { wiPostData };
            string wiPostDataString = JsonConvert.SerializeObject(wiPostDataArr);
            HttpContent wiPostDataContent = new StringContent(wiPostDataString, Encoding.UTF8, "application/json-patch+json");
            string url = "https://dev.azure.com/xyz/abcproject/_apis/wit/workitems/$Bug?api-version=5.0";
            try
            {
                HttpResponseMessage response = client.PatchAsync(url, wiPostDataContent).Result;
                try
                {
                    if (response.IsSuccessStatusCode)
                    {
                        response.EnsureSuccessStatusCode();
                        string responseContent = await response.Content.ReadAsStringAsync();
                        return responseContent;
                    }
                    else
                    {
                        return "Success code returned false";
                    }
                }
                catch(Exception ex)
                {
                    return "One " +ex.Message + " " + ex.StackTrace;
                }
            }
            catch(Exception ex)
            {
                return "Two " +ex.Message + " " + ex.StackTrace;
            }
        }
        catch(Exception ex)
        {
            return "Three " +ex.Message + " " + ex.StackTrace;
        }
    }

Этот код прекрасно работает как локально, так и при развертывании в облаке. Я не знаю почемуWorkItemHttpClient не работает в облаке и дает исключения, связанные с многопоточностью и исправлениями событий, хотя локально работает нормально.Я просто заставляю непрофессионала догадываться, что, возможно, WorkItemHttpClient не настолько мощный, как у HttpClient, и, следовательно, он не может создавать рабочие элементы при развертывании в облаке, поскольку должен делать это быстрее.Но это всего лишь техническая догадка.

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

0 голосов
/ 12 марта 2019

Подобный вопрос был здесь: Вы должны передать действительный патч-документ в теле запроса. Используется WorkItemTrackingHttpClient

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

Попробуйте обновить версию для предварительного просмотра ваших клиентских библиотек.

...