Webclient POST 405 Error in API - c#

I've written some code a while back that handles POST requests. Suddenly it stopped working whilst I changed nothing in either the API (It still works fine with postman) nor the C# code. But I get a 405 error (method not allowed) when I run my code.
The login method:
public byte[] logInViaAPI(string email, string password)
{
var response = APIHandler.Post("http://myurlhere", new NameValueCollection() {
{ "email", email },
{ "password", password },
});
return response;
}
This is my POST method:
public static byte[] Post(string uri, NameValueCollection pairs)
{
byte[] response = null;
try
{
using (WebClient client = new WebClient())
{
response = client.UploadValues(uri, pairs); //This is where I get my error
}
}
catch (WebException ex)
{
Console.Write(ex);
return null;
}
return response;
}
The error:
An unhandled exception of type 'System.Net.WebException' occurred in
System.dll
Additional information:
The remote server returned an error: (405) Method Not Allowed.
I used HTTP request with post as a source (and some other topics too) but I cant seem to figure out the problem.

Found the answer to my own question: I changed to protocol to HTTPS from HTTP, whilst still using the HTTP url.

Another possible solution is the use SecurityProtocol. Try this before the call:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Related

Bad Request : Sending request to ASP.NET WebAPI from android

I have tried to look for the solution for this with no success so far,
I am trying to call my ASP.NET WEB API (localhost:port) from Xamarin.Android (MainActivity).
I checked the API properly in Postman and it works as shown in the following screenshot
My code in Xamarin MainActivity is the following
try
{
using (var c = new HttpClient())
{
var client = new System.Net.Http.HttpClient();
var response = await client.GetAsync(new Uri("http://10.0.2.2:57348/api/remote"));
if (response.IsSuccessStatusCode)
{
Log.Info("myApp", "SUCCESS");
}
else
{
Log.Info("myApp", "ERROR: " + response.StatusCode.ToString());
}
}
}
catch (Exception X)
{
Log.Info("myApp", X.Message);
return X.Message;
}
I believe that 10.0.2.2 is to connect to the localhost from emulator -
When I run the code I get the error status as BadRequest
I also tried something like the following
try
{
Uri uri = new Uri("http://10.0.2.2:57348/api/remote");
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Method = "GET";
using (WebResponse response = await request.GetResponseAsync())
{
using (Stream stream = response.GetResponseStream())
{
Log.Info("myApp", "Success");
}
}
}
catch (Exception X)
{
Log.Info("myApp", X.Message);
}
I get 400 Bad Request
400 Bad Request means I am doing something wrong as assuming that my code can connect to the API but the server is considering API Call as invalid?
Just in case if anyone wants to know the code in my API, its the following
public class remoteController : ApiController
{
// GET: api/remote
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
Anyone has any idea about this, I have been trying different things for hours with no luck.
Also just to add, I tried 'http://10.0.2.2:57348/api/remote' in my Android Emulator's Chrome and I still get Bad Request response as shown in the following screenshot
but trying the same on my machine (browser) or Postman works fine using localhost
Please help
UPDATE:
Tried enabling External request on IIS Express using this http://www.lakshmikanth.com/enable-external-request-on-iis-express/
No luck,
The request is "bad" because the host header (in the request) is your 10.x.x.x. IP, and not localhost, which IIS Express won't accept.
We have an extension called "Conveyor", it's free and without configuration changes it opens up IIS Express to other machines on the network.
https://marketplace.visualstudio.com/items?itemName=vs-publisher-1448185.ConveyorbyKeyoti#overview
I think it is because of cross origin error add this in startup.cs ( in configure method)
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());

ApiController BadRequest(string message) method is not returning the custom message passed in parameter

On my console application I am making following webClient Request to upload the data.
using (var client = new WebClient())
{
client.Headers.Clear();
client.Headers.Add("Content-Type", "application/json; charset=utf-8");
client.UploadStringCompleted += (data, exception) =>
{
if (exception.Error != null)
{
_log.Error("Error While Posting XYZSets data {0}", exception.Error);
}
client.Dispose();
};
var ApplicationUrl = string.Format("{0}/api/AAA/PostXYZSets", ConfigurationManager.AppSettings["ApplicationUrl"]);
client.UploadStringAsync(new Uri(ApplicationUrl), jsonData);
}
In my MVC application at some point I am returning the IHttpActionResult by following code.
[ServiceAuthentication]
public IHttpActionResult PostXYZSets(XYZSet[] xYZSets)
{
return BadRequest("My Custom Error message");
}
But when UploadStringCompleted method receives exception, I nowhere find "My Custom Error message". it says (400) Bad Request.
Tell me what's wrong am i doing. thanks in advance.
The response is in the string returned, not in the header. It's there. Just read the return string as you would read an Ok response.

WebRequest Strange NotFound Error

I have 2 different ASP.NET Core websites: admin and public.
Both running on staging server and on local machine.
I send GET request to different pages to determine execution time of different pages and encountered problem with admin site: all urls on local instance and staging always returns 404 error:
An unhandled exception of type 'System.Net.WebException' occurred in
System.dll
Additional information: The remote server returned an error: (404) Not
Found.
Meanwhile, same requests in browser return html pages normally. Requests through HttpWebRequest to public site always also return 200 Status Code (OK).
Code for request I took here.
I tried to add all headers and cookies from browser request, but it didn't help. Also tried to debug local instance and found that no exceptions thrown while request executed.
Any ideas?
404 is way to generic. The code provided in answer in your link (https://stackoverflow.com/a/16642279/571203) does no error handling - this is brilliant example of how you can get to troubles when you blindly copy code from stackoverflow :)
Modified code with error handling should look like:
string urlAddress = "http://google.com/rrr";
var request = (HttpWebRequest)WebRequest.Create(urlAddress);
string data = null;
string errorData = null;
try
{
using (var response = (HttpWebResponse)request.GetResponse())
{
data = ReadResponse(response);
}
}
catch (WebException exception)
{
using (var response = (HttpWebResponse)exception.Response)
{
errorData = ReadResponse(response);
}
}
static string ReadResponse(HttpWebResponse response)
{
if (response.CharacterSet == null)
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
return reader.ReadToEnd();
}
}
using (var reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(response.CharacterSet)))
{
return reader.ReadToEnd();
}
}
So when there is an exception, you'll get not just the status code, but entire response from server in the errorData variable.
One thing to check is proxy - browser can use http proxy while your server client uses none.

HttpClient failing in accessing simple website

Here is my code
internal static void ValidateUrl(string url)
{
Uri validUri;
if(Uri.TryCreate(url,UriKind.Absolute,out validUri))
{
using (HttpClient client = new HttpClient())
{
try
{
HttpResponseMessage response = client.Get(url);
response.EnsureStatusIsSuccessful();
}
catch (Exception ex)
{
//exception handler goes here
}
}
}
}
This code when i run it produces this result.
ProxyAuthenticationRequired (407) is not one of the following:
OK (200), Created (201), Accepted (202), NonAuthoritativeInformation
(203), NoContent (204), ResetContent (205), PartialContent (206).
All i want to do is make this code validate whether a given website is up and running.
Any ideas?
This basically means exactly what it says: That you are trying to access the service via a proxy that you are not authenticated to use.
I guess that means your server was reached from the Web Service, but that it was not permitted to access the URL it tried to reach, since it tried to access it through a proxy it was not authenticated for.
It's what EnsureStatusIsSuccessful() does, it throws an exception if status code (returned from web server) is not one of that ones.
What you can do, to simply check without throwing an exception is to use IsSuccessStatusCode property. Like this:
HttpResponseMessage response = client.Get(url);
bool isValidAndAccessible = response.IsSuccessStatusCode;
Please note that it simply checks if StatusCode is within the success range.
In your case status code (407) means that you're accessing that web site through a proxy that requires authentication then request failed. You can do following:
Provide settings for Proxy (in case defaults one doesn't work) with WebProxy class.
Do not download page but just try to ping web server. You won't know if it's a web page or not but you'll be sure it's accessible and it's a valid URL. If applicable or not depends on context but it may be useful if HTTP requests fails.
Example from MSDN using WebProxy with WebRequest (base class for HttpWebRequest):
var request = WebRequest.Create("http://www.contoso.com");
request.Proxy = new WebProxy("http://proxyserver:80/",true);
var response = (HttpWebResponse)request.GetResponse();
int statusCode = (int)response.StatusCode;
bool isValidAndAccessible = statusCode >= 200 && statusCode <= 299;
You are invoking EnsureStatusIsSuccessful() which rightfully complains that the request was not successful because there's a proxy server between you and the host which requires authentication.
If you are on framework 4.5, I've included a slightly enhanced version below.
internal static async Task<bool> ValidateUrl(string url)
{
Uri validUri;
if(Uri.TryCreate(url,UriKind.Absolute,out validUri))
{
var client = new HttpClient();
var response = await client.GetAsync(validUri, HttpCompletionOption.ResponseHeadersRead);
return response.IsSuccessStatusCode;
}
return false;
}

Get html from Webclient even then Webclient throws exception

I'm working against an web API and then i authenticate myself to the webb API and provide the wrong username or password the site returns "The remote server returned an error: (401) Unauthorized." and that's fine.
But the site also return detailed information as JSON but I can't find out how to access this information then I'm getting a 401 exception.
Do anybody have a clue?
Here is the code I'm using:
private string Post(string data, string URI)
{
string response = string.Empty;
using (var wc = new WebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
try
{
response = wc.UploadString(URI, data);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
return response;
}
Thanks
You should receive a WebException.
The WebReception has a
Response
property, which should contain what you are looking for. You may check all other properties as well.

Categories

Resources