Is it possible to open a link in browser with HttpClient.GetAsync?
I got a report from a user of my app that the app opened a link in the browser which is only used in with HttpClient.GetAsync.
Some one else had the issue too: why HttpClient.GetAsync causes opening link in browser?
private JObject Get(string url)
{
JObject getResponse = new JObject();
getResponse["error"] = (int)Error.None;
getResponse["message"] = "";
try
{
using (HttpClient client = new HttpClient())
{
Task<HttpResponseMessage> res1 = client.GetAsync(url + GetRequestRandomizer());
HttpResponseMessage res = res1.WaitAndUnwrapException();
if (res.IsSuccessStatusCode && res.StatusCode == HttpStatusCode.OK)
{
var responseContent = res.Content;
getResponse["error"] = (int)Error.None;
getResponse["message"] = responseContent.ReadAsStringAsync().Result;
}
else
{
getResponse["error"] = (int)Error.RequestError;
getResponse["message"] = "";
}
}
}
catch (HttpRequestException exception)
{
getResponse["error"] = (int)Error.NetworkError;
getResponse["message"] = "";
}
return getResponse;
}
Related
I'm trying to manage the redirect on this site: https://uk.soccerway.com, so I wrote this code:
public static string GetHtml(string url)
{
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(url);
try
{
webReq.AllowAutoRedirect = false;
HttpWebResponse response = webReq.GetResponse() as HttpWebResponse;
WebClient client = new WebClient();
client.Encoding = System.Text.Encoding.UTF8;
url = (response.Headers["Location"] != null) ? response.Headers["Location"] : url;
return client.DownloadString(url);
}
catch (WebException)
{
throw;
}
}
this will return an Exception, in particular:
'The remote server returned an error: (302) Moved Temporarily.'
what I did wrong?
I can see this being a useful answer for many other users so reading this article helped me arrive with the code below. It recursively handles the redirects in case there are more than 1 redirects. Finally it returns the response:
public static HttpResponseMessage MakeRequest(string url)
{
using (var client = new HttpClient())
{
var request = new HttpRequestMessage()
{
RequestUri = new Uri(url),
Method = HttpMethod.Get
};
HttpResponseMessage response = client.SendAsync(request).Result;
var statusCode = (int)response.StatusCode;
// We want to handle redirects ourselves so that we can
// determine the final redirect Location (via header)
if (statusCode >= 300 && statusCode <= 399)
{
var redirectUri = response.Headers.Location;
if (!redirectUri.IsAbsoluteUri)
{
redirectUri = new Uri(request.RequestUri.
GetLeftPart(UriPartial.Authority) + redirectUri);
}
return MakeRequest(redirectUri.AbsoluteUri);
}
return response;
}
}
Usage
HttpResponseMessage response = MakeRequest("https://uk.soccerway.com");
if (response.IsSuccessStatusCode)
{
string content = response.Content.ReadAsStringAsync().Result;
}
I'm trying to make a POST request using HttpClient but it keeps throwing an ArgumentNullException.
on this call var response = await client.PostAsync(url, content);
I've set break points and verified that the values are populated.
Is there something I'm missing that would cause this?
public async Task<bool> PostSomeObject()
{
var transaction = new CreateTransactionRequest();
transaction.MerchantAuthentication.Name = "notmyName";
transaction.MerchantAuthentication.TransactionKey = "notMyKey";
transaction.TransactionRequest.TransactionType = "authOnlyTransaction";
transaction.TransactionRequest.Amount = 5;
transaction.TransactionRequest.Payment.CardCode = "999";
transaction.TransactionRequest.Payment.CardNumber = "5424000000000015";
transaction.TransactionRequest.Payment.ExpirationMonth = 12;
transaction.TransactionRequest.Payment.ExpirationYear = 20;
var url = "xml/v1/request.api";
using (HttpClient client = new HttpClient())
{
var sampleClassObjectJson = JsonConvert.SerializeObject(transaction);
client.BaseAddress = new Uri("http://localhost:56858/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var content = new StringContent(sampleClassObjectJson, Encoding.UTF8, "application/json");
//throws NullException on this call here
var response = await client.PostAsync(url, content);
if (response.StatusCode == HttpStatusCode.OK)
return true;
else
throw new WebException("An error has occurred while calling PostSomeObject method: " + response.Content);
}
}
Based on a comment I've added a try catch for the ArgumentNullException
try {
var response = await client.PostAsync(url, content);
}
catch (System.ArgumentNullException ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
It's not stepping into the catch statement but in the Output from debug it throws the exception.
Here is the controller action that calls my Post method
public async Task<IActionResult> PaymentInformation(Payment paymentInfo)
{
var cookie = GetCheckoutCookie();
//if there isn't a cookie ID something went wrong, redirect to Index
if (cookie.ID == null)
{
return RedirectToAction("Index");
}
var cookieSession = CheckoutSession.getCheckoutSession(cookie.ID);
if (ModelState.IsValid)
{
var status = await PostSomeObject();
}
else
{
}
return PartialView();
}
I wrote simple method for getting data from (online) REST Service:
public async Task<Object> GetTask()
{
try
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("http://111.111.111.111:8080/");
HttpResponseMessage result = await client.GetAsync("ABC/CDE/getsomeinfo");
if (result.IsSuccessStatusCode)
{
//Deserialize
}
}
}
catch (Exception ex)
{
Debug.WriteLine("Error" + ex);
}
return null;
}
Whenever i run this on UWP i'm getting catch exception:
The text associated with this error code could not be found.
A connection with the server could not be established
HResult 2147012867
Im trying to connect my client with restapi in internal network. In forms same code is working properly.
Try this
HttpResponseMessage response;
public async Task<string> webserviceResponse(string HttpMethod)
{
// check internet connection is available or not
if (NetworkInterface.GetIsNetworkAvailable() == true)
{
// CancellationTokenSource cts = new CancellationTokenSource(2000); // 2 seconds
HttpClient client = new HttpClient();
MultipartFormDataContent mfdc = new MultipartFormDataContent();
mfdc.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data");
string GenrateUrl = "your url";
if (HttpMethod == "POST")
{
response = await client.PostAsync(GenrateUrl, mfdc);
}
else if (HttpMethod == "PUT")
{
response = await client.PutAsync(GenrateUrl, mfdc);
}
else if (HttpMethod == "GET")
{
response = await client.GetAsync(GenrateUrl);
}
var respon = await response.Content.ReadAsStringAsync();
string convert_response = respon.ToString();
return convert_response;
}
else
{
return "0";
}
}
I m developing a Windows Phone 8.1 Application.
I'm newbie in C# and WP. I used restfull web services for sql server connection but i can't send data to server. I had an error message as "Bad Request".
This is my login page code bihend
KullaniciManager km = new KullaniciManager();
km.Login();
HttpClient httpClient = new System.Net.Http.HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "http://localhost:3577/KullaniciService.svc/Login");
HttpResponseMessage response = await httpClient.SendAsync(request);
MessageDialog msgbox = new MessageDialog("Serverdan gelecek hata mesajı");
await msgbox.ShowAsync();
My BLL code is here.
public LoginResponse KullaniciKontrolEt(string kulAdi, string sifre)
{
LoginResponse response = null;
using (NeydiolilacEntities noi = new NeydiolilacEntities())
{
object data = noi.ta_Kullanici.Where(x => x.Kul_Ad == kulAdi && x.Kul_Sifre == sifre && x.Kul_Statu == true).SingleOrDefault();
response = new LoginResponse()
{
Data = data
};
return response;
}
Thanks for your help :)
*
Hi Asim,
This will help you I hope
Note : Code for Win8.1
public async Task<string> GeneralRequestHandler(string RequestUrl, object ReqObj)
{
try
{
string json = Newtonsoft.Json.JsonConvert.SerializeObject(ReqObj);
HttpContent content = new StringContent(json);
Windows.Web.Http.IHttpContent c = new Windows.Web.Http.HttpStringContent(json);
c.Headers.ContentType = new Windows.Web.Http.Headers.HttpMediaTypeHeaderValue("application/json");
Windows.Web.Http.Filters.HttpBaseProtocolFilter aHBPF = new Windows.Web.Http.Filters.HttpBaseProtocolFilter();
aHBPF.IgnorableServerCertificateErrors.Add(Windows.Security.Cryptography.Certificates.ChainValidationResult.Untrusted);
aHBPF.IgnorableServerCertificateErrors.Add(Windows.Security.Cryptography.Certificates.ChainValidationResult.InvalidName);
string responseText;
using (var handler = new Windows.Web.Http.HttpClient(aHBPF))
{
Windows.Web.Http.HttpResponseMessage r = await handler.PostAsync(new Uri(RequestUrl), c);
responseText = await r.Content.ReadAsStringAsync();
}
}
catch (HttpRequestException ex)
{
}
return responseText;
}
*
I have used SO to help with several issues in the past. However, I cannot find a solution to something I have been struggling with for 2 days now.
I am a noob, please be kind :)
I have an app that I created using Xamarin Studio, targeted for Android. It is a basic GET request from a Rest Api. It was working perfectly until I realized I was not helping myself when it came time to create the same app in IOS and Windows. Once I changed my project to utilize a PCL I started getting errors, primarily around my RestClient class (originally got from http://www.codeproject.com/Tips/497123/How-to-make-REST-requests-with-Csharp)
From my droid app class:
var apiUser = GetString(Resource.String.apiUser);
var apiPass = GetString(Resource.String.apiPass);
//Get token from API
string token = authenticate(apiUser,apiPass);
public static string authenticate(string apiUser, string apiPass)
{
Authentication Auth = new Authentication ();
try
{
// set json by passing AuthenticationUrl as endpoint, returns json data
var o = JObject.Parse(EntryRepository.getJson(PJTApiUrls.getAuthenticationUrl(apiUser,apiPass)));
Auth.Token = (string)o["Token"];
return Auth.Token;
}
catch (Exception e)
{
// Couldn't do stuff. Log the exception.
// TODO possible timeout, try again, if fails again then return error message
if (e.Message.Contains("400") || e.Message.Contains("401"))
{
string error = string.Format("Invalid credentials, please try again");
return error;
} else {
string error = string.Format ("An error occurred: \r\n{0}", e.Message);
return error;
}
}
}
getAuthenticationUrl gets the api URL.
Here is getJson (in PCL):
public static string getJson(string endpoint)
{
string apiurl = endpoint;
var client = new _RestClient();
client.EndPoint = apiurl;
client.ContentType = "application/json";
client.Method = HttpVerb.GET;
//client.Method = HttpVerb.POST;
client.PostData = "";
//client.PostData = "{postData: value}";
//client.PostData = "{'someValueToPost': 'The Value being Posted'}";
var json = client._MakeRequestAsync();
// to append parameters, pass them into make request:
//var json = client.MakeRequest("?param=0");
return json.ToString();
}
And for the _RestClient class (in PCL):
public async Task<string> _MakeRequestAsync()
{
try {
var request = _MakeRequestAsync ("");
return await request;
}
catch (Exception e){
return e.Message;
}
}
public async Task<string> _MakeRequestAsync(string parameters)
{
var uri = new Uri(EndPoint + parameters);
var request = WebRequest.Create(uri) as HttpWebRequest;
using (var response = await request.GetResponseAsync () as HttpWebResponse) {
var responseValue = string.Empty;
if (response.StatusCode != HttpStatusCode.OK) {
var message = String.Format ("Request failed. Received HTTP {0}", response.StatusCode);
throw new Exception (message);
}
// grab the response
using (var responseStream = await Task.Factory.FromAsync<Stream>(request.BeginGetRequestStream, request.EndGetRequestStream, null)) {
//using (var responseStream = response.GetResponseStream ()) {
if (responseStream != null)
using (var reader = new StreamReader (responseStream)) {
responseValue = reader.ReadToEnd ();
}
}
return responseValue;
}
}
responseValue is returning null
return await request is saying "Status = Waiting for activation"
I have also had the error: "Unexpected character encountered while parsing value: S. Path '', line 0, position 0."
But this works if the RestClient class is within Droid (Instead of the shared PCL) and contains the following:
public string MakeRequest ()
{
return MakeRequest ("");
}
public string MakeRequest (string parameters)
{
var request = (HttpWebRequest)WebRequest.Create (EndPoint + parameters);
request.Method = Method.ToString ();
request.ContentLength = 0;
request.ContentType = ContentType;
if (!string.IsNullOrEmpty (PostData) && Method == HttpVerb.POST) {
var bytes = Encoding.GetEncoding ("iso-8859-1").GetBytes (PostData);
request.ContentLength = bytes.Length;
using (var writeStream = request.GetRequestStream ()) {
writeStream.Write (bytes, 0, bytes.Length);
}
}
using (var response = (HttpWebResponse)request.GetResponse ()) {
var responseValue = string.Empty;
if (response.StatusCode != HttpStatusCode.OK) {
var message = String.Format ("Request failed. Received HTTP {0}", response.StatusCode);
throw new ApplicationException (message);
}
// grab the response
using (var responseStream = response.GetResponseStream ()) {
if (responseStream != null)
using (var reader = new StreamReader (responseStream)) {
responseValue = reader.ReadToEnd ();
}
}
return responseValue;
}
}
I cannot figure this out, any help/guidance is appreciated. Let me know if I can clarify anything.
***** UPDATE ***** Thanks to #milen-pavlov help thus far, here is where I am currently at:
in Android project:
var apiUser = GetString(Resource.String.apiUser);
var apiPass = GetString(Resource.String.apiPass);
//Get token from API
var token = await authenticate(apiUser,apiPass);
lblOutput.Text = token;
calls (also in Android project):
public static async Task<string> authenticate(string apiUser, string apiPass)
{
Authentication Auth = new Authentication ();
try
{
// set json by passing AuthenticationUrl as endpoint, returns json data
var o = JObject.Parse(await EntryRepository.getJson(PJTApiUrls.getAuthenticationUrl(apiUser,apiPass)));
Auth.Token = (string)o["Token"];
return Auth.Token;
}
catch (Exception e)
{
if (e.Message.Contains("400") || e.Message.Contains("401"))
{
string error = string.Format("Invalid credentials, please try again");
return error;
} else {
string error = string.Format ("An error occurred: \r\n{0}", e.Message);
return error;
}
}
}
Calls json class in PCL project:
public static async Task<string> getJson(string endpoint)
{
string apiurl = endpoint;
var client = new _RestClient();
client.EndPoint = apiurl;
client.ContentType = "application/json";
client.Method = HttpVerb.GET;
client.PostData = "";
var json = await client._MakeRequestAsync();
return json;
}
which then calls restclient class in PCL project:
public async Task<string> _MakeRequestAsync()
{
var request = _MakeRequestAsync ("");
return await request;
}
public async Task<string> _MakeRequestAsync(string parameters)
{
var uri = new Uri(EndPoint + parameters);
using (var client = new HttpClient())
{
var response = await client.GetAsync(uri);
return await response.Content.ReadAsAsync<string>();
};
}
End result/error:
Any guidance is appreciated!
Can you use HttpClient instead?
Sample Get request will look similar to this:
public async Task<string> _MakeRequestAsync(string parameters)
{
var uri = new Uri(EndPoint + parameters);
using (var client = new HttpClient())
{
var response = await client.GetAsync(uri);
return await result.Content.ReadAsStringAsync();
};
}