J'essaie de créer un élément de travail dans Azure DevOps en utilisant des bibliothèques clientes et en utilisant OAuth comme mécanisme d'authentification.
Cela fonctionne bien sur ma machine locale (lorsque je le débogue localement), mais lève des exceptions chaque fois que déployé sur le cloud ( dans mon cas Azure App service).
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"; } }
L'exception qu'il lance est:
Une ou plusieurs erreurs se sont produites. ex.stacktrace à System.Threading.Tasks.Task.ThrowIfExceptional (Booléen includeTaskCanceledExceptions) à System.Threading.Tasks.Task
1.GetResultCore (Boolean waitCompletionNotification) à System.Threading.Tasks.Task
1.get_Result ()
Cette méthode est appelée directement à partir d'un lien et le jeton d'accès est passé avec lui. Auparavant, j'appelais cette méthode via un appel ajax car je pensais que les appels ajax n'attendaient peut-être pas l'async. Mais il a jeté la même exception.
Ensuite, j'ai changé ma méthode en async / await et l'ai appelée via un lien. Voici le code:
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 }
Ici, je reçois ce genre d'exception et avec la dernière ligne:
d__52.MoveNext () --- Fin de la trace de pile à partir de l'emplacement précédent où une exception a été lancée --- à System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (tâche tâche) à System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (tâche tâche) à Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.d__50.MoveNext () --- Fin de la trace de pile à partir de l'emplacement précédent où l'exception a été levée --- à System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (tâche tâche) à System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (tâche tâche) à Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.d__47
1.MoveNext () --- Fin de la trace de pile à partir de l'emplacement précédent où l'exception a été levée --- à System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (tâche tâche) à System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (tâche tâche) à Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.d__28
1.MoveNext () --- Fin de la trace de pile à partir de l'emplacement précédent où l'exception a été levée --- à System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (tâche tâche) à System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (tâche tâche)Vous devez transmettre un document correctif valide dans le corps de la requête. , sur Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.
Comme j'utilise le mécanisme OAuth, les jetons d'accès sont générés uniquement dans mon application cloud. Donc, pour l'exécuter localement, j'ai créé une application Web Asp.net distincte et je l'ai exécutée localement en transmettant le jeton d'accès généré à partir de mon application cloud.
Et je ne peux pas le souligner assez que les deux méthodes fonctionnent parfaitement bien lorsque je l'ai exécutée localement plusieurs fois.
Cela me frappe gravement, et comme je suis un peu novice dans ce monde de programmation, tout une aide avec un peu de détail sera très appréciée
3 Réponses :
La question similaire était ici: Vous devez transmettre un document correctif valide dans le corps de la requête. WorkItemTrackingHttpClient utilisé
Essayez de mettre à jour pour prévisualiser la version de vos bibliothèques clientes.
Salut @Shamrai, je pense que dans votre cas, vous ne pouvez pas vous autoriser ce qui, au cas où cela lèverait une exception à WorkItemTrackingHttpClient workItemTrackingHttpClient = connection.GetClient
Oui, dans mon cas également l'exception sur l'étape de création d'élément de travail. J'utilise le même jeton d'accès personnel pour VssOAuthAccessTokenCredential et VssBasicCredential. J'utilise cet exemple pour créer wi: github.com/ ashamrai / TFRestApi / blob / master /…
Dans mon cas, InnerException est Microsoft.VisualStudio.Services.Common.VssServiceException: vous devez transmettre un document correctif valide dans le corps de la demande. sur Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase. Bien que ce soit le même document de correctif qui utilise également localement.
@BeginnerTejas Quelle version de nuget.org/packages/Microsoft.TeamFoundationServer.Client utilisez-vous?
Version 15.131.1
@BeginnerTejas Vérifiez cette explication: developercommunity.visualstudio.com/content/problem/416838/... Vous avez peut-être besoin d'une version préliminaire.
Désolé pour la réponse retardée Shamrai. Mais j'ai mis à jour ma réponse. Merci beaucoup pour votre aide :)
Modifier:
Je ne sais vraiment pas comment, mais quand j'ai déployé mon code ci-dessus sur Azure service cloud, cela fonctionne. Mais ça montre encore les exceptions quand je cours it sur Azure App service. Peut-être le service d'application Azure que j'utilisais est venu sous un plan gratuit (sans aucun noyau), donc cela pourrait être le cas. Cependant, veuillez noter que HttpClient a fonctionné dans les deux cas. Espérer cette réponse peut faire gagner du temps à quelqu'un.
Ce code fonctionne très bien. Ici, au lieu d'utiliser WorkItemHttpClient, j'utilise 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; } }Ce code fonctionne très bien en local ainsi que lorsqu'il est déployé sur le cloud. Strong > Je ne sais pas pourquoi WorkItemHttpClient ne fonctionne pas sur le cloud et ne donne pas d'exceptions liées aux événements de threading et de correction, bien que cela fonctionne bien localement. Je fais juste supposer à un profane que WorkItemHttpClient n'est peut-être pas assez puissant que celui de HttpClient et qu'il n'est donc pas capable de créer des éléments de travail lorsqu'il est déployé sur le cloud car il doit le faire plus rapidement. Mais ce n'est qu'une supposition non technique.
Quoi qu'il en soit, j'ai publié cette réponse juste pour qu'une autre personne qui pourrait rencontrer le même problème puisse référer cette solution si elle le souhaite.
Suivez les étapes comme dans la documentation,
Juste une modification,
Au lieu de
WorkItem result = workItemTrackingHttpClient.CreateWorkItemAsync(patchDocument, project, "Issue").Result;
Nouveau code
WorkItem result = workItemTrackingHttpClient.CreateWorkItemAsync(patchDocument, project, "Bug").Result;