I'm trying to use the Windows.Web.Http.HttpClient class but it keeps throwing me an 404 error, even if I try the code from the doc :
var uri = new Uri("http://example.com/datalist.aspx");
var httpClient = new HttpClient();
try
{
var result = await httpClient.GetStringAsync(uri);
Debug.WriteLine("content : {0}", result);
}
catch (Exception e)
{
Debug.WriteLine("error : {0}", e.Message);
}
And this is the error :
A first chance exception of type 'System.Exception' occurred in mscorlib.ni.dll
error : Not found (404).
Response status code does not indicate success: 404 (Not Found).
link of the doc I used
I can access the address from the phone with a web browser like IE.
That's because it does return a 404 (use a sniffer and check).
Change the url to http://www.example.com and things will work.
The site returns the same response on all requests. You can try:
http://www.example.com/mynickistuff.abcd
Related
I have made a website to check if it is still working or not, on my machine it works normally but when I publish it on the server, it gives error 500. I looked at the article on microsoft and saw "Don't use WebRequest or its derived classes for new development. Instead, use the System.Net.Http.HttpClient class."
But I don't know how to use that method. How do I change the method of my website?
And this is my code:
public static bool WebRequestTest(string url)
{
try
{
System.Net.WebRequest myRequest = System.Net.WebRequest.Create(url);
System.Net.WebResponse myResponse = myRequest.GetResponse();
}
catch (System.Net.WebException)
{
return false;
}
return true;
}
And this is my error:
Server Error in '/' Application. Invalid URI: The format of the URI could not be determined. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.UriFormatException: Invalid URI: The format of the URI could not be determined.
You can do like below code
public static async Task<bool> WebRequestTest(string url)
{
try
{
using (var client = new HttpClient())
{
var result = await client.GetAsync(url);
HttpStatusCode httpStatusCode= result.StatusCode;
}
}
catch (System.Net.WebException)
{
return false;
}
return true;
}
You will get lot of example about Httpclient.
Hey guys,
I have a problem with my code. Since about a week my code is not working anymore without any changes. I am pretty sure, that my could should work. All I get is Error 404: forbidden.
Below is a snippet of my Code. I also read about adding a header of the webclient, which did not help. Any other suggestions? I am sorry if my syntax is not that good, it is my first post on stackoverflow.
Thanks in advance!
string epicId = "ManuelNotManni";
WebClient webClient = new WebClient();
Uri uri = new Uri("https://api.tracker.gg/api/v2/rocket-league/standard/profile/epic/");
string result = String.Empty;
try
{
string website = $"{uri.ToString()}{epicId}?";
result = webClient.DownloadString(website);
}
catch (Exception ex)
{
Console.WriteLine($"Error:\n{ex}");
Console.ReadLine();
}
finally
{
webClient.Dispose();
}
This is the exact error:
System.Net.WebException: The remote server returned an error: (403) Forbidden.
at System.Net.HttpWebRequest.GetResponse()
at System.Net.WebClient.GetWebResponse(WebRequest request)
at System.Net.WebClient.DownloadBits(WebRequest request, Stream writeStream)
at System.Net.WebClient.DownloadDataInternal(Uri address, WebRequest& request)
at System.Net.WebClient.DownloadString(Uri address)
at System.Net.WebClient.DownloadString(String address)
at TestProject.Program.Main(String[] args) in > C:\Users\Manue\source\repos\TestProject\Program.cs:line 17
You're right. Your code should work fine.
Issue is that URL you're requesting which is actually:
https://api.tracker.gg/api/v2/rocket-league/standard/profile/epic/ManuelNotManni?
This returns a 403 status code in any case - no matter if you use a browser, your code or for example postman.
I suggest to have a look at the response body while using postman.
It shows this
<html class="no-js" lang="en-US">
<!--<![endif]-->
<head>
<title>Attention Required! | Cloudflare</title>
<meta name="captcha-bypass" id="captcha-bypass" />
Tracker.gg wants API users to register their apps with them before they're given access to the API.
What you need to do is to first head to their Getting Started page. Here you will have to create an app, which should give you an authentication key.
When you have done this, you want to change your code slightly to add the Authentication Header. Like so for example:
var webClient = new WebClient();
webclient.Headers.Add("TRN-Api-Key", "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
As a sidenote, WebClient has been deprecated and it's recommended to use HttpClient from now on. Here's your code with HttpClient instead:
var epicId = "ManuelNotManni";
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("TRN-Api-Key", "YOUR API KEY GOES HERE");
// Simplifying Uri creation:
var uri = new Uri($"https://api.tracker.gg/api/v2/rocket-league/standard/profile/epic/{epicId}");
var result = string.Empty; // C# prefers lowercase string
try
{
var response = await httpClient.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
result = await response.Content.ReadAsStringAsync();
}
else
{
Console.WriteLine($"Unable to retrieve data for {epicId}.");
Console.WriteLine($"Statuscode: {response.StatusCode}");
Console.WriteLine($"Reason: {response.ReasonPhrase}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error:\n{ex}");
Console.ReadLine();
}
finally
{
httpClient.Dispose();
}
This happens when we violate the Firewall rule set by Cloudflare, you can visit this blog for more details.
https://community.cloudflare.com/t/community-tip-fixing-error-1020-access-denied/66439
The code goes below
public static async Task<string> getForwardUrl(string url)
{
try
{
HttpClient client = new HttpClient();
HttpRequestMessage forwardRequest = new HttpRequestMessage();
forwardRequest.RequestUri = new Uri(url);
HttpResponseMessage Message = await client.SendAsync(forwardRequest);
return Message.RequestMessage.RequestUri.OriginalString;
}
catch (Exception ex)
{
WriteLine(ex.Message);
}
//...
}
When I run this in a uwp project, exception occurs. The message of this exception shows that the redirection request would change the safe connection to an unsafe one(After that , I checked the URL of the login page , It's https ,but the page after I logged in is http).
I find a similar question, he recommends using Windows.Web.Http instead of System.Net.Http but I get the same error message.
Thanks for your reply
EDIT:
The URL is: https://tinyurl.com /57muy (remove the space) or short a http url with tinyurl.com! The problem only occurs with a shortet http side!
Error: An error occurred while sending the request. Innermessage: Error message not found for this error
According to your description, I'd suppose you are developing a UWP app. And as you've mentioned, we got the exception here because the redirection request would change the safe connection to an unsafe one. To solve this problem, we can turn off auto-redirect and do the redirection by ourselves.
For example:
public static async Task<string> getForwardUrl(string url)
{
var handler = new System.Net.Http.HttpClientHandler();
handler.AllowAutoRedirect = false;
var client = new System.Net.Http.HttpClient(handler);
var response = await client.GetAsync(url);
if (response.StatusCode == System.Net.HttpStatusCode.Redirect || response.StatusCode == System.Net.HttpStatusCode.Moved)
{
return response.Headers.Location.AbsoluteUri;
}
return url;
}
I'm trying to get a JSON response from a service in my C# code. I generate the URL, and pass it to the webClient.DownloadString method, where it comes back with a 400 error. I can copy the URL into a browser and get a correct response.
What might I be missing?
Here's the code:
using (var webClient = new WebClient())
{
try
{
var requestUrl = GetRequestUrl(email);
// Error here
var jsonResponse = webClient.DownloadString(requestUrl);
//...
}
catch (Exception exception)
{
// ...
}
}
Here's a sample of the URL as it's generated from GetRequestUrl(email) which returns a string. (Certain values redacted)
http://api.someservice.org/api.php?usr=xxxxyyyy&pwd=zzz2345mmm22&check=none#nowhere.com
And here's what I get with an actual URL from a browser.
{"authentication_status":1,"limit_status":0,"limit_desc":"Not Limited","verify_status":1,"verify_status_desc":"MX record about nowhere.com exists.Connection succeeded to nowhere-com.mail.protection.outlook.com SMTP.220 BN3NAM01FT045.mail.protection.outlook.com Microsoft ESMTP MAIL Service ready at Mon, 29 Feb 2016 14:52:44 +0000\n> HELO verify-email.org250 BN3NAM01FT045.mail.protection.outlook.com Hello [verify-email.org]\n> MAIL FROM: <check#verify-email.org>=250 2.1.0 Sender OK\n> RCPT TO: <none#nowhere.com>=250 2.1.5 Recipient OK\n"}
UPDATE: Here's what GetRequestUrl does:
protected string GetRequestUrl(string email)
{
if (string.IsNullOrEmpty(email))
throw new ArgumentNullException("email");
var requestUrl = string.Format("http://api.someservice.org/api.php?usr={0}&pwd={1}&check={2}", ApiUsername, ApiPassword, Uri.EscapeUriString(email));
return requestUrl;
}
UPDATE: Here is the exception message, InnerException is NULL.
The remote server returned an error: (400) Bad Request.
UPDATE: Caught the WebException, and got the full ResponseStream. I don't think the call is actually going out, Fiddler doesn't catch a call to the address. Here's the exception.Response:
<h2>Bad Request - Invalid Hostname</h2>
<p>HTTP Error 400. The request hostname is invalid.</p>
I'm building an HTTP API client using RestSharp, and I've noticed that when the server returns an HTTP error code (401 Unauthorized, 404 Not Found, 500 Internal Server Error, etc.) the RestClient.Execute() doesn't throw an exception - instead I get a valid RestResponse with a null .Data property. I don't want to manually check for every possible HTTP error code within my API client - does RestSharp provide a better way of passing these errors to my client application?
A little further detail. RestSharp exposes a Response.ErrorException property - if the RestClient.Execute<T>() call causes any exception, it'll be exposed via the ErrorException property instead of being thrown. Their documentation includes the following example:
// TwilioApi.cs
public class TwilioApi {
const string BaseUrl = "https://api.twilio.com/2008-08-01";
public T Execute<T>(RestRequest request) where T : new()
{
var client = new RestClient();
client.BaseUrl = BaseUrl;
client.Authenticator = new HttpBasicAuthenticator(_accountSid, _secretKey);
request.AddParameter("AccountSid", _accountSid, ParameterType.UrlSegment); // used on every request
var response = client.Execute<T>(request);
if (response.ErrorException != null)
{
const string message = "Error retrieving response. Check inner details for more info.";
var twilioException = new ApplicationException(message, response.ErrorException);
throw twilioException;
}
return response.Data;
}
}
I've adopted that pattern in my code, but my API server is returning a 401 Unauthorized and yet the ErrorException property is still null. I can see the Unauthorized status code and error message in the RestResponse.StatusCode and RestResponse.StatusDescription properties - but I'm confused as to why an unauthorized response wouldn't result in the ErrorException field being populated.
I encountered this same problem while trying to create a generic error handler for a RestSharp WebAPI client. Given these extension methods:
public static class RestSharpExtensionMethods
{
public static bool IsSuccessful(this IRestResponse response)
{
return response.StatusCode.IsSuccessStatusCode()
&& response.ResponseStatus == ResponseStatus.Completed;
}
public static bool IsSuccessStatusCode(this HttpStatusCode responseCode)
{
int numericResponse = (int)responseCode;
return numericResponse >= 200
&& numericResponse <= 399;
}
}
I made a request that required the response to be deserialized:
public async Task<ResponseModel<TResponse>> PerformRequestAsync<TResponse>(IRestRequest request)
{
var response = await _client.ExecuteTaskAsync<ResponseModel<TResponse>>(request);
ResponseModel<TResponse> responseData;
if (response.IsSuccessful())
{
responseData = response.Data;
}
else
{
string resultMessage = HandleErrorResponse<TResponse>(request, response);
responseData = new ResponseModel<TResponse>
{
Success = false,
ResultMessage = resultMessage
};
}
return responseData;
}
However, during testing, I found that when I had no error handling configured for that case, my web serivce returned an HTML-formatted 404 page when an unmapped URL was requested. This caused the response.ErrorException property to contain the following string:
Reference to undeclared entity 'nbsp'. Line n, position m.
As apparently RestSharp tried to parse the response as XML, even though the content-type was text/html. Maybe I'll file an issue with RestSharp for this.
Of course in production you should never get a 404 when calling your own service, but I want this client to be thorough and reusable.
So there's two solutions I can think of:
Inspect the status code and show the description
Make sure the service returns an error object that you can parse
The former is done quite easily. In HandleErrorResponse() I build the result message (user presentable) and error string (loggable) based on the numeric value of the status code:
public string HandleErrorResponse(IRestRequest request, IRestResponse response)
{
string statusString = string.Format("{0} {1} - {2}", (int)response.StatusCode, response.StatusCode, response.StatusDescription);
string errorString = "Response status: " + statusString;
string resultMessage = "";
if (!response.StatusCode.IsScuccessStatusCode())
{
if (string.IsNullOrWhiteSpace(resultMessage))
{
resultMessage = "An error occurred while processing the request: "
+ response.StatusDescription;
}
}
if (response.ErrorException != null)
{
if (string.IsNullOrWhiteSpace(resultMessage))
{
resultMessage = "An exception occurred while processing the request: "
+ response.ErrorException.Message;
}
errorString += ", Exception: " + response.ErrorException;
}
// (other error handling here)
_logger.ErrorFormat("Error response: {0}", errorString);
return resultMessage;
}
Now as my API responses always are wrapped in a ResponseModel<T> of my making, I can set up an exception filter and a NotFound route to return a parsable response model with the error or exception message in the ResultMessage property:
public class HandleErrorAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
// (log context.Exception here)
context.Response = context.Request.CreateResponse(HttpStatusCode.InternalServerError, new ResponseModel<object>
{
Success = false,
ResultMessage = "An exception occurred while processing the request: " + context.Exception.Message
});
}
}
And:
public class ErrorController : ApiController
{
public HttpResponseMessage Handle404()
{
const string notFoundString = "The requested resource could not be found";
var responseMessage = Request.CreateResponse(HttpStatusCode.NotFound, new ResponseModel<object>
{
Success = false,
ResultMessage = notFoundString
});
responseMessage.ReasonPhrase = notFoundString;
return responseMessage;
}
}
This way the response from my service can always be parsed by RestSharp, and I can use the generic logging method:
public string HandleErrorResponse<TResponseModel>(IRestRequest request, IRestResponse<<ResponseModel<TResponseModel>> response)
And log the actual response at // (other error handling here), if available:
if (response.Data != null && !string.IsNullOrWhiteSpace(response.Data.ResultMessage))
{
resultMessage = response.Data.ResultMessage;
errorString += string.Format(", Service response: \"{0}\"", response.Data.ResultMessage);
}
RestSharp has added boolean property IRestResponse.IsSuccessful which covers your use case. I couldn't find any documentation referring to this property, but here's the line that defines the property's method.
Interesting to note is that RestSharp considers codes 200-299 to be successful, while CodeCaster considers codes 200-399 to be successful.
It should be enough to check for a success code, and throw or report the error if you get any other code apart from success. This usually means checking for HTTP Status 200 after every request. If you create a new resource, you should expect Status 201.
With most APIs/frameworks, it is very very unusual to see any other status code except these if nothing has gone wrong.