VSO API工作项PATCH出现400 Bad Request错误

4
我正在使用Visual Studio Online REST API,除了创建工作项之外,似乎可以做到其他所有事情。这不是一个本地安装。我遵循此示例并发送PATCH请求,但收到400 Bad Request错误。VSO Create Work Item 根据Fiddler,这是我的原始请求:
    PATCH https://xxx.visualstudio.com/defaultcollection/myproject/_apis/wit/workitems/$Task?api-version=1.0 HTTP/1.1
Accept: application/json
Authorization: Basic RmI3etc_etc_etc==
Content-Type: application/json-patch+json; charset=utf-8
Host: xxx.visualstudio.com
Content-Length: 101
Expect: 100-continue
Connection: Keep-Alive

{"op":"add","path":"/fields/System.Title","value":"JavaScript implementation for Microsoft Account"}

我收到的响应是400 Bad Request:

{"$id":"1","innerException":null,"message":"You must pass a valid patch document in the body of the request.","typeName":"Microsoft.VisualStudio.Services.Common.VssPropertyValidationException, Microsoft.VisualStudio.Services.Common, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03ftoken0a3a","typeKey":"VssPropertyValidationException","errorCode":0,"eventId":3000}

我不确定为什么会提示补丁文档无效。
更新:按照请求,分享一些代码。我修改了我的库。以下是我编写的代码,可以轻松地将工作项添加到项目中(产品待办事项、缺陷等)。
public void AddWorkItem(VSOWorkItem workItem, string project)
    {
        Project = project;

        using (HttpClient client = new HttpClient())
        {
            client.DefaultRequestHeaders.Accept.Add(
            new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

            //Set alternate credentials
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(
                    System.Text.ASCIIEncoding.ASCII.GetBytes(
                        string.Format("{0}:{1}", UserName, Password))));

            var workItems = new List<VSOFieldPatch>();
            workItems.Add(new VSOFieldPatch() { Op = "add", Path = "/fields/" + VSOWorkItemFieldName.Title, Value = workItem.Title });
            workItems.Add(new VSOFieldPatch() { Op = "add", Path = "/fields/" + VSOWorkItemFieldName.Description, Value = workItem.Description });

            if (!string.IsNullOrEmpty(workItem.Tags))
                workItems.Add(new VSOFieldPatch() { Op = "add", Path = "/fields/" + VSOWorkItemFieldName.Tags, Value = workItem.Tags });

            var resp = AddWorkItemAsync(client, workItems, BaseProjectUrl + "wit/workitems/$" + workItem.WorkItemType.ToString());
        }

    }


 private async Task<String> AddWorkItemAsync(HttpClient client,
                                      IEnumerable<VSOFieldPatch> data,
                                      String apiUrl)
    {
        var responseBody = String.Empty;

        var temp = JsonConvert.SerializeObject(data);

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

        try
        {
            using (HttpResponseMessage response = client.PatchAsync(apiUrl + ApiVersion, content).Result)
            {
                response.EnsureSuccessStatusCode();
                responseBody = await response.Content.ReadAsStringAsync();
            }
        }
        catch (Exception ex)
        {

        }

        return responseBody;
    }

这是我所创建的PATCH扩展程序:

public static class HttpClientExtensions
{

    public static Task<HttpResponseMessage> PatchAsync(this HttpClient client, string requestUri, HttpContent content)
    {
        HttpRequestMessage request = new HttpRequestMessage
        {
            Method = new HttpMethod("PATCH"),
            RequestUri = new Uri(client.BaseAddress + requestUri),
            Content = content,
        };

        return client.SendAsync(request);
    }


}

先生,您能否为我提供完整的代码示例以供参考?我正在使用JavascriptSerializer发送一个Patch请求。 - Ace McCloud
@PrasaanthNeelakandan 看看这是否有帮助 - Papa Burgundy
我有几乎完全相同的代码,但它不起作用...http://stackoverflow.com/questions/36023821/how-to-pass-the-following-json-to-a-c-sharp-patch-method-w-or-w-o-javascript-ser - Ace McCloud
那个问题我也尝试了第一个答案...我用POSTMAN检查了Patch请求,它返回了“所请求的资源不支持HTTP方法'PATCH'”。 - Ace McCloud
我正在尝试更新一个字段,但不希望创建一个工作项。 - Ace McCloud
我知道你几个月前尝试过这个...但如果你能指导一下呢?我尝试了很多JSON组合..不确定是JSON格式引起的。 - Ace McCloud
2个回答

10

所有的示例看起来都像是发送了一个操作数组,而不仅仅是一个单独的操作。我不知道这是否是必需的,但也许它期望PATCH请求体是一个数组。

你可以尝试发送:

[{"op":"add","path":"/fields/System.Title","value":"JavaScript implementation for Microsoft Account"}]

看看它是否有效?


谢谢Tim,我甚至没有注意到,但现在看来你可能是对的。让我试一试。 - Papa Burgundy
搞定了!是我疏忽了,感谢您的帮助,让我看到了新的方向。 - Papa Burgundy
1
@scottndecker 看看这能否帮助到您。 - Papa Burgundy
@PapaBurgundy 确实如此。与此同时,我已经能够解决问题,并实现了类似的功能,其中我构建了一个项目列表,对其进行序列化(这是添加缺少的[]的地方),然后将其PATCH到VSTS上。感谢您的分享!只是好奇,你们用VSTS Rest API做什么?似乎没有很多人在使用它,但我迄今为止很喜欢它。 - Scott Decker
@scottndecker 我们正在与用户测试一种通信想法。目前,我们在其中一个应用程序上提供了一个支持页面,应用程序所有者可以访问该页面。他们可以提交新功能或错误的想法。它会自动显示在我的VSTS列表中作为工作项。我给它们全部打上“用户生成”的标签,以便我知道它来自于他们。此外,在VSTS中,您可以设置当添加新的工作项时发送电子邮件通知。所以这很有趣。到目前为止,我们很喜欢它。 - Papa Burgundy
显示剩余2条评论

2

对我来说,将application/json更改为application/json-patch+json似乎解决了问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接