httpClient Does not give Response - c#

i am trying to call the Zoom Api for Access token. It work Perfectly fine when i am trying to post with postman .
but from code it does not respond
ZoomApiLink_StepNo2
below are the following details
public static async Task<String> PostTogetToken<T>(string requestUrl, string client_Secretkey) {
ZoomToken hello = new ZoomToken();
var EncodedURl = ApiService.Base64Encode(client_Secretkey);
using (var _httpClient = new HttpClient()) {
if (!string.IsNullOrEmpty(requestUrl))
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "Basic " + EncodedURl);
var httpContent = new StringContent("", System.Text.Encoding.UTF8, "application/x-www-form-urlencoded");
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, new Uri(requestUrl)) {
Version = HttpVersion.Version11,
Content = httpContent
};
using (var response = await _httpClient.SendAsync(httpRequestMessage)) {
if (response.IsSuccessStatusCode) {
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
} else {
return await response.Content.ReadAsStringAsync();
}
}
}
}

You're seeing a common deadlock problem because code further up the stack is using Result, blocking on asynchronous code.
To fix, change the Result to await and use async all the way.

Related

How to send a post request in dotnet with a list of request headers

public static async Task<HttpResponseMessage> Post(string endPoint, string data){
HttpContent c = new StringContent(data, Encoding.UTF8, "application/json");
using (var client = new HttpClient())
{
HttpRequestMessage request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri(VodapayBaseUrl + endPoint),
Content = c,
};
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage result = await client.SendAsync(request).ConfigureAwait(false); // The code fails here
if (result.IsSuccessStatusCode)
{
Console.WriteLine("got here");
return result;
}
else
{
Console.WriteLine("failled");
return result;
}
}
// return result;
}
Here is an updated version:
public static async Task Post()
{
using (var httpClient = new HttpClient())
{
var requestString = "{\"authCode\": \"0000000001Nk1EEhZ3pZ73z700271891\" }";
httpClient.BaseAddress = new Uri("https://bounties-backend-mini-program.herokuapp.com");
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var request = new HttpRequestMessage(HttpMethod.Post, $"/api/userInfo");
request.Content = new StringContent(requestString, System.Text.Encoding.UTF8, "application/json");
var response = await httpClient.SendAsync(request);
var responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine(JsonConvert.SerializeObject(response.Headers.ToList()));
if (response.IsSuccessStatusCode)
{
Console.WriteLine("Successful");
Console.WriteLine(responseContent);
}
else
{
Console.WriteLine("Not successful");
}
}
}
class Program
{
private static void Main(string[] args)
{
Post().Wait();
Console.WriteLine();
}
}
}
Can someone please help with this I am new to c# and relatively new to coding. I am trying to send a request using httpclient I need to send data in a json format I also need to send a list of headers. How can I do this and also return json data at the end your help will be appreciated.I am getting an error when i run this:
Your code isn't far off, here's an example that I had in one of my projects ...
using (var httpClient = new HttpClient())
{
var requestString = "{\"authCode\": \"0000000001Nk1EEhZ3pZ73z700271891\" }";
// Setup the HttpClient and make the call and get the relevant data.
httpClient.BaseAddress = new Uri("https://bounties-backend-mini-program.herokuapp.com");
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var request = new HttpRequestMessage(HttpMethod.Post, $"/api/userInfo");
request.Content = new StringContent(requestString, System.Text.Encoding.UTF8, "application/json");
var response = await httpClient.SendAsync(request);
var responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine(JsonConvert.SerializeObject(response.Headers.ToList()));
if (response.IsSuccessStatusCode)
{
Console.WriteLine("Successful");
Console.WriteLine(responseContent);
}
else
{
Console.WriteLine("Not successful");
}
}
... obviously, it has varying degrees of thought for the scenario at hand but just adapt it as need be.

HttpClient post returns bad request in c#, works in postman

I'm trying to access a rest endpoint, https://api.planet.com/auth/v1/experimental/public/users/authenticate. It is expecting json in the request body.
I can get the request to work in Postman but not using c#. Using postman I get the expected invalid email or password message but with my code I get "Bad Request" no matter I try.
Here is the code that makes the request
private void Login()
{
try
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://api.planet.com/");
client.DefaultRequestHeaders.Accept.Clear();
//ClientDefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
Data.User user = new Data.User
{
email = "myemail#company.com",
password = "sdosadf"
};
var requestMessage = JsonConvert.SerializeObject(user);
var content = new StringContent(requestMessage, Encoding.UTF8, "application/json");
var response = client.PostAsync("auth/v1/experimental/public/users/authenticate", content).Result;
Console.WriteLine(response.ToString());
}
catch (WebException wex )
{
MessageBox.Show(wex.Message) ;
}
}
class User
{
public string email;
public string password;
}
Here are screen grabs form Postman that are working
The way to get this to work was to alter the content header "content-type". By default HTTPClient was creating content-type: application/json;characterset= UTF8. I dropped and recreated the content header without the characterset section and it worked.
content.Headers.Remove("Content-Type");
content.Headers.Add("Content-Type", "application/json");
The issue is you are trying to call an async method without waiting for the response using await method or var task = method; task.Wait() Therefore, when you end up doing response.ToString() it returns the text you are seeing.
One way to handle this within a non-async method would be to do the following:
var task = client.PostAsync("auth/v1/experimental/public/users/authenticate", content);
task.Wait();
var responseTask = task.Content.ReadAsStringAsync();
responseTask.Wait();
Console.WriteLine(responseTask.Result);
Another way is to make the current method async by doing private async void Login() and then do:
var postResp = await client.PostAsync("auth/v1/experimental/public/users/authenticate", content);
var response = await postResp.Content.ReadAsStringAsync();
Console.WriteLine(response);
Create a Method Like this...
static async Task<string> PostURI(Uri u, HttpContent c)
{
var response = string.Empty;
var msg = "";
using (var client = new HttpClient())
{
HttpResponseMessage result = await client.PostAsync(u, c);
msg = await result.Content.ReadAsStringAsync();
if (result.IsSuccessStatusCode)
{
response = result.StatusCode.ToString();
}
}
return response;
}
call In your Method
public void Login()
{
string postData ="{\"email\":\"your_email\",\"password\":\"your_password\"}";
Uri u = new Uri("yoururl");
var payload = postData;
HttpContent c = new StringContent(payload, Encoding.UTF8,"application/json");
var t = Task.Run(() => PostURI(u, c));
t.Wait();
Response.Write(t.Result);
}

Even with a successful access Token I get a 401 unauthorized in my Get() async method?

Currently I have to async methods Post() & Get(). For my Post() method is returning a access token and if you look at the bottom of my post method I am calling my Get() in there also, for the simple reason of being able to call string result in my get. but even with a successful access token I Keep getting a 401 unauthorized Status code, why?
Click to view error in VS
namespace APICredential.Controllers
{
[RoutePrefix("api")]
public class ValuesController : ApiController
{
[HttpGet, Route("values")]
public async Task<string> Post()
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("https://api.elliemae.com/oauth2/");
var parameters = new Dictionary<string, string>()
{
{"grant_type", "password"}, //Gran_type Identified here
{"username", "admin#encompass:BE11200822"},
{"password", "Shmmar****"},
{"client_id", "gpq4sdh"},
{"client_secret", "dcZ42Ps0lyU0XRgpDyg0yXxxXVm9#A5Z4ICK3NUN&DgzR7G2tCOW6VC#HVoZPBwU"},
{"scope", "lp"}
};
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "v1/token")
{
Content = new FormUrlEncodedContent(parameters)
};
HttpResponseMessage response = await client.SendAsync(request);
string resulted = await response.Content.ReadAsStringAsync();
await Get(resulted);
return resulted;
}
}
[HttpGet, Route("values/get")]
public async Task<string> Get(string resulted)
{
string res = "";
using (var client = new HttpClient())
{
// HTTP POST
client.BaseAddress = new Uri("https://api.elliemae.com/");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = client.GetAsync("/encompass/v1/loans/{ea7c29a6-ee08-4816-99d2-fbcc7d15731d}?Authorization=Bearer "+resulted+"&Content-Type=application/json").Result;
using (HttpContent content = response.Content)
{
// ... Read the string.
Task<string> result = content.ReadAsStringAsync();
res = result.Result;
}
}
return res;
}
The following is missing:
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + Accesstoken);
This is your default header once you insert this then you have premission to getstring data from whatever your URL is...
code will look like this:
public async Task<string> Get(string Accesstoken)
{
string res = "";
using (var client = new HttpClient())
{
Accesstoken = Accesstoken.Substring(17, 28);
client.BaseAddress = new Uri("https://api.elliemae.com/");
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + Accesstoken);
var response = client.GetAsync("encompass/v1/loans/ea7c29a6-ee08-4816-99d2-fbcc7d15731d").Result;
using (HttpContent content = response.Content)
{
// ... Read the string.
Task<string> result = content.ReadAsStringAsync();
res = result.Result;
}

HttpClient PostAsync returns error 404 Not found in .net core 2.0

I am trying to call the webapi using httpclient. but it's not recognizing method and always throw 404 error.
My api Action method is like this.
[Route("AddEmployee")]
[HttpPost]
public async Task<IActionResult> PostTEmployee([FromBody]Employee emp)
{ // doing something here}
And the calling method is like below
using (var httpClient = new HttpClient())
{i
String BaseUrl = "http://ip:port/";
httpClient.BaseAddress = new Uri(BaseUrl);
AuthenticationHeaderValue parsedAuthToken = null;
bool authParsed = AuthenticationHeaderValue.TryParse(authToken, out parsedAuthToken);
if (authParsed)
{
httpClient.DefaultRequestHeaders.Authorization = parsedAuthToken;
}
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
string serialisedData = JsonConvert.SerializeObject(emp);
HttpContent content = new StringContent(serialisedData, Encoding.UTF8, "application/json");
HttpResponseMessage response = null;
response = await httpClient.PostAsync("AddEmployee", content);
if (response.IsSuccessStatusCode)
{
}
}
I am stuck with this issue from 2 days. Not sure what is the mistake? please help me.
Totally a wild guess but is your endpoint /api/AddEmployee not /AddEmployee?
try changing
response = await httpClient.PostAsync("AddEmployee", content);
To
response = await httpClient.PostAsync("api/AddEmployee", content);

Troubleshooting HTTPClient asynchronous POST and reading results

I have a problem post string to form and read. Problem is they get away but need to do so sophisticated and it was very fast. Absolutely perfect multithreaded or asynchronous. Thank you very for your help.
This is my code.
private static void AsyncDown()
{
const string url = "http://whois.sk-nic.sk/index.jsp";
const string req = "PREM-0001";
var client = new HttpClient();
var pairs = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("text", "PREM-0001")
};
FormUrlEncodedContent content = new FormUrlEncodedContent(pairs);
HttpResponseMessage response = client.PostAsync("http://whois.sk-nic.sk/index.jsp", content).Result;
if (response.IsSuccessStatusCode)
{
HttpContent stream = response.Content;
Task<string> data = stream.ReadAsStringAsync();
}
}
Taking a rough stab in the dark at what your problem is, I'd guess that you're having trouble reading the response of your call.
When the content is POSTed to the server,
HttpResponseMessage response
= client.PostAsync("http://whois.sk-nic.sk/index.jsp", content).Result;
if (response.IsSuccessStatusCode)
{
HttpContent stream = response.Content;
Task<string> data = stream.ReadAsStringAsync();
}
It does so asynchronously, so the code will continue execution even though the result is not (most likely) available yet. Checking response.IsSuccessStatusCode will thus not give you the behavior you're expecting.
Change your calls to look like this by adding the await keyword:
HttpResponseMessage response
= await client.PostAsync("http://whois.sk-nic.sk/index.jsp", content);
Then, change the reading of the stream to use await as well:
if (response.IsSuccessStatusCode)
{
var data = await response.Content.ReadAsStringAsync();
}
EDIT: got some await objects mixed up and have corrected the code listing.
edit 2: here is the complete LINQPad script that I used to successfully download an HTML page from the given URL.
var client = new HttpClient();
var pairs = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("text", "PREM-0001")
};
FormUrlEncodedContent content = new FormUrlEncodedContent(pairs);
HttpResponseMessage response = await client.PostAsync("http://whois.sk-nic.sk/index.jsp", content);
if (response.IsSuccessStatusCode)
{
var data = await response.Content.ReadAsStringAsync();
//data.Dump(); //uncomment previous if using LINQPad
}
Maybe the site has changed since last post but now the request parameter name is whois not text. If this was the case a year ago too that's why it didn't work.
Today site responds to get too, i.e. http://whois.sk-nic.sk/index.jsp?whois=PREM-0001
Full code with get:
private async Task<string> Get(string code)
{
using (var client = new HttpClient())
{
var requestUri = String.Format("http://whois.sk-nic.sk/index.jsp?whois={0}", code);
var data = await client.GetStringAsync(requestUri);
return data;
}
}
Full code with post:
private async Task<string> Post()
{
using (var client = new HttpClient())
{
var postData = new KeyValuePair<string, string>[]
{
new KeyValuePair<string, string>("whois", "PREM-0001"),
};
var content = new FormUrlEncodedContent(postData);
var response = await client.PostAsync("http://whois.sk-nic.sk/index.jsp", content);
if (!response.IsSuccessStatusCode)
{
var message = String.Format("Server returned HTTP error {0}: {1}.", (int)response.StatusCode, response.ReasonPhrase);
throw new InvalidOperationException(message);
}
var data = await response.Content.ReadAsStringAsync();
return data;
}
}
Or a parser could be used because I guess extracting the returned values is the final goal:
private void HtmlAgilityPack(string code)
{
var requestUri = String.Format("http://whois.sk-nic.sk/index.jsp?whois={0}", code);
var request = new HtmlWeb();
var htmlDocument = request.Load(requestUri);
var name = htmlDocument.DocumentNode.SelectSingleNode("/html/body/table[1]/tr[5]/td/table/tr[2]/td[2]").InnerText.Trim();
var organizations = htmlDocument.DocumentNode.SelectSingleNode("/html/body/table[1]/tr[5]/td/table/tr[3]/td[2]").InnerText.Trim();
}

Categories