I have following C# code:
Uri url = new Uri("http://lu32kap.typo3.lrz.de/mensaapp/exportDB.php?mensa_id=all");
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.UserAgent.TryParseAdd("Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
var content = response.Content;
if(content != null)
{
string result = await content.ReadAsStringAsync();
if (result != null)
{
tblock.Text = result;
}
}
Every time I run it, I get a COMException "HRESULT E_FAIL".
I was able to track it down partially. It's caused by the website I'm trying to get my data from because if I'm changing it to "https://www.google.de/" it works.
It's crashing at:
string result = await content.ReadAsStringAsync();
Nevertheless I need to get it to work with this website because it returns a, with PHP generated, json object.
Is there a way to fix this?
The image behind this link shows the crash in VS2015
I ran this code locally and I end up getting this Exception
The character set provided in ContentType is invalid. Cannot read
content as string using an invalid character set.
And it looks like it is returning UTF8
'utf8' is not a supported encoding name. For information on defining a
custom encoding, see the documentation for the
Encoding.RegisterProvider method.
Can you ensure that the output on the server is in the correct format? Perhaps try this answer:
Parsing UTF8 JSON response from server
Solution:
It was a problem with the UTF8 encoding. I was able to build a small workaround.
Thanks to Glitch100!
Uri url = new Uri("http://lu32kap.typo3.lrz.de/mensaapp/exportDB.php?mensa_id=all");
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.UserAgent.TryParseAdd("Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
IHttpContent content = response.Content;
if(content != null)
{
IBuffer buffer = await content.ReadAsBufferAsync();
using (DataReader dataReader = DataReader.FromBuffer(buffer))
{
string result = dataReader.ReadString(buffer.Length);
if (result != null)
{
tblock.Text = result;
}
}
}
Related
I have a UWP app written in C#.
For some specific users (i.e. specific PCs), the app is not able to perform HTTP requests.
Those PCs are not under any VPN, they turned off any firewall or antivirus, they tried with several connections (e.g. home router, phone hotspot, public wifi, etc.), always with the same result.
Opening a browser and browsing to
https://ltbackend.azurewebsites.net/diagnostic/ping
they are able to see the correct page (actually, a plain text "OK").
But if they use the app (which performs an HTTP GET call using C#), this one fails.
This is the code in C# that we use:
string pingUrl = "https://ltbackend.azurewebsites.net/diagnostic/ping";
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, pingUrl);
using (HttpClient httpClient = new HttpClient())
{
try
{
using (HttpResponseMessage response = await httpClient.SendAsync(req))
{
string stringRes = await response.Content.ReadAsStringAsync();
HttpStatusCode respCode = response.StatusCode;
// .... our biz logic with stringRes and respCode...
}
}
catch (HttpRequestException e)
{
// the ping request for those users throws this exception...
// the error message is "An error occurred while sending the request."
}
}
But if they use the app (which performs an HTTP GET call using C#), this one fails.
I have run your code within UWP platform, it could work well and return 'ok' string. But it looks you used HttpClient under System.Net.Http namespace, and it often used in cross-platform, such as xamarin app.
For sending get request within UWP, we suggest you use Windows.Web.Http.HttpClient. The following is simple get method you could refer to.
Windows.Web.Http.HttpClient httpClient = new Windows.Web.Http.HttpClient();
//Add a user-agent header to the GET request.
var headers = httpClient.DefaultRequestHeaders;
//The safe way to add a header value is to use the TryParseAdd method and verify the return value is true,
//especially if the header value is coming from user input.
string header = "ie";
if (!headers.UserAgent.TryParseAdd(header))
{
throw new Exception("Invalid header value: " + header);
}
header = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)";
if (!headers.UserAgent.TryParseAdd(header))
{
throw new Exception("Invalid header value: " + header);
}
Uri requestUri = new Uri("https://ltbackend.azurewebsites.net/diagnostic/ping");
//Send the GET request asynchronously and retrieve the response as a string.
Windows.Web.Http.HttpResponseMessage httpResponse = new Windows.Web.Http.HttpResponseMessage();
string httpResponseBody = string.Empty;
try
{
//Send the GET request
httpResponse = await httpClient.GetAsync(requestUri);
httpResponse.EnsureSuccessStatusCode();
httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
httpResponseBody = "Error: " + ex.HResult.ToString("X") + " Message: " + ex.Message;
}
For more info please refer HttpClient document.
If you are using latest version of .NET try once using WebClient instead of HttpClient.
Ref: https://learn.microsoft.com/en-us/dotnet/api/system.net.webclient.downloadstringasync?view=net-5.0
string pingUrl = "https://ltbackend.azurewebsites.net/diagnostic/ping";
var client = new WebClient();
string stringRes = await client.DownloadStringTaskAsync(pingUrl);
got typical api request for sending sms through sms gateway.
Any chance that I can check connection of the device?
string readUrl = "http://192.168.253.160/index.php/http_api/read_sms";
string result;
WebClient Client = new WebClient();
Client.QueryString.Add("login", "admin");
Client.QueryString.Add("pass", "password");
Client.QueryString.Add("folder", "sentitems");
Client.QueryString.Add("idfrom", "100");
Client.QueryString.Add("idto", "101");
Client.QueryString.Add("limit", "1");
Client.Headers.Add("user-agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0");
Stream receivedStream = Client.OpenRead(readUrl);
StreamReader reader = new StreamReader(receivedStream);
result = reader.ReadToEnd();
receivedStream.Close();
reader.Close();
MessageBox.Show(result);
I would like to make condition:
if(result == true)
{
button green
}
else
{
button Red
}
I know that if i check folder sentitems with correct ID and I get correct result I will get response what can I use in this condition. But this response is so long. So I am just thinking about another/different option.
Thanks
I have ASP.NET website. When I call the url 'http://example.org/worktodo.ashx' from browser it works ok.
I have created one android app and if I call the above url from android app then also it works ok.
I have created windows app in C# and if I call the above url from that windows app then it fails with error 403 forbidden.
Following is the C# code.
try
{
bool TEST_LOCAL = false;
//
// One way to call the url
//
WebClient client = new WebClient();
string url = TEST_LOCAL ? "http://localhost:1805/webfolder/worktodo.ashx" : "http://example.org/worktodo.ashx";
string status = client.DownloadString(url);
MessageBox.Show(status, "WebClient Response");
//
// Another way to call the url
//
WebRequest request = WebRequest.Create(url);
request.Method = "GET";
request.Headers.Add("Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
request.Headers.Add("Connection:keep-alive");
request.Headers.Add("User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36");
request.Headers.Add("Upgrade-Insecure-Requests:1");
request.Headers.Add("Accept-Encoding:gzip, deflate, sdch");
request.ContentType = "text/json";
WebResponse response = request.GetResponse();
string responseString = new System.IO.StreamReader(response.GetResponseStream()).ReadToEnd();
MessageBox.Show(responseString, "WebRequest Response");
}
catch (WebException ex)
{
string error = ex.Status.ToString();
}
The exception thrown is:
The remote server returned an error: (403) Forbidden.
StatusCode value is 'Forbidden'
StatusDescription value is 'ModSecurity Action'
Following is android app code (uses org.apache.http library):
Handler handler = new Handler() {
Context ctx = context; // save context for use inside handleMessage()
#SuppressWarnings("deprecation")
public void handleMessage(Message message) {
switch (message.what) {
case HttpConnection.DID_START: {
break;
}
case HttpConnection.DID_SUCCEED: {
String response = (String) message.obj;
JSONObject jobjdata = null;
try {
JSONObject jobj = new JSONObject(response);
jobjdata = jobj.getJSONObject("data");
String status = URLDecoder.decode(jobjdata.getString("status"));
Toast.makeText(ctx, status, Toast.LENGTH_LONG).show();
} catch (Exception e1) {
Toast.makeText(ctx, "Unexpected error encountered", Toast.LENGTH_LONG).show();
// e1.printStackTrace();
}
}
}
}
};
final ArrayList<NameValuePair> params1 = new ArrayList<NameValuePair>();
if (RUN_LOCALLY)
new HttpConnection(handler).post(LOCAL_URL, params1);
else
new HttpConnection(handler).post(WEB_URL, params1);
}
Efforts / Research done so far to solve the issue:
I found following solutions that fixed 403 forbidden error for them but that could not fix my problem
Someone said, the file needs to have appropriate 'rwx' permissions set, so, I set 'rwx' permissions for the file
Someone said, specifying USER-AGENT worked, I tried (ref. Another way to call)
Someone said, valid header fixed it - used Fiddler to find valid header to be set, I used Chrome / Developer Tools and set valid header (ref.
another way to call)
Someone configured ModSecurity to fix it, but, I don't have ModSecurity installed for my website, so, not an option for me
Many were having problem with MVC and fixed it, but, I don't use MVC, so those solutions are not for me
ModSecurity Reference manual says, to remove it from a website, add <modules><remove name="ModSecurityIIS" /></modules> to web.config. I did but couldn't fix the issue
My questions are:
Why C# WinApp fails where as Android App succeeds?
Why Android App doesn't encounter 'ModSecurity Action' exception?
Why C# WinApp encounter 'ModSecurity Action' exception?
How to fix C# code?
Please help me solve the issue. Thank you all.
I found the answer. Below is the code that works as expected.
bool TEST_LOCAL = false;
string url = TEST_LOCAL ? "http://localhost:1805/webfolder/worktodo.ashx" : "http://example.org/worktodo.ashx";
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "GET";
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36";
request.ContentType = "text/json";
WebResponse response = request.GetResponse();
string responseString = new System.IO.StreamReader(response.GetResponseStream()).ReadToEnd();
MessageBox.Show(responseString, "WebRequest Response");
NOTE: requires using System.Net;
I'm trying to deserialize some JSON in C#, but when I run my program I'm getting this error message:
I've looked through all my code, and I can't find a "<" anywhere there shouldn't be one, and I went to the web address that the json is coming from:
http://forecast.weather.gov/MapClick.php?lat=47.1211&lon=-88.5694&FcstType=json,
and there isn't a "<" character. I used json2csharp.com to translate to C# classes, and everything there seems fine as well. Any thoughts? Here is the part of my code where I try to do all of this:
var http = new HttpClient();
var url = "http://forecast.weather.gov/MapClick.php?lat=47.1211&lon=-88.5694&FcstType=json";
var response = await http.GetAsync(url);
var result = await response.Content.ReadAsStringAsync();
var serializer = new DataContractJsonSerializer(typeof(RootObject2));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var data = (RootObject2)serializer.ReadObject(ms);
return data;
Your call is failing because you are not setting a header the API is expecting. Add a user agent and check for success prior to attempting to read the response.
var http = new HttpClient();
var url = "http://forecast.weather.gov/MapClick.php?lat=47.1211&lon=-88.5694&FcstType=json";
//Supply the same header as chrome
http.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.84 Safari/537.36");
var response = await http.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var serializer = new DataContractJsonSerializer(typeof(RootObject2));
var data = (RootObject2)serializer.ReadObject(ms);
}
check that answer, it says some issue with the connection, that he was not receiving the full response from the API
Unexpected character encountered while parsing value:
I am trying to download a webpage using async and await and HttpClient, but am getting only a string full of special characters... Code is like..
static async void DownloadPageAsync(string url)
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml");
client.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate");
client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0");
client.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Charset", "ISO-8859-1");
HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
var responseStream = await response.Content.ReadAsStreamAsync();
var streamReader = new StreamReader(responseStream);
var str = streamReader.ReadToEnd();
}
and url is
url = #"http://www.nseindia.com/live_market/dynaContent/live_watch/live_index_watch.htm";
When i did
client.DefaultRequestHeaders.Add("User-Agent",
"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2;
WOW64; Trident/6.0)");
in place of those four DefaultRequestHeaders, I got a 403 error, but this is nse site and is free for all. Please help friends get me correct response..
regards
Srivastava
client.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate");
With this you tell the server that you allow it to compress the response gzip/deflate. So the response is actually compressed which explains why you get the kind of response text you get.
If you want plain text, you shouldn’t add the header, so the server won’t compress the response. If you remove above line, you get a normal HTML response text.
Alternatively, you can of course keep that header in and decompress the response using GZipStream after receiving it. That would work like this:
using (var responseStream = await response.Content.ReadAsStreamAsync())
using (var deflateStream = new GZipStream(responseStream, CompressionMode.Decompress))
using (var streamReader = new StreamReader(deflateStream))
{
var str = streamReader.ReadToEnd();
Console.WriteLine(str);
}
Ideally, you should check the value of response.Content.Headers.GetValues("Content-Encoding") to make sure that the encoding is gzip. Since you also accepted deflate as a possible encoding, you could then use DeflateStream to decode that; or don’t decode anything in case the Content-Encoding header is missing.