How to post JSON to a server using C#?
C#JsonPostHttpwebrequestC# Problem Overview
Here's the code I'm using:
// create a request
HttpWebRequest request = (HttpWebRequest)
WebRequest.Create(url); request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
request.Method = "POST";
// turn our request string into a byte stream
byte[] postBytes = Encoding.UTF8.GetBytes(json);
// this is important - make sure you specify type this way
request.ContentType = "application/json; charset=UTF-8";
request.Accept = "application/json";
request.ContentLength = postBytes.Length;
request.CookieContainer = Cookies;
request.UserAgent = currentUserAgent;
Stream requestStream = request.GetRequestStream();
// now send it
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
// grab te response and print it out to the console along with the status code
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string result;
using (StreamReader rdr = new StreamReader(response.GetResponseStream()))
{
result = rdr.ReadToEnd();
}
return result;
When I'm running this, I'm always getting 500 internal server error.
What am I doing wrong?
C# Solutions
Solution 1 - C#
The way I do it and is working is:
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://url");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"user\":\"test\"," +
"\"password\":\"bla\"}";
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
I wrote a library to perform this task in a simpler way, it is here: https://github.com/ademargomes/JsonRequest
Solution 2 - C#
Ademar's solution can be improved by leveraging JavaScriptSerializer
's Serialize
method to provide implicit conversion of the object to JSON.
Additionally, it is possible to leverage the using
statement's default functionality in order to omit explicitly calling Flush
and Close
.
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://url");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = new JavaScriptSerializer().Serialize(new
{
user = "Foo",
password = "Baz"
});
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
Solution 3 - C#
The HttpClient
type is a newer implementation than the WebClient
and HttpWebRequest
. Both the WebClient
and WebRequest
have been marked as obsolete. [1]
You can simply use the following lines.
string myJson = "{'Username': 'myusername','Password':'pass'}";
using (var client = new HttpClient())
{
var response = await client.PostAsync(
"http://yourUrl",
new StringContent(myJson, Encoding.UTF8, "application/json"));
}
When you need your HttpClient
more than once it's recommended to only create one instance and reuse it or use the new HttpClientFactory
. [2]
> For FTP, since HttpClient doesn't support it, we recommend using a third-party library.
@docs.microsoft.com [3]
Since dotnet core 3.1 you can use the JsonSerializer
from System.Text.Json
to create your json string.
string myJson = JsonSerializer.Serialize(credentialsObj);
Solution 4 - C#
Further to Sean's post, it isn't necessary to nest the using statements. By using
the StreamWriter it will be flushed and closed at the end of the block so no need to explicitly call the Flush()
and Close()
methods:
var request = (HttpWebRequest)WebRequest.Create("http://url");
request.ContentType = "application/json";
request.Method = "POST";
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
string json = new JavaScriptSerializer().Serialize(new
{
user = "Foo",
password = "Baz"
});
streamWriter.Write(json);
}
var response = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
Solution 5 - C#
If you need to call is asynchronously then use
var request = HttpWebRequest.Create("http://www.maplegraphservices.com/tokkri/webservices/updateProfile.php?oldEmailID=" + App.currentUser.email) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "text/json";
request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);
private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
// End the stream request operation
Stream postStream = request.EndGetRequestStream(asynchronousResult);
// Create the post data
string postData = JsonConvert.SerializeObject(edit).ToString();
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
//Start the web request
request.BeginGetResponse(new AsyncCallback(GetResponceStreamCallback), request);
}
void GetResponceStreamCallback(IAsyncResult callbackResult)
{
HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream()))
{
string result = httpWebStreamReader.ReadToEnd();
stat.Text = result;
}
}
Solution 6 - C#
I recently came up with a much simpler way to post a JSON, with the additional step of converting from a model in my app. Note that you have to make the model [JsonObject]
for your controller to get the values and do the conversion.
Request:
var model = new MyModel();
using (var client = new HttpClient())
{
var uri = new Uri("XXXXXXXXX");
var json = new JavaScriptSerializer().Serialize(model);
var stringContent = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PutAsync(uri,stringContent).Result;
// ...
}
Model:
[JsonObject]
[Serializable]
public class MyModel
{
public Decimal Value { get; set; }
public string Project { get; set; }
public string FilePath { get; set; }
public string FileName { get; set; }
}
Server side:
[HttpPut]
public async Task<HttpResponseMessage> PutApi([FromBody]MyModel model)
{
// ...
}
Solution 7 - C#
Solution 8 - C#
WARNING! I have a very strong view on this subject.
.NET’s existing web clients are not developer friendly! WebRequest & WebClient are prime examples of "how to frustrate a developer". They are verbose & complicated to work with; when all you want to do is a simple Post request in C#. HttpClient goes some way in addressing these issues, but it still falls short. On top of that Microsoft’s documentation is bad … really bad; unless you want to sift through pages and pages of technical blurb.
Open-source to the rescue. There are three excellent open-source, free NuGet libraries as alternatives. Thank goodness! These are all well supported, documented and yes, easy - correction…super easy - to work with.
- ServiceStack.Text - fast, light and resilient.
- RestSharp - simple REST and HTTP API Client
- Flurl- a fluent, portable, testable HTTP client library
There is not much between them, but I would give ServiceStack.Text the slight edge …
- Github stars are roughly the same.
- Open Issues & importantly how quickly any issues closed down? ServiceStack takes the award here for the fastest issue resolution & no open issues.
- Documentation? All have great documentation; however, ServiceStack takes it to the next level & is known for its ‘Golden standard’ for documentation.
Ok - so what does a Post Request in JSON look like within ServiceStack.Text?
var response = "http://example.org/login"
.PostJsonToUrl(new Login { Username="admin", Password="mypassword" });
That is one line of code. Concise & easy! Compare the above to .NET’s Http libraries.
Solution 9 - C#
This option is not mentioned:
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:9000/");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var foo = new User
{
user = "Foo",
password = "Baz"
}
await client.PostAsJsonAsync("users/add", foo);
}
Solution 10 - C#
Some different and clean way to achieve this is by using HttpClient like this:
public async Task<HttpResponseMessage> PostResult(string url, ResultObject resultObject)
{
using (var client = new HttpClient())
{
HttpResponseMessage response = new HttpResponseMessage();
try
{
response = await client.PostAsJsonAsync(url, resultObject);
}
catch (Exception ex)
{
throw ex
}
return response;
}
}
Solution 11 - C#
I finally invoked in sync mode by including the .Result
HttpResponseMessage response = null;
try
{
using (var client = new HttpClient())
{
response = client.PostAsync(
"http://localhost:8000/....",
new StringContent(myJson,Encoding.UTF8,"application/json")).Result;
if (response.IsSuccessStatusCode)
{
MessageBox.Show("OK");
}
else
{
MessageBox.Show("NOK");
}
}
}
catch (Exception ex)
{
MessageBox.Show("ERROR");
}
Solution 12 - C#
I find this to be the friendliest and most concise way to post an read JSON data:
var url = @"http://www.myapi.com/";
var request = new Request { Greeting = "Hello world!" };
var json = JsonSerializer.Serialize<Request>(request);
using (WebClient client = new WebClient())
{
var jsonResponse = client.UploadString(url, json);
var response = JsonSerializer.Deserialize<Response>(jsonResponse);
}
I'm using Microsoft's System.Text.Json
for serializing and deserializing JSON. See NuGet.
Solution 13 - C#
This is how I do it
//URL
var url = "http://www.myapi.com/";
//Request
using var request = new HttpRequestMessage(HttpMethod.Post, url);
//Headers
request.Headers.Add("Accept", "application/json");
request.Headers.Add("Cache-Control", "no-cache");
//Payload
var payload = JsonConvert.SerializeObject(
new
{
Text = "Hello world"
});
request.Content = new StringContent(payload, Encoding.UTF8, "application/json");
//Send
var response = await _httpClient.SendAsync(request);
//Handle response
if (response.IsSuccessStatusCode)
return;
Solution 14 - C#
Dot net core solution
first using Newtonsoft.Json
then write a method like this:
public static string? LoginToken()
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://url");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
// write your json content here
string json = JsonConvert.SerializeObject(new
{
userName = ApiOptions.Username,
password = ApiOptions.Password
}
);
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
return result;
}
}
This method return string
. if you want to deserialize the string
result to JSON
, simply add this line at the end of the method:
var result = streamReader.ReadToEnd();
var json_result = JsonConvert.DeserializeObject<LoginTokenResponse>(result); // + add this code
Which LoginTokenResponse
is the custom class you want to Deserialize the string result
Solution 15 - C#
var data = Encoding.ASCII.GetBytes(json);
byte[] postBytes = Encoding.UTF8.GetBytes(json);
Use ASCII instead of UFT8