Before everyone tells me to increase the timeout values I don't want to increase it because it doesn't make sense that 100 seconds isn't long enough. All other get and post responses take less time without throwing a timeout/task cancel exception.
I am trying to mimic the following, I whited out the user and password...
Here is the code
var baseAddress = new Uri("http://www.foodservice.com/home/fs_login.cfm?logmode=Home");
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
var trypage = await client.GetAsync("http://www.foodservice.com/home/fs_login.cfm?logmode=Home");
trypage.EnsureSuccessStatusCode();
Console.WriteLine("something");
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("user_name", "someuser"),
new KeyValuePair<string, string>("password", "somepass"),
new KeyValuePair<string, string>("logmode", "Home")
});
var result = await client.PostAsync("http://www.foodservice.com/home/fs_login_check.cfm", content);
Console.WriteLine("somethingelse");
result.EnsureSuccessStatusCode();
It hands on. something prints, somethingelse doesn't
var result = await client.PostAsync("http://www.foodservice.com/home/fs_login_check.cfm", content);
I don't see any reason why it should hang and fail here...
Summary: Why isn't my post getting through? I am I using the wrong address or something?
Try this
await client.GetAsync("http://www.foodservice.com/home/fs_login.cfm?logmode=Home").ConfigureAwait(false);
and
await client.PostAsync("http://www.foodservice.com/home/fs_login_check.cfm", content).ConfigureAwait(false);
you can get more information on Httpclient Async call
For some reason the process could not be multithreaded.
Switched from Tasks to blocking single threaded it worked fine...
Related
I'm writing a simple dotnet core API, under search controller which like below :
[HttpGet("order")]
public async Task <Order> SearchOrder(string ordername, int siteid) {
return await service.getorder(ordername,siteid)
}
The swagger UI where the path https://devehost/search/order test pretty work, but when I use another client to call this api by below
client = new HttpClient {
BaseAddress = new Uri("https://devehost")
};
var request = new HttpRequestMessage(HttpMethod.Get, "Search/order") {
Content = new FormUrlEncodedContent(
new List<KeyValuePair<string, string>> {
new("ordername", "pizza-1"),
new("siteid", "1"),
})
};
var response = await client.SendAsync(request);
The status code always return bad request. But the postman is work, can I know the problem inside?
Thank you
For a GET request, the parameters should be sent in the querystring, not the request body.
GET - HTTP | MDN
Note: Sending body/payload in a GET request may cause some existing implementations to reject the request — while not prohibited by the specification, the semantics are undefined.
For .NET Core, you can use the Microsoft.AspNetCore.WebUtilities.QueryHelpers class to append the parameters to the URL:
Dictionary<string, string> parameters = new()
{
["ordername"] = "pizza-1",
["siteid"] = "1",
};
string url = QueryHelpers.AppendQueryString("Search/order", parameters);
using var request = new HttpRequestMessage(HttpMethod.Get, url);
using var response = await client.SendAsync(request);
This is driving me cray cray, I have the following code:
public WorkItemQueryResult GetListOfStories(string queryString, string tfsInstance, string PAT)
{
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", $"{GetPatAsEncodedString(PAT)}");
var request = new HttpRequestMessage()
{
Content = new StringContent(JsonSerializer.Serialize(queryString)),
Method = HttpMethod.Post,
RequestUri = new Uri($"{tfsInstance}_apis/wit/wiql?api-version=5.1")
};
var task = Task.Run(() => client.SendAsync(request));
task.Wait();
if (!task.Result.IsSuccessStatusCode) return new WorkItemQueryResult();
var response = task.Result.Content.ReadAsAsync<WorkItemQueryResult>();
return response.Result;
}
Which when I debug it with a break point on Task.Run shows the following:
My issue is that after executing the method I get an error from Azure DevOps telling me that the method isn't allowed. Here's the request after task.Wait:
I've verified that the same body and auth headers work through another client (YaRC). Obviously I'm doing something wrong but I can't see it :(
I had the same problem, try using 'ConfigureAwait' and 'GetAwaiter' like bellow:
var task = Task.Run(() => client.SendAsync(request));
//task.Wait();
task.ConfigureAwait(false).GetAwaiter();
Know its been a bit but, the issue ended up being that when a 3xx redirect is returned, the Authorization header is cleared out for security. So the POST is redirecting, causing a GET to be sent without authorization, resulting in 405.
The original request URL was http and as a result were getting redirected to https. Which then caused the above to occur :)
Everything works fine on Postman with x-www-from-urlencoded and basic auth. Now trying to get my hands dirty, I just get status code 200 with nothing on mailgun, no logs recorded.
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://api.mailgun.net/v3");
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("api", "key-withheld-till-a-verdict-has-passed");
var msg = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("from",
$"Excited User <mailgun#sandboxSOMEGUIDHERE.mailgun.org>"),
new KeyValuePair<string, string>("to","approved-to-receive#mailgun"),
new KeyValuePair<string, string>("subject", "Test Please Do Not Reply"),
new KeyValuePair<string, string>("text","Thanks for borrowing me your inbox")
};
var request = new HttpRequestMessage(HttpMethod.Post,
"sandboxSOMEGUIDHERE.mailgun.org/messages");
request.Content = new FormUrlEncodedContent(msg);
var response = await client.SendAsync(request);
// I get 200 status code
var result = await response.Content.ReadAsStringAsync();
//I get result = "Mailgun Magnificent API"
}
First, it turns out I was getting the BaseAddress not right. I had to place a slash at the end of the BaseAddress.
client.BaseAddress = new Uri("https://api.mailgun.net/v3/");
without the slash, I was posting to (note v3 is missing),
https://api.mailgun.net/sandboxSOMEGUIDHERE.mailgun.org/messages
After sorting that out, another problem emerged 401 - ANAUTHORIZED. And with the help of this SO answer I do,
var byteArray = new UTF8Encoding()
.GetBytes("api:key-withheld-till-a-verdict-has-passed");
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
But the reason why mailgun was responding with Ok still remain mysterious. To investigate further, I used Postman to post to,
https://api.mailgun.net/sandboxSOMEGUIDHERE.mailgun.org/messages
and to my surprise, Mailgun mysteriously responded with Ok.
This question already has answers here:
await vs Task.Wait - Deadlock?
(3 answers)
Closed 7 years ago.
I have next part of code :
using (var client = new HttpClient()) // from Windows.Web.Http;
{
//setup client
var tokenUri = new Uri(apiBaseUri + "/token");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new HttpMediaTypeWithQualityHeaderValue("application/json"));
//setup login data
IHttpContent formContent = new HttpFormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", userName),
new KeyValuePair<string, string>("password", password),
});
//send request
HttpResponseMessage responseMessage = await client.PostAsync(tokenUri, formContent);
//get access token from response body
var responseJson = await responseMessage.Content.ReadAsStringAsync();
var jObject = JObject.Parse(responseJson);
return jObject.GetValue("access_token").ToString();
}
This makes call to my Web Api. I have checked if it's really works with fiddler - as result I can see response what i espect (Bearer token). But in code this response are never received.
What is the problem?
This:
var token = GetAPIToken(UserName, Password, ApiBaseUri).Result;
Causes a classic deadlock. You shouldn't be blocking on async code with Task.Result or Task.Wait. Instead, you need to go "async all the way" and await on it too, making the method higher up the call stack async Task as well:
public async Task GetApiTokenAsync()
{
var token = await GetAPIToken(UserName, Password, ApiBaseUri);
}
I am figuring out the new HttpClient.
I try to POST a http uri like this:
http://server/API/user/login?login=name&password=password
I thought this would be the way to go:
using (var client = new HttpClient())
{
var values = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("login", "user"),
new KeyValuePair<string, string>("password ", "password")
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("http://server/REST/user/login", content);
}
The only way I can get it to work is:
using (var client = new HttpClient())
{
var response = await client.PostAsync("http://server/REST/user/login?login=user&password=password",null);
}
Is the last way the correct way or am I doing something wrong in the first approach?
The sample shows that it is being passed along in the Cookie header, not the body. If I interpret the API correctly you have to indeed pass username and password in the URL and give the Cookie header the url-encoded data.
Essentially: use your second approach and for all subsequent calls, add this:
client.DefaultRequestHeaders.Add("Cookie", await content.ReadAsStringAsync());