HttpRequestException StatusCode in Xamarin - xamarin

The StatusCode property has been added to HttpRequestException in .NET 5. Is there any way to use this in Xamarin today?

The following example compares the status returned by an HttpWebResponse with a member of the HttpStatusCode class to determine the status of a response.
HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create("http://www.contoso.com");
httpReq.AllowAutoRedirect = false;
HttpWebResponse httpRes = (HttpWebResponse)httpReq.GetResponse();
if (httpRes.StatusCode==HttpStatusCode.Moved)
{
// Code for moved resources goes here.
}
// Close the response.
httpRes.Close();

Related

What is the callback URL after calling repeat.vsp when using Form Integration?

I'm trying to do repeat payments with Form Integration in Sagepay (now Opayo).
From an earlier problem posted on here, I get that the securitykey is needed but is not returned in the Form call, so an additional call needs to be made to the getTransactionDetails command.
I have the securitykey and can now make a call to https://test.sagepay.com/gateway/service/repeat.vsp to initiate the repeat payment. However, the documentation does not say where the response to that call goes. I assume therefore, that it would go to the NotificationURL that is set up with a payment when using the Server or Direct integrations. Since I'm using Form, this is not set.
The question is, is there any way of capturing the response to the https://test.sagepay.com/gateway/service/repeat.vsp call if the initial payment was created using Form integration?
I suppose the second question is, has anybody successfully made repeat payments work with Sagepay Form integration?
Not sure if this helps you and we didn't do repeat payments; but we are looking at releasing deferred payments and I think it is a similar approach.
How do you make the call to 'https://test.sagepay.com/gateway/service/repeat.vsp'?
Could you use a 'HttpWebRequest' to make the call then capture the direct response in 'HttpWebResponse'?
EG:
private static void DeferredSharedApiCall(Dictionary<string, string> data, string type, string url)
{
string postData = string.Join("&", data.Select(x => $"{x.Key}={HttpUtility.UrlEncode(x.Value)}"));
HttpWebRequest request = WebRequest.CreateHttp(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
using (TextWriter tw = new StreamWriter(request.GetRequestStream()))
{
tw.Write(postData);
}
HttpWebResponse response = null;
try
{
response = request.GetResponse() as HttpWebResponse;
}
catch (WebException ex)
{
//log.Error($"{type} Error, data: {postData}", ex);
}
catch (Exception ex)
{
//log.Error($"{type} Error, data: {postData}", ex);
}
if (response != null)
{
using (TextReader tr = new StreamReader(response.GetResponseStream()))
{
string result = tr.ReadToEnd();
//log.Info($"{type} Response: {Environment.NewLine}{result}");
}
}
}

My ASP.NET REST app is returning JSON even though the client is requesting XML

I have an ASP.NET Web API2 web application. For its configuration it has:
GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;
The client is requesting XML:
private static HttpWebRequest CreatetRequest(Uri uri, string method, int timeout)
{
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = method;
request.Timeout = timeout == 0 ? System.Threading.Timeout.Infinite : timeout;
request.Accept = "application/xml";
request.ContentType = "application/xml";
return request;
}
But what is being returned is JSON. And when the client then makes the following call:
using (var stream = response.GetResponseStream())
{
body = XDocument.Load(XmlReader.Create(stream));
It throws an exception because it can't load JSON as XML. What do I need to do on the server side to fix this (I can't change the client side - that code is out and in use)?
Found it - one of the objects being returned dd not have a parameterless constructor. XML serialization requires that while JSON does not.

Windows Phone sends more than one web requests in order in a call

Reccently, I am working on a project in Windows Phone. and In this project, to validate a user, I need to check at 3 web API, the logic is like below:
Step 1: access web api 1 to get the token
Step 2: access web api 2 to get the username/password by the token retrieved in Step 1
Step 3: access web API 3 to validate the user name/password in step 2
you can see we need to access those 3 API in order. as well know, window phone now access the network asynchronously, which causes a big challenge on make those API access in order, and which make the soure code hard to maintainace.
I also consider the synchronous source code like below, but I found there are some problems to access the network,many exeption will be thrown. For example, when an exception is thrown, I try to use asynchronous web request to access the same URL, it is OK. I am strugglig in it now. And I have to introduce thread to call it to avoid to block the UI thread.
internal static class HttpWebRequestExtensions
{
public const int DefaultRequestTimeout = 60000;
public static bool IsHttpExceptionFound = false;
public static WebResponse GetResponse(this WebRequest request, int nTimeOut = DefaultRequestTimeout)
{
var dataReady = new AutoResetEvent(false);
HttpWebResponse response = null;
var callback = new AsyncCallback(delegate(IAsyncResult asynchronousResult)
{
try
{
response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
dataReady.Set();
}
catch(Exception e)
{
IsHttpExceptionFound = true;
}
});
request.BeginGetResponse(callback, request);
if (dataReady.WaitOne(nTimeOut))
{
return response;
}
return null;
}
public static WebResponse PostRequest(this HttpWebRequest request, String postData, int nTimeOut = DefaultRequestTimeout)
{
var dataReady = new AutoResetEvent(false);
HttpWebResponse response = null;
var callback = new AsyncCallback(delegate(IAsyncResult asynchronousResult)
{
Stream postStream = request.EndGetRequestStream(asynchronousResult); //End the operation.
byte[] byteArray = Encoding.UTF8.GetBytes(postData); //Convert the string into a byte array.
postStream.Write(byteArray, 0, postData.Length); //Write to the request stream.
postStream.Close();
dataReady.Set();
});
request.BeginGetRequestStream(callback, request);
if (dataReady.WaitOne(nTimeOut))
{
response = (HttpWebResponse)request.GetResponse(nTimeOut);
if (IsHttpExceptionFound)
{
throw new HttpResponseException("Failed to get http response");
}
return response;
}
return null;
}
}
Any suggestion on using asynchronous web request to solve my case?
There's an example here of using asynchronous web services in a chained manner to call the Microsoft Translator service on WP7
Maybe it will give you some pointers?
http://blogs.msdn.com/b/translation/p/wp7translate.aspx

Windows Phone 7.5 handle webrequest redirect

Today i found very strange behavior in WP7.5/7.8
I am implementing authentification, i have to make post request, after that i will be redirected to result page.
In WP8 i am getting result page, after redirect. In WP7.5/7.8 - i am getting redirect result (StatusCode - 302).
public void MakeRequest() {
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(Consts.Url);
request.AllowAutoRedirect = true;
request.Method = "POST";
request.Headers[HttpRequestHeader.Cookie] = cookie;
request.BeginGetResponse(new AsyncCallback(ProcessRequest), request);
}
Process response
private void ProcessRequest(IAsyncResult callbackResult) {
HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState;
using (HttpWebResponse myResponse = (HttpWebResponse)myRequest.EndGetResponse(callbackResult)) {
if (myResponse.StatusCode != HttpStatusCode.OK) {
RaiseConnectionError(string.Format("Response from server {0}\n{1}", myResponse.StatusCode, myResponse.StatusDescription));
return;
}
}
}
This situation i noticed in backed in current project. When i created the same situation on my backed using ASP.NET MVC,
[HttpPost]
public ActionResult Redirect() {
return RedirectToAction("Index");
}
// index returns simple view
it worked for both WP7.5 & 8. It's strange, because backend works fine for iOS and Android.
I saw similar questions, where guys recommends to use custom UserAgent (like normal browser), but it did not work for me.

SOAP Parsing in windows phone 7

I will searching since 10 days but i have not succeed in soap parsing in wp7.
My code is below. I get the The remote server returned an error: NotFound. and System.Net.WebException.
code is below :
private const string AuthServiceUri = "http://manarws.org/WS/manarService.asmx";
private const string AuthEnvelope =
#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<fnGetNewsResponse xmlns=""http://tempuri.org/"">
<fnGetNewsResult></fnGetNewsResult>
</fnGetNewsResponse>
</soap:Body>
</soap:Envelope>";
public void Authenticate()
{
HttpWebRequest spAuthReq = HttpWebRequest.Create(AuthServiceUri) as HttpWebRequest;
spAuthReq.Headers["SOAPAction"] = "http://tempuri.org/fnGetNews";
spAuthReq.ContentType = "text/xml; charset=utf-8";
spAuthReq.Method = "POST";
spAuthReq.BeginGetRequestStream(new AsyncCallback(spAuthReqCallBack), spAuthReq);
}
private void spAuthReqCallBack(IAsyncResult asyncResult)
{
UTF8Encoding encoding = new UTF8Encoding();
HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
System.Diagnostics.Debug.WriteLine("REquest is :" + request.Headers);
Stream _body = request.EndGetRequestStream(asyncResult);
string envelope = string.Format(AuthEnvelope,"","");
System.Diagnostics.Debug.WriteLine("Envelope is :" + envelope);
byte[] formBytes = encoding.GetBytes(envelope);
_body.Write(formBytes, 0, formBytes.Length);
_body.Close();
request.BeginGetResponse(new AsyncCallback(ResponseCallback), request);
}
private void ResponseCallback(IAsyncResult asyncResult)
{
System.Diagnostics.Debug.WriteLine("Async Result is :" + asyncResult);
HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
System.Diagnostics.Debug.WriteLine("Response is :::::::::::::::::::----" + request.EndGetResponse(asyncResult));
if (request != null && response != null)
{
if (response.StatusCode == HttpStatusCode.OK)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
string responseString = reader.ReadToEnd();
}
}
}
I get the error in HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult); line...
So, Please help me.
Thanks.
Maybe I am missing something but why not just adding a service reference ?
The service located at 'http://manarws.org/WS/manarService.asmx' is a classic web service and you can browse wsdl. You can add a reference in Visual Studio. It will generate a proxy class to call this webservice. Manual soap parsing is quite painful.
EDIT :
1) Right clic on service reference in your project.
2) Enter your service url. Then click Go.
3) You will have new classes in your project.
Just use them as you want. Exemple :
public void GetBranches()
{
ManarServiceReference.manarServiceSoapClient client = new ManarServiceReference.manarServiceSoapClient();
client.fnGetBranchesCompleted += new EventHandler<ManarServiceReference.fnGetBranchesCompletedEventArgs>(client_fnGetBranchesCompleted);
client.fnGetBranchesAsync();
}
void client_fnGetBranchesCompleted(object sender, ManarServiceReference.fnGetBranchesCompletedEventArgs e)
{
//TODO
}
Follow these steps to know how to use a SOAP service
-- Create a new project.
-- Right-click on the Project name and click on "Add Service Reference"...
Then provide address as "http://manarws.org/WS/manarService.asmx?wsdl" and click Go.
-- Once service information is downloaded, provide Namespace something like
"MyMemberService" at the bottom and click Ok.
Now that your proxy classes should be ready.
Go to your Mainpage.xaml.cs and type 'client' there..you should probably get a class with the name "ManarServiceClient".
If you get that, then try to call the suitable methods of that class.
For an example,
ManarServiceClient client = new ManarServiceClient();
client.fnGetNewsResponseCompleted += new EventHandler<fnGetNewsResponseCompletedEventArgs>(client_fnGetNewsResponseCompleted);
client.fnGetNewsResponseAsync();
Note: I am not with my working system, so cannot give you exact code. All the above is a guessed code and shall point you in the right direction. Will test my code and update soon.
If you create of an asmx web service. The first call is incredibly slow.

Resources