Send JSON via POST in C# and Receive the JSON returned?
I found myself using the HttpClient library to query RESTful APIs as the code is very straightforward and fully async'ed. To send this JSON payload:
{ "agent": { "name": "Agent Name", "version": 1 }, "username": "Username", "password": "User Password", "token": "xxxxxx"}
With two classes representing the JSON structure you posted that may look like this:
public class Credentials{ public Agent Agent { get; set; } public string Username { get; set; } public string Password { get; set; } public string Token { get; set; }}public class Agent{ public string Name { get; set; } public int Version { get; set; }}
You could have a method like this, which would do your POST request:
var payload = new Credentials { Agent = new Agent { Name = "Agent Name", Version = 1 }, Username = "Username", Password = "User Password", Token = "xxxxx"};// Serialize our concrete class into a JSON Stringvar stringPayload = JsonConvert.SerializeObject(payload);// Wrap our JSON inside a StringContent which then can be used by the HttpClient classvar httpContent = new StringContent(stringPayload, Encoding.UTF8, "application/json");var httpClient = new HttpClient() // Do the actual request and await the responsevar httpResponse = await httpClient.PostAsync("http://localhost/api/path", httpContent);// If the response contains content we want to read it!if (httpResponse.Content != null) { var responseContent = await httpResponse.Content.ReadAsStringAsync(); // From here on you could deserialize the ResponseContent back again to a concrete C# type using Json.Net}
Using the JSON.NET NuGet package and anonymous types, you can simplify what the other posters are suggesting:
// ...string payload = JsonConvert.SerializeObject(new{ agent = new { name = "Agent Name", version = 1, }, username = "username", password = "password", token = "xxxxx",});var client = new HttpClient();var content = new StringContent(payload, Encoding.UTF8, "application/json");HttpResponseMessage response = await client.PostAsync(uri, content);// ...
You can build your HttpContent
using the combination of JObject
to avoid and JProperty
and then call ToString()
on it when building the StringContent
:
/*{ "agent": { "name": "Agent Name", "version": 1 }, "username": "Username", "password": "User Password", "token": "xxxxxx" }*/ JObject payLoad = new JObject( new JProperty("agent", new JObject( new JProperty("name", "Agent Name"), new JProperty("version", 1) ), new JProperty("username", "Username"), new JProperty("password", "User Password"), new JProperty("token", "xxxxxx") ) ); using (HttpClient client = new HttpClient()) { var httpContent = new StringContent(payLoad.ToString(), Encoding.UTF8, "application/json"); using (HttpResponseMessage response = await client.PostAsync(requestUri, httpContent)) { response.EnsureSuccessStatusCode(); string responseBody = await response.Content.ReadAsStringAsync(); return JObject.Parse(responseBody); } }