How to post JSON with HttpClient using C#? - c#

I have no idea how to POST JSON with HttpClient. I find some solution, like this, but I have to use HttpClient, cause of async and have to add a header.
This is my code below. Any idea how to fix it?
List<Order> list = new List<Order> { new Order() { Name = "CreatedTime", OrderBy = 1 } };
Queues items = new Queues { Orders = list };
var values = new Dictionary<string, string> { { "Orders", JsonConvert.SerializeObject(list) } };
var content = new FormUrlEncodedContent(values);
//HttpContent cc = new StringContent(JsonConvert.SerializeObject(items));
_msg = await _client.PostAsync(input, content);
//_msg = await _client.PostAsync(input, cc);
var response = await _msg.Content.ReadAsStringAsync();

You can use the method PostAsJsonAsync which can be found in the extensions assemblies:
System.Net.Http.Formatting.dll
Example
public static async Task SendJsonDemo(object content)
{
using(var client = new HttpClient())
{
var response = await client.PostAsJsonAsync("https://example.com", content);
}
}
If you want to add custom headers to the request, add it to DefaultRequestHeaders:
client.DefaultRequestHeaders.Add("mycustom", "header1");

You can send any type of request like as
public static async Task<HttpResponseMessage> SendRequest(HttpMethod method, string endPoint, string accessToken, dynamic content = null)
{
HttpResponseMessage response = null;
using (var client = new HttpClient())
{
using (var request = new HttpRequestMessage(method, endPoint))
{
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
if (content != null)
{
string c;
if (content is string)
c = content;
else
c = JsonConvert.SerializeObject(content);
request.Content = new StringContent(c, Encoding.UTF8, "application/json");
}
response = await client.SendAsync(request).ConfigureAwait(false);
}
}
return response;
}

Related

How to read header values with HttpClient in .net core

This is the code i'm using
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", HttpContext.Session.GetString("JwtToken"));
var url = $"...some url";
var requestUri = new Uri(url);
var responseTask = client.GetAsync(requestUri);
responseTask.Wait();
var result = responseTask.Result;
if (result.IsSuccessStatusCode)
{
var reportResults = Task.Run(async() => await result.Content.ReadAsAsync<JArray>()).Result;
return reportResults;
}
}
Here if i try to access header like this
string error = responseTask.Headers.TryGetValue("X-TotalResults").FirstOrDefault();
I'm getting error
Task<HttpResponseMessage> does not contain a
definition for Headers and no accessible extension method Headers
So How i can read the header .. thanks in advance
You have a Task<HttpResponseMessage> rather than a HttpResponseMessage.
Instead of using .Result, which is dangerous for many reasons, convert your code to use async properly.
static HttpClient client = new HttpClient();
private async JArray GetReportResults()
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", HttpContext.Session.GetString("JwtToken"));
var url = $"...some url";
using (var response = await client.GetAsync(url))
{
result.EnsureSuccessStatusCode()
var reportResults = await result.Content.ReadAsAsync<JArray>();
return reportResults;
}
}

how to get API response it in asp.net c#

i have the following API json request
"myjsonrequest": {
"ServiceKey": "Hello",
"Identityvals": {
"IDName": "regnum",
"IDValue": "112233"
}
}
any simple way to get the response , im using ASP.net c#
i tried this code
HttpClient client = new HttpClient();
string x = "{'IDName','regnum'},{'IDValue','112233'}";
var Keys = new Dictionary<string, string>
{
{ "ServiceKey", "hello" },
{ "PractitionerIdentity",x}
};
var content = new FormUrlEncodedContent(Keys);
var response = await client.PostAsync("https://apiurl", content);
var responseval = await response.Content.ReadAsStringAsync();
Try this :
var json = new {
ServiceKey = "",
PractitionerIdentity = new {
IDName = "" ,
IDValue = ""
}
};
HttpClient client = new HttpClient();
var content = new StringContent(json, Encoding.UTF8, "application/json")
var response = await client.PostAsync("https://apiurl", content);
Your Json data should be saved to a model in the following way:
public class YourJsonData{
public string ServiceKey {get; set;}
//add other names
}
The best thing about this is that if you call your object, you get a variable back for easy usage.
then you can add it in a task:
public async Task<List<YourJsonData>> GetJsonAsync(CancellationToken cancellationToken = default)
{
using (var client = new HttpClient())
{
//Make the request, and ensure we can reach it
var response = await client.GetAsync(yourJosnUrl, cancellationToken);
if (response.IsSuccessStatusCode)
{
//Read the actual stream (download the content)
var content = await response.Content.ReadAsStringAsync();
//Make sure we do have some valid content before we try to deserialize it
if (string.IsNullOrEmpty(content))
{
return new List<YourJsonData>();
}
//Deserialize into a list of yourjsondata
return JsonConvert.DeserializeObject<List<YourJsonData>>(content);
}
}
return new List<YourJsonData>();
}
also if you are lazy, you can replace YourJsonData with dynamic. the downpart here is that you won't be able to see what you are revering to.

Xamarin Sending POST Data

I am attempting to send POST data to my server and get back a response. For some reason, no POST data is actually getting sent. A request is being sent to my server but the POST array is empty.
Here is my code for sending the request:
public class GlobalMethods
{
public async Task<string> callAjax(string mthd,NameValueCollection parameters)
{
var client = new HttpClient();
var content = JsonConvert.SerializeObject(parameters);
var result = await client.PostAsync("http://dev.adex-intl.com/adex/mvc/receiving/"+mthd, new StringContent(content)).ConfigureAwait(false);
var tokenJson = "";
if (result.IsSuccessStatusCode)
{
tokenJson = await result.Content.ReadAsStringAsync();
}
return tokenJson;
}
}
And here is my code that calls the above method:
public void loginPressed(object sender, EventArgs e)
{
if(String.IsNullOrEmpty(badge.Text)) {
DisplayAlert("Error", "Enter your badge number", "Ok");
} else {
IsBusy = true;
NameValueCollection parameters = new NameValueCollection();
parameters["badgetNumber"] = badge.Text;
GlobalMethods globalMethods = new GlobalMethods();
var results = globalMethods.callAjax("login", parameters);
}
}
I'm not sure what I'm doing wrong. Also, I'm a newbie to Xamarin and C# so I'm not even sure if the way I am attempting to do things is the best way.
You haven't specify the type of content that you want to send, in your case it's 'application/json', you can set it like that:
"var client = new HttpClient();
var content = new StringContent(JsonConvert.SerializeObject(parameters));
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");". Also, I would suggest you to write code like that:
var uri = new Uri(url);
using (var body = new StringContent(JsonConvert.SerializeObject(data)))
{
body.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var request = new HttpRequestMessage
{
Version = new Version(1, 0),
Content = body,
Method = HttpMethod.Post,
RequestUri = uri
};
try
{
using (var response = await _client.SendAsync(request,cancellationToken))
{
if (response.IsSuccessStatusCode)
{
//Deal with success response
}
else
{
//Deal with non-success response
}
}
}
catch(Exception ex)
{
//Deal with exception.
}
}
You can use PostAsync for async sending data to server. your code should be something like this:
HttpClient client = new HttpClient();
var values = new Dictionary<string, string>
{
{ "p1", "data1" },
{ "p2", "data2" }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("http://www.example.com/index.php", content);
var responseString = await response.Content.ReadAsStringAsync();

HTTP content to string/model

I have an object.
I'am sending it this to my api project this way :
mymodel obj = new mymodel();
obj.prop = "this";
obj.prop2 = "prop2";
var content = JsonConvert.SerializeObject(obj);
var buffer = System.Text.Encoding.UTF8.GetBytes(content);
var byteContent = new ByteArrayContent(buffer);
byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
string response = "";
using (HttpClient client = new HttpClient())
{
var rez = await client.PostAsync(uri + myenum.Insert, byteContent).ConfigureAwait(false);
response = rez.ToString();
}
In my api method i want to convert that string or http content again to model.
[ActionName("Insert")]
[HttpGet]
public bool Insert(string obj)
{
try
{
mymodel model = JsonConvert.DeserializeObject<mymodel>(obj);
How to handle object i'am sending with postasync in my api method ?
Any help ?
First you cannot use PostAsync on a HTTPGet method.
Second, I dont understand what you mean. If you are using json then you dont have to do anything. Just have a simple client method as such:
public async Task<TResult> PostAsync<TResult, TInput>(string uriString, TInput payload = null) where TInput : class
{
var uri = new Uri(uriString);
using (var client = GetHttpClient())
{
var jsonContent = JsonConvert.SerializeObject(payload, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() });
HttpResponseMessage response = await client.PostAsync(uri, new StringContent(jsonContent, Encoding.UTF8, "application/json"));
if (response.StatusCode != HttpStatusCode.OK)
{
//Log.Error(response.ReasonPhrase);
return default(TResult);
}
var json = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<TResult>(json);
}
}
And you can just add the same object to your API like
[ActionName("Insert")]
[HttpPost]
public bool Insert(YourObjectClass obj)
{
try
{
....code....
}
}

Using a token to search on Twitter with OAuth2

Before Twitter switched to OAuth2, I was using the following query:
string atomTweetSearchURL = string.Format("http://search.twitter.com/search.atom?q={0}", searchText);
This no longer works, so now I'm trying to switch to OAuth2. I manage to successfully retrieve a token, but once I've got this, I seem to be unable to actually perform the search. Here's the latest incarnation of what I've tried:
var searchUrl = string.Format("https://api.twitter.com/1.1/search/tweets.json?q={0}&access_token={1}&token_type={2}", srchStr, twitAuthResponse.access_token, twitAuthResponse.token_type);
WebRequest srchRequest = WebRequest.Create(searchUrl);
using (var response2 = await srchRequest.GetResponseAsync())
{
Stream stream = response2.GetResponseStream();
using (StreamReader sr = new StreamReader(stream))
{
string jsonResponse = await sr.ReadToEndAsync();
}
}
This gives me a 400 - bad request.
I've also tried building the request like this:
System.Net.Http.HttpClient srchRequest = new System.Net.Http.HttpClient();
string authHdr = string.Format(srchHeaderFormat, twitAuthResponse.token_type, twitAuthResponse.access_token);
srchRequest.DefaultRequestHeaders.Add("Authorization", authHdr);
There's a massive quantity of articles out there detailing how to do this, but none of them seem to work correctly with WinRT. Can anyone point me in the right direction?
EDIT
Here's my code to get the token:
var oAuthConsumerKey = key;
var oAuthConsumerSecret = secret;
var oAuthUri = new Uri("https://api.twitter.com/oauth2/token");
var authHeaderFormat = "Basic {0}";
var authHeader = string.Format(authHeaderFormat,
Convert.ToBase64String(Encoding.UTF8.GetBytes(Uri.EscapeDataString(oAuthConsumerKey)
+ ":" +
Uri.EscapeDataString((oAuthConsumerSecret)))
));
var req = new HttpClient();
req.DefaultRequestHeaders.Add("Authorization", authHeader);
HttpRequestMessage msg = new HttpRequestMessage(new HttpMethod("POST"), oAuthUri);
msg.Content = new HttpStringContent("grant_type=client_credentials");
msg.Content.Headers.ContentType = new Windows.Web.Http.Headers.HttpMediaTypeHeaderValue("application/x-www-form-urlencoded");
HttpResponseMessage response = await req.SendRequestAsync(msg);
TwitAuthenticateResponse twitAuthResponse;
using (response)
{
string objectText = await response.Content.ReadAsStringAsync();
twitAuthResponse = JSonSerialiserHelper.Deserialize<TwitAuthenticateResponse>(objectText);
}
With the 1.1 API you don't pass the access token as part of the url, you need to include it as the Authorization header as "Bearer access_token" so you were almost there!
EDIT
To do this in the Windows.Web.Http namespace the following works:
private static async Task SearchTweets(AuthenticationResponse twitAuthResponse)
{
string srchStr = "tweet";
var client = new HttpClient();
var searchUrl = string.Format("https://api.twitter.com/1.1/search/tweets.json?q={0}", srchStr);
var uri = new Uri(searchUrl);
client.DefaultRequestHeaders.Authorization = new HttpCredentialsHeaderValue("Bearer", twitAuthResponse.AccessToken);
var response2 = await client.GetAsync(uri);
string content = await response2.Content.ReadAsStringAsync();
}
Or with System.Net.Http use the following:
This code will run the search for srchStr using the access token you already acquired as you showed in the first example:
var client = new HttpClient();
var searchUrl = string.Format("https://api.twitter.com/1.1/search/tweets.json?q={0}", srchStr);
var uri = new Uri(searchUrl);
client.DefaultRequestHeaders.Add("Authorization", string.Format("Bearer {0}", twitAuthResponse.access_token));
HttpResponseMessage response = await client.GetAsync(uri);
Task<string> content = response.Content.ReadAsStringAsync();
EDIT
This is a strange one, I tested your code and you're right it does throw an exception when attempting to add the Auth header, however the code I had used for grabbing the Access Token is almost identical but uses the System.Net.Http methods rather than the Windows.Web.Http ones that you use and it works, so I'll provide my code here, maybe this is a bug in the framework, or someone else can provide some more insight! This also uses the JSON.NET library which can be found on NuGet.
private static async Task SearchTweets(AuthenticationResponse twitAuthResponse)
{
string srchStr = "tweet";
var client = new HttpClient();
var searchUrl = string.Format("https://api.twitter.com/1.1/search/tweets.json?q={0}", srchStr);
var uri = new Uri(searchUrl);
client.DefaultRequestHeaders.Add("Authorization", string.Format("Bearer {0}", twitAuthResponse.AccessToken));
HttpResponseMessage response2 = await client.GetAsync(uri);
string content = await response2.Content.ReadAsStringAsync();
}
private async void GetAuthenticationToken()
{
var client = new HttpClient();
var uri = new Uri("https://api.twitter.com/oauth2/token");
var encodedConsumerKey = WebUtility.UrlEncode(TwitterConsumerKey);
var encodedConsumerSecret = WebUtility.UrlEncode(TwitterConsumerSecret);
var combinedKeys = String.Format("{0}:{1}", encodedConsumerKey, encodedConsumerSecret);
var utfBytes = System.Text.Encoding.UTF8.GetBytes(combinedKeys);
var encodedString = Convert.ToBase64String(utfBytes);
client.DefaultRequestHeaders.Add("Authorization", string.Format("Basic {0}", encodedString));
var data = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", "client_credentials")
};
var postData = new FormUrlEncodedContent(data);
var response = await client.PostAsync(uri, postData);
AuthenticationResponse authenticationResponse;
using (response)
{
if (response.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception("Did not work!");
var content = await response.Content.ReadAsStringAsync();
authenticationResponse = JsonConvert.DeserializeObject<AuthenticationResponse>(content);
if (authenticationResponse.TokenType != "bearer")
throw new Exception("wrong result type");
}
await SearchTweets(authenticationResponse);
}
}
class AuthenticationResponse
{
[JsonProperty("token_type")]
public string TokenType { get; set; }
[JsonProperty("access_token")]
public string AccessToken { get; set; }
}

Categories

Resources