I have some very simple code that I have been using in a windows 8 store app without any issue. However When I shared the code with windows phone app It just hangs forever. See sample below. This calls any web url and returns its source as a string. both the post and get methods hang in the same way. any help is much appreciated, Thank you.
public static string GetWebSource(string Url)
{
HttpClient client = new HttpClient();
Task<HttpResponseMessage> Resp = client.GetAsync(Url);
//code hangs on following line forever
//Resp.status always stays at waiting for activation
Task.WaitAll(Resp);
if (Resp.Result.IsSuccessStatusCode)
{
Task<string> response = Resp.Result.Content.ReadAsStringAsync();
Task.WaitAll(response);
return response.Result;
}
return "";
}
public static string PostWebSource(string Url, string data)
{
HttpClient client = new HttpClient();
StringContent sc = new StringContent(data);
Task<HttpResponseMessage> Resp = client.PostAsync(Url, sc);
//code hangs on following line forever
//Resp.status always stays at waiting for activation
Resp.Wait();
if (Resp.Result.IsSuccessStatusCode)
{
Task<string> response = Resp.Result.Content.ReadAsStringAsync();
Task.WaitAll(response);
return response.Result;
}
return "";
}
You should be using an HttpWebRequest on Windows Phone. See this link: http://social.msdn.microsoft.com/Forums/wpapps/en-us/9b4c1ef2-853c-468a-bca8-97477a02583c/httpclient-for-windows-phone-8?forum=wpdevelop
Related
I am trying to learn some docker, i managed to setup API image/container and it works fine, I can get response from the API when i'll go through web browser. However my console client can't get a request to my API and I am not sure why. The only error i get is Cannot assign requested address in docker CLI.
class Program
{
static HttpClient client = new HttpClient();
static string apiUrl = "http://localhost:8080";
static void Main()
{
System.Console.WriteLine("Console started.");
RunAsync().GetAwaiter().GetResult();
}
static async Task RunAsync()
{
// Update port # in the following line.
client.BaseAddress = new Uri("http://localhost:64195/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
System.Console.WriteLine(client.BaseAddress);
try
{
var value = await GetValueAsync();
}
}
}
And the method that generate the error:
static async Task<Value> GetValueAsync()
{
Value value = null;
HttpResponseMessage response = await client.GetAsync(apiUrl + "/value");
System.Console.WriteLine("TEST");
if (response.IsSuccessStatusCode)
{
value = await response.Content.ReadAsAsync<Value>();
}
return value;
}
Program stops and returns an error on the client.GetAsync line, it never gets to the writeline("TEST"). Anyone knows what could be the problem? Everything else works until the request. On the request the Cannot assign requested address shows up and stops the container/program.
The code below works for sending a HTTP post to Webhook.site, but when doing the same request to my own azurewebsite the debugger stops at postasync and the ’response’ variable remains null.
My azure website returns 200 from json-string POST from ReqBin. My excel application can send working http posts to Webhook.site using the code below, just not to my own azurewebsite. What am I missing?
Some resources suggest SSL validation might cause problems? Not sure if this is the case.
private static readonly HttpClient client = new HttpClient();
public async Task<HttpResponseMessage> PostRequest(IRibbonControl control)
{
var content = new StringContent(json_object.ToString(), System.Text.Encoding.UTF8, "application/json");
//This is where i input my own website and it doesn't work
HttpResponseMessage response = await client.PostAsync("https://webhook.site/9b994ad0-81a1-496f-b910-d48d0567b1b8", content).ConfigureAwait(false);
var responseString = await response.Content.ReadAsStringAsync();
return response;
}
Thank you for your help.
To see result of postAsync method in debug execute 2 steps. Screenshot: postAsync debug
return HttpResponseMessage from method with postAsync:
private static async Task<HttpResponseMessage> methodWithPostAsync(){
...
response = await client.PostAsync(url, data);
return response
}
call method and wait for response message status:
Task<HttpResponseMessage> content= methodWithPostAsync();
while (!content.IsCompleted)
{
Console.WriteLine("busy");
System.Threading.Thread.Sleep(1000);
}
When testing my web API with Postman my API get executes fine!
When it comes to running the code with HttpClient in my client application the code executes without error but without the expected result on the server.
What could be happening?
From my client application:
private string GetResponseFromURI(Uri u)
{
var response = "";
HttpResponseMessage result;
using (var client = new HttpClient())
{
Task task = Task.Run(async () =>
{
result = await client.GetAsync(u);
if (result.IsSuccessStatusCode)
{
response = await result.Content.ReadAsStringAsync();
}
});
task.Wait();
}
return response;
}
Here is the API controller:
[Route("api/[controller]")]
public class CartsController : Controller
{
private readonly ICartRepository _cartRepo;
public CartsController(ICartRepository cartRepo)
{
_cartRepo = cartRepo;
}
[HttpGet]
public string GetTodays()
{
return _cartRepo.GetTodaysCarts();
}
[HttpGet]
[Route("Add")]
public string GetIncrement()
{
var cart = new CountedCarts();
_cartRepo.Add(cart);
return _cartRepo.GetTodaysCarts();
}
[HttpGet]
[Route("Remove")]
public string GetDecrement()
{
_cartRepo.RemoveLast();
return _cartRepo.GetTodaysCarts();
}
}
Note these API calls work as expected when called from Postman.
You shouldn't use await with client.GetAsync, It's managed by .Net platform, because you can only send one request at the time.
just use it like this
var response = client.GetAsync("URL").Result; // Blocking call!
if (response.IsSuccessStatusCode)
{
// Parse the response body. Blocking!
var dataObjects = response.Content.ReadAsAsync<object>().Result;
}
else
{
var result = $"{(int)response.StatusCode} ({response.ReasonPhrase})";
// logger.WriteEntry(result, EventLogEntryType.Error, 40);
}
You are doing fire-and-forget approach. In your case, you need to wait for the result.
For example,
static async Task<string> GetResponseFromURI(Uri u)
{
var response = "";
using (var client = new HttpClient())
{
HttpResponseMessage result = await client.GetAsync(u);
if (result.IsSuccessStatusCode)
{
response = await result.Content.ReadAsStringAsync();
}
}
return response;
}
static void Main(string[] args)
{
var t = Task.Run(() => GetResponseFromURI(new Uri("http://www.google.com")));
t.Wait();
Console.WriteLine(t.Result);
Console.ReadLine();
}
Simple sample used to get page data.
public string GetPage(string url)
{
HttpResponseMessage response = client.GetAsync(url).Result;
if (response.IsSuccessStatusCode)
{
string page = response.Content.ReadAsStringAsync().Result;
return "Successfully load page";
}
else
{
return "Invalid Page url requested";
}
}
I've had a problem with chace control when using httpclient.
HttpBaseProtocalFilter^ filter = ref new HttpBaseProtocolFilter();
filter->CacheControl->ReadBehavior = Windows::Web::Http::Filters::HttpCacheReadBehavior::MostRecent;
HttpClient^ httpClient = ref new HttpClient(filter);
I'm not really sure what the expected results are or what results your getting at all so this is really just a guessing game right now.
When I POST something using HttpClient I found adding headers by hand seemed to work more often than using default headers.
auto httpClient = ref new HttpClient();
Windows::Web::Http::Headers::HttpMediaTypeHeaderValue^ type = ref new Windows::Web::http::Headers::HttpMediaTypeHeaderValue("application/json");
content->Headers->ContentType = type;
If I don't do these 2 things I found, for me anyways, that half the time my web requests were either not actually being sent or the headers were all messed up and the other half of the time it worked perfectly.
I just read a comment where you said it would only fire once, that makes me think it is the cachecontrol. I think what happens is something (Windows?) sees 2 requests being sent that are the exact same, so to speed things up it just assumes the same answer and never actually sends the request a 2nd time
I am trying to send an Http Get message to the Google location Api which is supposed to have Json data such as this
https://maps.googleapis.com/maps/api/geocode/json?address=Los%20Angeles,CA=AIzaSyDABt
as you noticed the response is in Json. I want to give a a Http Call to that URL and save the Json content in a variable or string. My code does not give out any errors but it is also not returning anything
public async System.Threading.Tasks.Task<ActionResult> GetRequest()
{
var client = new HttpClient();
HttpResponseMessage response = await client.GetAsync("https://maps.googleapis.com/maps/api/geocode/json?address=Los%20Angeles,CA=AIzaSyDABt");
string data = response.Content.ToString();
return data;
}
I want to send out a Get Request using HttpClient() or anything that will send out the URL request and then save that content into a string variable . Any suggestions would be appreciated, again my code gives no errors but it is not returning anything.
Use ReadAsStringAsync to get the json response...
static void Main(string[] args)
{
HttpClient client = new HttpClient();
Task.Run(async () =>
{
HttpResponseMessage response = await client.GetAsync("https://maps.googleapis.com/maps/api/geocode/json?address=Los%20Angeles,CA=AIzaSyDABt");
string responseString = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseString);
});
Console.ReadLine();
}
If you use response.Content.ToString() it is actually converting the datatype of the Content to string so you will get System.Net.Http.StreamContent
Try this.
var client = new HttpClient();
HttpResponseMessage httpResponse = await client.GetAsync("https://maps.googleapis.com/maps/api/geocode/json?address=Los%20Angeles,CA=AIzaSyDABt");
string data = await httpResponse.Content.ReadAsStringAsync();
How about using the Json framework for .NET powered by Newtonsoft ?
You can try to parse your content to a string with this.
Well, your code can be simplified:
public async Task<ActionResult> GetRequest()
{
var client = new HttpClient();
return await client.GetStringAsync("https://maps.googleapis.com/maps/api/geocode/json?address=Los%20Angeles,CA=AIzaSyDABt");
}
However...
My code does not give out any errors but it is also not returning anything
This is almost certainly due to using Result or Wait further up the call stack. Blocking on asynchronous code like that causes a deadlock that I explain in full on my blog. The short version is that there is an ASP.NET request context that only permits one thread at a time; await by default will capture the current context and resume in that context; and since Wait/Result is blocking a thread in the request context, the await cannot resume executing.
Try this
public async static Task<string> Something()
{
var http = new HttpClient();
var url = "https://maps.googleapis.com/maps/api/geocode/json?address=Los%20Angeles,CA=AIzaSyDABt";
var response = await http.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
result = JsonConvert.DeserializeObject<string>(result);
return result;
}
return "";
}
var result = Task.Run(() => Something()).Result;
I have code like this:
public async Task<string> getToken()
{
string uri = "http://localhost/api/getToken";
HttpClient client = new HttpClient();
//client.BaseAddress = new Uri(uri);
string token = "asfd";
string baseId = "asfasdf";
string appVersion = "afsadf";
string content = "";
HttpResponseMessage response = null;
try
{
string url = string.Format("{0}?token='{1}'&baseId='{2}'&appVersion='{3}'", uri, token, baseId, appVersion);
//client.BaseAddress = new Uri(url);
response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();
content = await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
}
return content;
}
And when I get to the line when is GetAsync called VS turn off debug mode and does not throw any exception.
On the server I have breakpoint in the action in controller (mvc web api) and it is not reached.
But when I copy url and past it to the browser action in controller is invoked.
And when I change my url for some other incorrect url, GetAsync throw exception which is captured in catch.
My application is in .net framework 4.5, console application.
Maybe I must add any dll ?
You probably aren't waiting for the asynchronous operation to complete. That's why it gets to that aysnc call, the method returns the task that represents the operation and then the application ends.
You need to await the task getToken returns by using await getToken(). If you call getToken from the main method, which can't be async you need to use Task.Wait to wait synchronously:
static void Main()
{
getToken().Wait();
}