我正在尝试使用客户端库并将OAuth作为身份验证机制在Azure DevOps中创建工作项。
它在我的本地计算机上运行良好(当我在本地调试时),但是只要部署在云上(在我的情况下为Azure App服务),都会引发异常。
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在 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调用可能不会等待异步。但是它抛出了同样的异常。
然后,我将方法更改为异步/等待,并通过链接对其进行了调用。 这是代码:
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(任务 任务) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务) Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.d__50.MoveNext() ---从上一个引发异常的位置开始的堆栈跟踪- System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务) 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(任务 任务) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)您必须在请求的正文中传递有效的补丁文档。 ,位于Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase。
由于我使用的是OAuth机制,因此访问令牌仅在我的云应用中生成。 因此,要在本地运行它,我创建了一个单独的Asp.net Web应用程序,并通过传递从我的云应用程序生成的访问令牌在本地运行。
当我在本地多次运行它时,我不能强调得太好,以至于两种方法都运行得很好。
对此我感到很震惊,并且由于我是这个编程世界的新手,因此非常感谢您提供一点细节的帮助
答案 0 :(得分:0)
编辑:
我真的不知道如何,但是当我在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强大,因此部署在云上时无法创建工作项,因为它必须更快地完成工作。但这只是非技术性的猜测。
无论如何,我只是发布此答案,以便其他可能面临相同问题的其他人可以根据需要引用此解决方案。
答案 1 :(得分:0)
按照文档中的步骤进行操作
只需更改
代替
WorkItem result = workItemTrackingHttpClient.CreateWorkItemAsync(patchDocument, project, "Bug").Result;
新代码
WorkItem result = workItemTrackingHttpClient.CreateWorkItemAsync(patchDocument, project, "Issue").Result;