Prasaanth Neelakandan Prasaanth Neelakandan - 4 months ago 63
JSON Question

how to pass the following JSON to a C# patch method w or w/o Javascript serializer

I am working on a program to access the REST API for Visual Studio Team Services (was Visual Studio Online). I am following https://www.visualstudio.com/integrate/api/wit/work-items

I was able to query the work item by passing the correct Id using this code snippet:

var uri = new Uri("https://{instance}.visualstudio.com/DefaultCollection/_apis/wit/workitems/7?api-version=1.0");
GetWorkItem(uri);

public static async void GetWorkItem(Uri uri)
{
try
{
var username = "my username";
var password = " my pass word";

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

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", username, password))));

using (HttpResponseMessage response = client.GetAsync(uri)

.Result)
{
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();

Console.WriteLine(responseBody);
}
Console.Read();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.Read();
}
}


It correctly returns a JSON as specified here https://www.visualstudio.com/integrate/api/wit/work-items#GetalistofworkitemsByIDs

Now I am trying to update the work item by modifying its title .

https://www.visualstudio.com/integrate/api/wit/work-items#UpdateworkitemsUpdateafield

For this I wrote a method :

public static async void UpdateWorkItemStatus(Uri requestUri, HttpContent iContent)
{
{
var method = new HttpMethod("PATCH");

var request = new HttpRequestMessage(method, requestUri)
{
Content = iContent
};

HttpResponseMessage response;

try
{
using (HttpClient client = new HttpClient())
{
var username = "my username";
var password = "my password";

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", username, password))));

response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(response);

Console.Read();
}
}
catch (TaskCanceledException e)
{
Console.WriteLine("ERROR: " + e.ToString());
Console.Read();
}

}
}


I am calling this method by passing my json :

var uri = new Uri("https://{instance}.visualstudio.com/DefaultCollection/_apis/wit/workitems/7?api-version=1.0");
string json = new JavaScriptSerializer().Serialize(new
{
op="replace",
path="fields/System.Title",
value=" 123 New Title"

});

HttpContent httpContent = new StringContent(json, Encoding.UTF8, "application/json-patch+json");

UpdateWorkItemStatus(uri, httpContent);


This is in accordance with the information in https://www.visualstudio.com/integrate/api/wit/work-items#Updateworkitems

They don't have any code samples so I used JavascriptSerializer
But this doesn't do anything . The code runs but gives no output and my work item is also not edited. I am not sure if it is incorrect in format due to using JavascriptSerializer but I have used this class before and it has worked well.

Basically I need to pass this JSON :

[
{
"op": "replace",
"path": "fields/System.Title",
"value":"New Title"
}
]


Any help on how to get this running and pass the JSON in a right format would be appreciated even if without using the JS Serializer class.

Eventually the idea is to convert this to an interpreted script that can run on Unix, like curl, Python or Perl. Any pointers or recommendations on that would also be appreciated.

Answer

I usually pass the content strings directly and it works:

string json = "[{\"op\":\"replace\",\"path\":\"/fields/System.Title\",\"value\":\"Title\"}]";

The string json you generated by JavaScriptSerializer is missing "[" and "]".

By the way, with the code you provided, if you run GetWorkItem(uri) before UpdateWorkItemStatus(uri, httpContent), UpdateWorkItemStatus() won't run since the app exit after GetWorkItem().