Downloading webpages in WinRT throws an exception - c#

I'm using this code to download a web page in my Metro Style app:
public static async Task<string> DownloadPageAsync(string url)
{
HttpClientHandler handler = new HttpClientHandler();
handler.UseDefaultCredentials = true;
handler.AllowAutoRedirect = true;
HttpClient client = new HttpClient(handler);
HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
string responseBody = response.Content.ReadAsString();
return responseBody;
}
the problem is that when the line client.GetAsync(url) runs, it throws an exception that says:
An error occurred while sending the request. From type: HttpRequestException.
EDIT:
I've used the InnerException to get more info. The first exception thrown is SocketException with the message below:
An attempt was made to access a socket in a way forbidden by its access permissions
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
EDIT 2:
I've downloaded and ran the sample from Microsoft and I get the same error:
http://code.msdn.microsoft.com/windowsapps/HttpClient-Upload-Sample-f1abcc4e
EDIT 3:
I ran this on another machine and it worked fine. So I guess there's nothing wrong with the code. I copied the solution and it means that there's nothing wrong with the solution either. I'm trying to re-install Windows Developer Preview to see if it fixes my problem.

OK. I found the answer. The exception was because I installed NetLimiter product on Windows 8 Developer Preview and somehow it prevented my app from accessing the internet.
UPDATE:
First of all, this is the code working in EVERY version of Windows 8.
public static async Task<string> DownloadPageAsync(string url)
{
try
{
HttpClientHandler handler = new HttpClientHandler { UseDefaultCredentials = true, AllowAutoRedirect = true };
HttpClient client = new HttpClient(handler);
HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
string html = await response.Content.ReadAsStringAsync();
return html;
}
catch (Exception)
{
return "";
}
}
Secondly, if this doesn't work, chances are, you have a network-related software preventing your app to access the Internet. One popular case is proxifier. If you have proxifier installed your MetroStyle apps won't be able to access the internet. To make it work, please refer to my blog at:
http://anoori.me/blog/general/use-proxifier-in-windows-8-without-fiddler2

pretty sure netlimiter was running your internet request through a localhost proxy, and your app didn't have the "local network" capability which would allow such access to the local network

Related

Adding SSL cert causes 404 only in browser calls

I am working in an internal corporate environment. We have created a webapi installed on iis on port 85. We call this from another MVC HelperApp on port 86. It all works as expected. Now we want to tighten security and add an SSL cert to iis on port 444 and bind it to our API.
Initially we test it with Postman, SoapUI, and a C# console app and it all works. Now we try calling it from our MVC HelperApp and it returns a 404 sometimes.
Deeper debugging; I put the code into a C# DLL (see below). Using the console app I call the Dll.PostAPI and it works as expected. Now I call that same Dll.PostAPI from the MVC HelperApp and it won't work. When I step through the code I make it as far as this line await client.PostAsync(url, data); and the code bizarrely ends, it doesn't return and it doesn't throw an exception. Same for Post and Get. I figure it makes the call and nothing is returned, no response and no error.
Also, if I change the url to "https://httpbin.org/post" or to the open http port85 on iss it will work. I have concluded that the C# code is not the problem (but I'm open to being wrong).
Therefore I have come to the conclusion that for some reason the port or cert is refusing calls from browsers.
We are looking at:
the "Subject Alternative Name" but all the examples show
WWW.Addresses which we are not using.
the "Friendly Name" on the cert creation.
and CORS Cross-Origin Resource Sharing.
These are all subjects we lack knowledge in.
This is the calling code used exactly the same in the console app and the web app:
var lib = new HttpsLibrary.ApiCaller();
lib.makeHttpsCall();
This is what's in the DLL that gets called:
public async Task<string> makeHttpsCall()
{
try
{
List<Quote> quotes = new List<Quote>();
quotes.Add(CreateDummyQuote());
var json = JsonConvert.SerializeObject(quotes);
var data = new StringContent(json, Encoding.UTF8, "application/json");
var url = "https://httpbin.org/post"; //this works in Browser
//url = "https://thepath:444//api/ProcessQuotes"; //444 DOES NOT WORK in browsers only. OK in console app.
//url = "http://thepath:85/api/ProcessQuotes"; //85 works.
var client = new HttpClient();
var response = await client.PostAsync(url, data); //<<<this line never returns when called from browser.
//var response = await client.GetAsync(url); //same outcome for Get or Post
var result = await response.Content.ReadAsStringAsync();
return result;
}
catch (Exception ex)
{
throw;
}
}

Xamarin.Forms iOS throwing NSURLErrorDomain "internet connection offline" when device is online

When calling a request from the HTTP manager the application throws an NSURL Error that states the internet connection is offline.
Foundation.NSErrorException: Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline."
This is only happening sometimes and every time that it is happening the device has internet access.
Upon attempting to debug the solution it seems that the rest service call for client.GetAsync isn't returning a response.
public async Task<T> callGetAsync<T>(string path) {
using(var client = new HttpClient()) {
var result = default(T);
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
if (App.User.Context != null)
{
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", App.User.Context.AccessToken);
}
HttpResponseMessage response = await client.GetAsync(path);
if(response.IsSuccessStatusCode) {
string json = await response.Content.ReadAsStringAsync();
result = JsonConvert.DeserializeObject<T>(json);
}
else {
Console.WriteLine("Error");
Analytics.TrackEvent($"API Failure: {path}");
}
return result;
}
}
The expected result is the application should successfully make the call and return the desired results, instead the application is suggesting the internet connection is offline.
Has anyone else seen this behavior? If so, have you been able to solve it?
This has been reported to be an issue with Visual Studio Preview builds. Downgrading back to the latest stable release has fixed the issue for now.
https://github.com/xamarin/xamarin-macios/issues/6762#issuecomment-524016733
I found this and Visual Studio 2019 is long out of preview. Looking up this error in different places. I read "Check the URL that you are using and make sure that is correct" and thought of course it is. I was wrong. So this is a friendly reminder. Check your pride and the URL :) Don't worry I made the same mistake.

await HttpClient.SendAsync not throwing exception when expected

I have a Windows Phone 8 app containing code as follows:
using (var client = new HttpClient())
{
var httpRequest = new HttpRequestMessage(method, uri);
try
{
var response = client.SendAsync(httpRequest);
var httpResponse = await response;
if (httpResponse.IsSuccessStatusCode)
{
var result = await httpResponse.Content.ReadAsStringAsync();
return result;
}
else
{
HandleError(httpResponse);
return null;
}
}
catch (Exception ex)
{
throw;
}
}
If the client successfully connects to the server, I will get the expected results, including all the appropriate HTTP status codes and reason phrases.
If the client is unable to contact the server (e.g. incorrect domain/IP/port in the URL), the awaited task completes after some delay, with a 404 status and no reason phrase. The task never throws an exception. The task (the response variable in the code snippet) has the status of "ran to completion". Nothing about the result is indicative of the actual problem - be it networking failure, unreachable server, etc.
How can I capture more meaningful errors in the case where the URL points to a non-existent or unreachable server, socket connection refused, etc.? Shouldn't SendAsync be throwing specific exceptions for such cases?
FWIW, the client code is built into a PCL library using VS 2013 update 3 and running in the Windows Phone emulator, using System.Net.Http 2.2.28 from NuGet
Windows Phone's implementation of the .NET HttpClient is different from Desktop's implementation (wininet vs. custom stack). This is one of the incompatibilities that you need to be aware of, if there is a semantic difference for you.
In my simple test I do get a ReasonPhrase of "Not Found" on the phone emulator. Also you can see that the Headers collection is empty whereas if the server was found and actually returned a real 404 then there would be headers.

Windows store app HttpClient issue

i'm testing some code here and came across a really weird issue. The HttpClient class works like a charm if my tablet is on but whenever the battery safe state kicks in and the screen is locked the HttpClient class throw an exception and the app suddendly exits giving me small chances to log the exception. If i'm not mistaken the error seems to be a send request error but that's weird since i have full access to the internet while the tablet is on.
Here the code i'm using and the one that crash on that state(System.Net.Http namespace ):
private static async Task<string> HttpGet(string uri)
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("User-Agent", BotUserAgent);
var response = await client.GetAsync(uri);
return await response.Content.ReadAsStringAsync();
}
}
Alternatively i've used the client of the web.http namespace with the same result:
using(var client = new Windows.Web.Http.HttpClient())
{
client.DefaultRequestHeaders.Add("User-Agent", BotUserAgent);
var response = await client.GetAsync(new Uri(uri));
return await response.Content.ReadAsStringAsync();
}
This is the error i get(after adding an exception logger):
An error occurred while sending the request.
Any ideas?
The problem is that your WinRT-device sends your app to the background when the battery safe state kiks in.
whenever the user moves your app into the background, your app can be suspended or frozen, essentially stopping any downloads dead in their tracks. In some scenarios, the app might
even be terminated, forcing you to create a new instance of the class in an attempt to start the download again. Fortunately, WinRT provides a way to handle this specific scenario using a background task.
This is a quote from http://www.informit.com/articles/article.aspx?p=2229233&seqNum=6
On this site is an easy tutorial to follow on how to use BackgroundTransfers in the Windows.Networking.BackgroundTransfer-Namespace.

azure website running in browser but not in PCL

I have a azure website which was running in browser. If I go to a particular page like my.azurewebsites.net/rest/api it's showing response on webpage. But if I used it in my PCL code like this
using (var httpClient = new HttpClient() { MaxResponseContentBufferSize = int.MaxValue })
{
HttpResponseMessage response = await httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
Than its showing inner exception "The remote name could not be resolved".
Addition information; "An error occurred while sending request"
3 days before it was working fine. Now I don't know what happened and how to fix.

Categories