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

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());

Related

Webclient POST 405 Error in API

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;

Differences between using C# HttpClient API and the postman testing? Client call works on postman, but not C# httpClient getAsync

I am testing a REST API post, and it works well when I try it on Postman. However, in some scenario (related to the posting XML data) if I post with HttpClient API, I would receive the following error:
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
But the same XML content works fine on Postman with status OK and proper response.
What is the differences between using the C# HttpClient API and the postman testing? How can I configure my API call to match with the behavior on postman?
Here I attached the source code, and the Postman screenshot
public void createLoan()
{
string baseCreateLoanUrl = #"https://serverhost/create?key=";
var strUCDExport = XDocument.Load(#"C:\CreateLoan_testcase.xml");
using (var client = new HttpClient())
{
var content = new StringContent(strUCDExport.ToString(), Encoding.UTF8, Mediatype);
string createLoanApi = string.Concat(baseCreateLoanUrl, APIKey);
try
{
var response = client.PostAsync(createLoanApi, content).Result;
}
catch (Exception ex)
{
MessageBox.Show("Error Happened here...");
throw;
}
if (response.IsSuccessStatusCode)
{
// Access variables from the returned JSON object
string responseString = response.Content.ReadAsStringAsync().Result;
JObject jObj = JObject.Parse(responseString);
if (jObj.SelectToken("failure") == null)
{
// First get the authToken
string LoanID = jObj["loanStatus"]["id"].ToString();
MessageBox.Show("Loan ID: " + LoanID);
}
else
{
string getTokenErrorMsg = string.Empty;
JArray errorOjbs = (JArray) jObj["failure"]["errors"];
foreach (var errorObj in errorOjbs)
{
getTokenErrorMsg += errorObj["message"].ToString() + Environment.NewLine;
}
getTokenErrorMsg.Dump();
}
}
}
Thanks for Nard's comment, after comparing the header, I found the issue my client header has this:
Expect: 100-continue
While postman doesn't has.
Once I removed this by using the ServicePointManager:
ServicePointManager.Expect100Continue = false;
Everything seems fine now. Thanks all the input!
My gut tells me it's something simple. First, we know the API works, so I'm thinking it's down to how you are using the HttpClient.
First things first, try as suggested by this SO answer, creating it as a singleton and drop the using statement altogether since the consensus is that HttpClient doesn't need to be disposed:
private static readonly HttpClient HttpClient = new HttpClient();
I would think it would be either there or an issue with your content encoding line that is causing issues with the API. Is there something you are missing that it doesn't like, I bet there is a difference in the requests in Postman vs here. Maybe try sending it as JSON ala:
var json = JsonConvert.SerializeObject(strUCDExport.ToString());
var content = new StringContent(json, Encoding.UTF8, Mediatype);
Maybe the header from Postman vs yours will show something missing, I think the real answer will be there. Have fiddler running in the background, send it via Postman, check it, then run your code and recheck. Pay close attention to all the attribute tags on the header from Postman, the API works so something is missing. Fiddler will tell you.
I was struggling with this for 2 days when I stumbled over Fiddler which lets you record the traffic to the service. After comparing the calls I saw that I had missed a header in my code.

Web API returns status 413

I am consuming a ASP.Net WEB API written in c# hosted in IIS6. When making a POST to the API it returns HTTP status 413. The API (not WCF) returns response as long as the content in the body is around 32+KB. If the size is like 40 KB then it errors out.
Below is the code snippet on the consumer side
string apiUrl = "https://a.com/api/emails/send";
using (WebClient client = new WebClient())
{
client.Headers.Add("Content-Type", "application/json");
client.Headers.Add("Accept", "application/json");
try
{
var jsonResponce = client.UploadString(apiUrl, jsonRequest);
var sendEmailResponce = JsonConvert.DeserializeObject<SendEmailResponce>(jsonResponce);
var emailMessageId = sendEmailResponce.EmailMessageId;
Console.WriteLine("email sent.");
}
catch (WebException exp)
{
var error = exp.ToString();
Console.WriteLine(error);
}
catch (Exception exp)
{
var error = exp.Message;
}
}
I am using IIS6 . Is there any setting in IIS / Code changes on the client might help me to get around this issue?
try this,
Launch “Internet Information Services (IIS) Manager”
Select the site that you are hosting your web application under it.
In the Features section, double click “Configuration Editor”
Under “Section” select: system.webServer then serverRuntime
Modify the “uploadReadAheadSize” section to be like 20MB (the value there is in Bytes)
Click Apply.

Why HttpResponse always return 404 status code

I am trying to send request to http://localhost/apptfg/get_biography_group?nombre_grupo=fondoflamenco which is a php based webservice that access to mysql database and retrieve information about the group but I always get a 404 not found when I execute the application in my windows phone 8 device, however when I debug the url in fiddler I get the right result which must be {"success":1,"group":[{"nombre_grupo":"fondoflamenco","anyo_creacion":"2006","descripcion":"Fondo Flamenco Flamenco is a group formed by three young Sevillian. Astola Alejandro Soto, Antonio Sanchez and Rafael Ruda M.R","musicos":"Rafael Ruda,Antonio Manuel Rios,"}]}
this is the HttpClient code I use in my application:
public async Task<string> makeHttpRequest(string group_name)
{
var resultstring = String.Empty;
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Accept", "text/html");
try
{
resultstring = await client.GetStringAsync(new Uri("http://localhost/apptfg/get_group_biography.php?nombre_grupo=" + group_name));
client.Dispose();
}
catch (Exception exp)
{
Console.WriteLine(exp.Message);
}
return resultstring;
}

HttpWebRequest/Response on localhost (WebException: operation timed out)

I need to inspect some HTTP headers and so I'm using C#'s HttpWebRequest and HttpWebResponse classes.
I'm developing using Visual Studio 2012 and would like to test out the request and response on my localhost so I can see what kind of headers I'm dealing with (I use devtools in Chrome so I can see there, but I want to make sure my code is returning the proper values). When I simply put in http://localhost:[Port]/ it doesn't connect.
I can see that it repeatedly is making a request to the server and eventually I get the exception WebException: The Operation has timed out. If I add request.KeepAlive = false' then I get the exception WebException: Unable to connect to the remote server.
So I'm wondering:
Is something wrong with my code? (see below)
How can I test HttpWebRequest and HttpWebResponse on localhost?
I've tried using the IP address in place of "localhost" but that didn't work (ex http://127.0.0.1:[port]/)
Code:
public class AuthorizationFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
string url = "http://127.0.0.1:7792/";
string responseString;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
//request.KeepAlive = false;
//request.AllowAutoRedirect = false;
System.Diagnostics.Debug.Write(request);
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
responseString = reader.ReadToEnd();
System.Diagnostics.Debug.Write(responseString);
}
}
}
catch (Exception e)
{
System.Diagnostics.Debug.Write(e.Message);
System.Diagnostics.Debug.Write(e.Source);
}
}
}
Have you tried Fiddler? Fiddler will show you all the HTTP Requests, all headers, response status, with different data views like raw, hex, image etc, a timeline view, HTTPS Connects, pretty much everything.
There are also Firefox extensions like httpfox. But I strongly recommend you try out Fiddler.

Categories

Resources