Send Parameter HttpWebRequest return XML - c#

Good morning,
I am trying to connect to a payment gateway which sends you a post parameters using HttpWebRequest.
The code that has done in the api is php but I need in C#.
function send_trans($url, $postData) {
$headers = array( 'Connection: Keep-Alive',
'Content-Type: application/x-www-form-urlencoded');
$ch = curl_init($url);
curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko
/20080311 Firefox/2.0.0.13');
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($ch, CURLOPT_TIMEOUT, 40); // timeout en 40 segundos
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$xml = curl_exec($ch);
curl_close($ch);
return ($xml);
}
have tried it with the following code.
  
 
public static string HttpPostRequest (string url, Dictionary <string, string> postParameters)
        {
            string postData = "";
            foreach (string key in postParameters.Keys)
            {
                postData + = key + "=" + postParameters [key] + "&";
            }
            HttpWebRequest myHttpWebRequest = (HttpWebRequest) HttpWebRequest.Create (url);
            myHttpWebRequest.Method = "POST";
            byte [] data = Encoding.ASCII.GetBytes (postData);
            myHttpWebRequest.ContentType = "application / x-www-form-urlencoded";
            myHttpWebRequest.ContentLength = data.Length;
            Stream requestStream = myHttpWebRequest.GetRequestStream ();
            requestStream.Write (data, 0, data.Length);
            requestStream.Close ();
            HttpWebResponse myHttpWebResponse = (HttpWebResponse) myHttpWebRequest.GetResponse ();
            Stream responseStream = myHttpWebResponse.GetResponseStream ();
            StreamReader myStreamReader = new StreamReader (responseStream, Encoding.Default);
            string pageContent = myStreamReader.ReadToEnd ();
            myStreamReader.Close ();
            responseStream.Close ();
            myHttpWebResponse.Close ();
            return pageContent;
        }
the error it gives me is in the line of Stream responseStream = myHttpWebResponse.GetResponseStream (), I have tried with other code and it is always the same error in GetResponseStream.

Related

How to POST request for authorization token from filemaker API in c#

I am hitting a POST request to a FileMaker API to get an authorization token but its throwing web exception. How can I fix it?
I have tried it in java. Now I am trying it in c# .NET framework 4.6.1
private static void GetToken(string username, string password)
{
try
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://exchange.furniflair.com/fmi/data/v1/databases/FurniflairDB/sessions");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
var bytes = Encoding.UTF8.GetBytes("dataapi:Data4me");
string temp = Convert.ToBase64String(bytes);
httpWebRequest.Headers.Add("Authorization", "Basic ZGF0YWFwaTpEYXRhNG1l");
string token;
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
token = streamReader.ReadToEnd();
}
}
catch (WebException ex){}
}
I expect the output to be the authorization token in response, but I am getting only exceptions like httpWebException.
If it helps you set the headers correctly, here is an example that works using PHP.
$Post_Json = '{}';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$URL);
curl_setopt($ch, CURLOPT_PORT,443);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_TIMEOUT, 30); //timeout after 30 seconds
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $Post_Json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
$result=curl_exec ($ch);
This comes from: https://schwarzsoftware.com.au/blogentry.php?id=19
Also ensure that the Data API is turned on in the FileMaker Admin server console, and enabled for the FileMaker file you are trying to access, and access priviliges enabled for that user in the FileMaker file.

Https Post with .crt and .key

I am sorry if it is duplicate. I see a couple of post over the internet about this topic. But do not get any appropriate solution. I am working at nopcommerce 4.0, which is run on the .net core but the targeted framework is 4.x.x. I am developing a payment plugin which needs secure connection with .crt and .key files. The payment method provider sends a php file which is working as expected. Below is the sample code
function ProcessRequest($curl_post_data,$service_url,$proxy,$proxyauth)
{
$output = '';
$certfile = '/createorder.crt';
$keyfile = '/createorder.key';
$cert_password = '';
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $service_url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt( $ch, CURLOPT_SSLCERT, getcwd() . $certfile );
curl_setopt( $ch, CURLOPT_SSLKEY, getcwd() . $keyfile );
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curl_post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$output = curl_exec($ch);
if (curl_error($ch)) {
echo $error_msg = curl_error($ch);
}
$cblcz = json_decode($output, true );
return $cblcz;
}
$proxy ="";
$proxyauth ="";
$postDatatoken = '{
"password": "123456Aa",
"userName": "test"
}';
$serviceUrltoken ="";
$serviceUrltoken= 'https://sandbox.thecitybank.com:7788/transaction/token';
$cblcz = ProcessRequest($postDatatoken,$serviceUrltoken,$proxy,$proxyauth);
I can not convert this curl to http post. I tried below link
PHP/Curl-SSL operations alternative in C# and others but do not get any work around.
Do not work. For openssl it is throwing dependency are not loaded. Here is my c# code
try
{
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
| SecurityProtocolType.Tls11
| SecurityProtocolType.Tls12
| SecurityProtocolType.Ssl3;
var certPath = Path.Combine(CommonHelper.MapPath("~/Plugins/Payments.CityBankApi/"), "createorder.crt");
var keyPath = Path.Combine(CommonHelper.MapPath("~/Plugins/Payments.CityBankApi/"), "createorder.key");
string certificateText = File.ReadAllText(certPath);
string privateKeyText = File.ReadAllText(keyPath);
ICertificateProvider provider = new CertificateFromFileProvider(certificateText, privateKeyText);
//X509Certificate certificate = provider.Certificate;
string accessTokenUrl = "https://sandbox.thecitybank.com:7788/transaction/token";
var requestUrl = new Uri(accessTokenUrl);
var request = (HttpWebRequest)WebRequest.Create(accessTokenUrl);
request.ContentType = "application/json";
request.Method = "POST";
request.ClientCertificates.Add(provider.Certificate);
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
string json = "{\"userName\":\"test\"," +
"\"password\":\"123456Aa\"}";
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
}
catch (Exception ex)
{
throw ex;
}
Your code seems correct. But make sure you have valid certificate. If the certification is not correct it will through an exception. Check your exception message and try to detect exact error. OR post your error message here.
moreover you should add
request.ServerCertificateValidationCallback = (e,r,c,n) => true;

Converting PHP CURL query to C#'s HttpWebRequest

I'm using HttpWebRequest in C# to do a POST to a particular API. The problem is that the system on the other end does not receive the body of the request. More so, when trying to send the request via tools like Postman, I have the same issue. The only thing that seems to work is a PHP implementation, detailed below.
My best guess is that I'm missing some header or another that the PHP sets automatically.
Has anybody encountered a similar problem/does anyone have a clue what I'm missing?
Both implementations below.
<?php
error_reporting(E_ALL);
$url = <<the APIs url>>
$hash = base64_encode('<<username>>:<password>>');
$data = [];
$username = <<username>>
$password =<password>>
$data = array(array(
"id" => "9999999",
"status" => 1,
<<rest of the formated data>>
));
$requestData = array(
'data' => $data,
'hash' => $hash
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($requestData));
$result = curl_exec($ch);
// $result = json_decode($result, true);
curl_close($ch);
die('done :'.$result);
?>
And here the C# implementation:
var httpWebRequest = (HttpWebRequest)WebRequest.Create(this.api_url);
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
httpWebRequest.Method = "POST";
httpWebRequest.KeepAlive = true;
httpWebRequest.Date = DateTime.Now.Date;
httpWebRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
httpWebRequest.Headers.Add("Authorization", "Basic " + Base64Encode(userName + ":" + password));
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
tring requestResult = null;
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
requestResult= streamReader.ReadToEnd();
}
If you are posting JSON data, you should set the content type to application/json.

How to achive this code in c# to post Xml

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://abc.com/");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $theXML);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$response = curl_exec ($ch);
curl_close ($ch);
How i can acheive this in c# to post xml requrest?
You will have to create object, uri is your url and than post it.
xmldata is your xml file
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
byte[] postDataBytes = Encoding.ASCII.GetBytes(xmldata);
req.Method = "POST";
req.ContentLength = postDataBytes.Length;
Stream requestStream = req.GetRequestStream();
requestStream.Write(postDataBytes, 0, postDataBytes.Length);
requestStream.Close();

Https POST from Php to C#

I have to make a post to a third party https url to get data procesed and sent back. And all I have as an example is this:
$signature= foo_string;
$data_to_post = json_dictionary;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $base_url);
curl_setopt($ch, CURLOPT_USERPWD, "$user:$password");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER,array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_HTTPHEADER,array("JSON-Signature: $signature"));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_to_post);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
curl_close($ch);
As we work with ASP .NET C# 2.0, I have to port this, but I get always a not autenticated error.
Here is what I'm doing:
HttpWebRequest q = (HttpWebRequest)WebRequest.Create(Host + ":" + Port);
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(new interhanse().AcceptAllCertifications);
q.Method = "POST";
q.Headers.Add("JSON-Signature:" + GetSignature(data));
q.ContentType = "application/json";
q.UseDefaultCredentials = false;
q.Credentials = new NetworkCredential(user,pwd, Host);
byte[] buffer = UTF8Encoding.UTF8.GetBytes(data);
q.ContentLength = data.Length;
Stream oStream = q.GetRequestStream();
StreamWriter oWriter = new StreamWriter(oStream);
oWriter.Write(buffer);
oWriter.Close();
HttpWebResponse reps = q.GetResponse() as HttpWebResponse;
I've read all SO questions I can find about this, but I don't get any improvements. Thanks in advance!
Well, one thing you're doing wrong is assuming that the length in bytes is the same as the length in characters. You should use buffer.Length for the content length. You're also calling StreamWriter.Write with a byte array. You shouldn't do that - you should just use the stream, as you've already done the encoding:
byte[] buffer = Encoding.UTF8.GetBytes(data);
q.ContentLength = buffer.Length;
using (Stream stream = q.GetRequestStream())
{
stream.Write(buffer, 0, buffer.Length);
}
Now, that won't solve the authentication issue. You may find that just setting PreAuthenticate solves that though:
q.PreAuthenticate = true;
If that doesn't work, I suggest you run WireShark and look at the differences between the request through Curl and the request from .NET.
I think you should not supply the host in the authentication...
q.Credentials = new NetworkCredential(user,pwd);
Which would be something like:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Host + ":" + Port);
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(new interhanse().AcceptAllCertifications);
request.Method = "POST";
request.Headers.Add("JSON-Signature:" + GetSignature(data));
request.ContentType = "application/json";
request.UseDefaultCredentials = false;
request.Credentials = new NetworkCredential(user, pwd);
byte[] buffer = UTF8Encoding.UTF8.GetBytes(data);
request.ContentLength = buffer.Length;
using (Stream oStream = request.GetRequestStream()) {
oStream.Write(buffer, 0, buffer.Length);
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
// load data from response here
}
Also you should avoid assigning the service point validation delegate on each request, this may slow down the requests increasingly because the validation is performed multiple times, and it's also kind of a memory leak.
curl_setopt($ch, CURLOPT_USERPWD, "$user:$password");
Here is how you add that CURLOPT_USERPWD in Asp.Net:
private async Task<string> Execute(string url, string query, string user, string pasword)
{
HttpClient httpClient = new HttpClient();
var baseUri = new Uri(url, UriKind.Absolute); // e.g. http://somedomain.com/endpoint
Uri request = new Uri(baseUri, query); // with query e.g. http://somedomain.com/endpoint?arg1=xyz&arg2=abc
// Add a new Request Message
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, request);
// add headers -> CURLOPT_USERPWD equivalent
var encodedStr = Convert.ToBase64String(Encoding.Default.GetBytes(string.Format("{0}:{1}", user, password)));
var authorizationKey = "Basic" + " " + encodedStr; // Note: Basic case sensitive
requestMessage.Headers.Add("Authorization", authorizationKey);
// if POST - do this instead
// content
//HttpContent content = new StringContent(jsonContent); // string jsonContent i.e. JsonConvert.SerializeObject(YourObject);
//requestMessage.Content = content;
//requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
// execute
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
var responseString = await responseMessage.Content.ReadAsStringAsync(); // reads it as string;
// if json and you need to convert to an object do this
// var myresponse = JsonConvert.DeserializeObject<YourMappedObject>(responseString);
return responseString;
}

Categories

Resources