我正在使用Visual Studio Online REST API,除了创建工作项外,似乎可以使一切工作正常。这不是内部部署安装。我按照这个例子发送一个PATCH但收到400 Bad Request错误。 VSO Create Work Item
Per 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);
}
}
答案 0 :(得分:9)
所有示例看起来都像是在发送一系列操作,而不仅仅是单个操作。我不知道这是否是一项要求。但也许它期望PATCH的主体是一个数组。
你可以尝试发送:
[{"op":"add","path":"/fields/System.Title","value":"JavaScript implementation for Microsoft Account"}]
看看它是否有效?
答案 1 :(得分:0)
将application / json更改为application / json-patch + json似乎对我有用。