Why python request working but C# request not working? - c#

First, i try to post the script in PostMan tool.
{"AO":"ECHO"}
It working fine. Then i'm writing this request in C# but it not working.
And more i wrote the request again in Python, and it working well.
But my project is in Microsoft C#. I dont want to run script Python in C# at all.
==== Python =========
import httplib
import json
import sys
data = '{"AO":"ECHO"}'
headers = {"Content-Type": "application/json", "Connection": "Keep-Alive" }
conn = httplib.HTTPConnection("http://10.10.10.1",1040)
conn.request("POST", "/guardian", data, headers)
response = conn.getresponse()
print response.status, response.reason
print response.msg
==== C# ============
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://10.10.10.1:1040/guardian");
httpWebRequest.Method = "POST";
httpWebRequest.ContentType = "application/json";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"AO\":\"ECHO\"}";
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
Console.WriteLine(result);
}
}
I try to put "ContentLength" but it still timeout exception.
And i try to using RestSharp, it's not timeout but return null.
Any one please help...
var client = new RestClient("http://10.10.10.1:1040/guardian");
var request = new RestRequest();
request.Method = Method.POST;
request.AddHeader("Content-Type", "application/json");
request.Parameters.Clear();
request.RequestFormat = DataFormat.Json;
request.AddBody(new { AO = "ECHO" });
var response = client.Execute(request);
var content = response.Content;
Please help me,
I dont understand why it working fine in python.
But why it not working in C#.
I try to find many request in C# but it got error exception with timeout.

Python will automatically add Content-Length http header.
https://docs.python.org/2/library/httplib.html#httpconnection-objects
I think you might have to set this header manually in C#.
httpWebRequest.ContentLength = json.length;
Depending on the server, you may have to set UserAgent as well.
httpWebRequest.UserAgent=".NET Framework Test Client";

Related

Unable to post to merchant API due to error saying I must provide a request body

I spent all day trying to figure out what I was doing wrong yesterday.
Coming here to try and find some help.
The follow error is triggered when I run the actual GetResponse.
I am new to APIs so I am sure I am missing something real simple.
You must provide a request body if you set ContentLength>0 or SendChunked==true. Do this by calling [Begin]GetRequestStream before [Begin]GetResponse.
Here is my code I am using to try and send JSON to the API. Payment object just has the form values entered in and the credentials to use the correct account on the merchants end.
var json = JsonConvert.SerializeObject(payment);
var apiUrl = new Uri($"Removed endpoint URL");
var postBytes = Encoding.UTF8.GetBytes(json);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var httpWebRequest = (HttpWebRequest)WebRequest.Create(apiUrl);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Accept = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.ContentLength = postBytes.Length;
httpWebRequest.AllowWriteStreamBuffering = false;
//This is where the error triggers and drops to the catch.
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
I appreciate any help in advance, I may be doing this completely wrong, its a series of things I threw together trying to fix issues with the call.
Unless I missed it, you're not actually writing your payload data to the HttpWebRequest body before you're sending it.
using (Stream _reqStrm = httpWebRequest.GetRequestStream())
{
_reqStrm.Write(postBytes, 0, postBytes.Length);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
....
Unrelated but if you can, consider HttpClient
Hth..

API call successfully from external client but not from c#

I need to call client API-HTTPS (GET) with some specific headers
Accept:application/json,application/vnd.error+json
Date:2018-10-03T06:52:48Z
Authorization:<SECRETKEY>
In this scenario when I try to call it from client like Postman or Advanced REST client, API give proper result. But the same thing I tried with C# code which generates 401-Unauthorized errorcode.
For example If I'm using postman code for RestSharp (C#). It won't work from my code.
Postman screenshot:
Even I tried the same with HttpWebRequest and HttpClient too. But no luck.
Code which postman provided from code section is as below with some confidential information which I can't expose.
var client = new RestClient("https://**CLIENT_API_PATH**");
var request = new RestRequest(Method.GET);
request.AddHeader("Postman-Token", "ef8c2a79-a501-4cef-aa2e-bacdc9d3a922");
request.AddHeader("Cache-Control", "no-cache");
request.AddHeader("Authorization", "**SECRET_KEY**");
request.AddHeader("Date", "2018-10-03T06:52:48Z");
request.AddHeader("Accept", "application/json,application/vnd.error+json");
IRestResponse response = client.Execute(request);
In above code 3 parameters are compulsory and have to pass for successful call to API.
Date with the above mentioned format only.
Accept with above mentioned string only.
Authorization with specific authentication (custom by client).
As per suggested comment I also add fiddler data from the call.
Postman request fetch from fiddler
fiddler screenshot
C# api call code request from fiddler
fiddler screenshot
C# code debug result
visual studio debug screenshot
Try this.
public static string Get(Uri uri, string token)
{
string responseString = string.Empty;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Method = "GET";
request.ContentType = "application/json;charset=utf-8";
request.Headers.Add("Authorization", string.Format("Bearer {0}", token));
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
StreamReader responseReader = new StreamReader(responseStream);
responseString = responseReader.ReadToEnd();
}
}
return responseString;
}

Get Request in C# Returning 401 Not Authorised

Currently trying to do a Get request as part of a c# program. The request works fine on Postman as it uses a header for authorization. However I cannot get the code working for the program to use this header correctly in its Get request. I've had a good look around and tried various bits of code I've found but haven't managed to resolve it so any help would be appreciated!
public string Connect()
{
using (WebClient wc = new WebClient())
{
string URI = "myURL.com";
wc.Headers.Add("Content-Type", "text");
wc.Headers[HttpRequestHeader.Authorization] = "Bearer OEMwNjI2ODQtMTc3OC00RkIxLTgyN0YtNzEzRkE5NzY3RTc3";//this is the entry code/key
string HtmlResult = wc.DownloadString(URI);
return HtmlResult;
}
}
Above is one method inside the class.
Below is another attempt which is an extension method that gets passed the URL:
public static string GetXml(this string destinationUrl)
{
HttpWebRequest request =
(HttpWebRequest)WebRequest.Create(destinationUrl);
request.Method = "GET";
request.Headers[HttpRequestHeader.Authorization] = "Bearer
OEMwNjI2ODQtMTc3OC00RkIxLTgyN0YtNzEzRkE5NzY3RTc3";
HttpWebResponse response;
response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
Stream responseStream = response.GetResponseStream();
string responseStr = new
StreamReader(responseStream).ReadToEnd();
return responseStr;
}
else
{
Console.Write(String.Format("{0}({1})",
response.StatusDescription, response.StatusCode));
}
return null;
}
Might I recommend the very handy RestSharp package (find it on Nuget).
It turns your current code into something like
public string Connect()
{
var client = new RestClient();
var request = new RestRequest("myURL.com", Method.GET);
request.AddParameter("Authorization", "Bearer OEMwNjI2ODQtMTc3OC00RkIxLTgyN0YtNzEzRkE5NzY3RTc3");
var response = client.Execute(request);
return response.Content;
}
It's much more succinct and easier to use (in my opinion) and thus lessens the likelihood of passing in or using incorrect methods.
If you're still having issues getting data back/connecting. Then using PostMan click Code in the upper right of PostMan and select the C# (RestSharp) option. Whatever is generated there matches exactly what PostMan is sending. Copy that over and you should get data back that matches your PostMan request.

Request throwing An existing connection was forcibly closed by the remote host only on C# request

I'm having a hard time trying to consume a REST service from Cielo (credit/debit card gateway company). If I use postman it works:
POST /1/sales/ HTTP/1.1
Host: apisandbox.cieloecommerce.cielo.com.br
MerchantKey: my_key
Content-Type: application/json
MerchantId: merc_id
Cache-Control: no-cache
Postman-Token: 6643cc5a-173a-f5db-8924-85ea8b7bbb55
{"MerchantId":"00000000-0000-0000-0000-000000000000","MerchantKey":null,"RequestId":"00000000-0000-0000-0000-000000000000","MerchantOrderId":"1223","Customer":{"Name":"Emerson Fitchy"},"Payment":{"PaymentId":"00000000-0000-0000-0000-000000000000","Type":"CreditCard","Amount":15700,"Installments":1,"Provider":null,"ProofOfSale":null,"Tid":null,"AuthorizationCode":null,"SoftDescriptor":null,"ECI":null,"Status":0,"ReturnCode":null,"ReturnMessage":null,"CreditCard":{"CardNumber":"0000000000000001","Holder":"Emerson Fitchy Santis","ExpirationDate":"12/2022","SecurityCode":"154","Brand":"Visa"}}}
And this is the C# code (at the moment, I tried also with RestSharp and HttpClient with the same results):
var webrequest = (HttpWebRequest)WebRequest.Create(Constants.Cielo.GetSalesUrl());
webrequest.ContentType = "application/json";
webrequest.Method = "POST";
webrequest.Headers.Add("MerchantId", Constants.Cielo.Sandbox.MerchantId.ToString());
webrequest.Headers.Add("MerchantKey", Constants.Cielo.Sandbox.MerchantKey);
using (var streamWriter = new StreamWriter(webrequest.GetRequestStream()))
{
var json = JsonConvert.SerializeObject(sale);
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)webrequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
var x = result;
}
Any ideas on what am I doing wrong? I tried using Fiddler 4 but it's not picking up this request (I don't know why) and WireShark picks it up, but doesn't show the information the way Fiddler does (Maybe it's because I'm using https?).
Any ideas?
Thanks!
EDIT
Response/Exception
I just had the same issue where I suddenly was unable to make calls to a specific website from a Windows Server where I was running a console application on .NET 4.7.2. I was able to make the call in Postman from the same machine, but started getting the An existing connection was forcibly closed by the remote host.
It turns out that the sever had TLS 1.2 disabled. I was able to resolve it following the steps in this answer. I still am not sure if this setting was changed on the server or if the website started enforcing it, but it resolved the issue for me.
Try this client and see if it you get a different result:
var client = new HttpClient();
using (HttpRequestMessage request = new HttpRequestMessage())
{
request.Method = HttpMethod.Post;
request.RequestUri = new Uri(Constants.Cielo.GetSalesUrl(), UriKind.Absolute);
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var requestContent = JsonConvert.SerializeObject(sale);
request.Content = new StringContent(requestContent, Encoding.UTF8, "application/json");
request.Headers.Add("MerchantId", Constants.Cielo.Sandbox.MerchantId.ToString());
request.Headers.Add("MerchantKey", Constants.Cielo.Sandbox.MerchantKey);
using (HttpResponseMessage response = await client.SendAsync(request))
{
if (response.IsSuccessStatusCode)
{
if (response.Content != null)
{
var rawJson = await response.Content.ReadAsStringAsync();
// do stuff - map to type, etc.
}
}
return something;
}
}

WebRequest to connect to the Wikipedia API

This may be a pathetically simple problem, but I cannot seem to format the post webrequest/response to get data from the Wikipedia API. I have posted my code below if anyone can help me see my problem.
string pgTitle = txtPageTitle.Text;
Uri address = new Uri("http://en.wikipedia.org/w/api.php");
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
string action = "query";
string query = pgTitle;
StringBuilder data = new StringBuilder();
data.Append("action=" + HttpUtility.UrlEncode(action));
data.Append("&query=" + HttpUtility.UrlEncode(query));
byte[] byteData = UTF8Encoding.UTF8.GetBytes(data.ToString());
request.ContentLength = byteData.Length;
using (Stream postStream = request.GetRequestStream())
{
postStream.Write(byteData, 0, byteData.Length);
}
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
// Get the response stream.
StreamReader reader = new StreamReader(response.GetResponseStream());
divWikiData.InnerText = reader.ReadToEnd();
}
You might want to try a GET request first because it's a little simpler (you will only need to POST for wikipedia login). For example, try to simulate this request:
http://en.wikipedia.org/w/api.php?action=query&prop=images&titles=Main%20Page
Here's the code:
HttpWebRequest myRequest =
(HttpWebRequest)WebRequest.Create("http://en.wikipedia.org/w/api.php?action=query&prop=images&titles=Main%20Page");
using (HttpWebResponse response = (HttpWebResponse)myRequest.GetResponse())
{
string ResponseText;
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
ResponseText = reader.ReadToEnd();
}
}
Edit: The other problem he was experiencing on the POST request was, The exception is : The remote server returned an error: (417) Expectation failed. It can be solved by setting:
System.Net.ServicePointManager.Expect100Continue = false;
(This is from: HTTP POST Returns Error: 417 "Expectation Failed.")
I'm currently in the final stages of implementing an C# MediaWiki API which allows the easy scripting of most MediaWiki viewing and editing actions.
The main API is here: http://o2platform.googlecode.com/svn/trunk/O2%20-%20All%20Active%20Projects/O2_XRules_Database/_Rules/APIs/OwaspAPI.cs and here is an example of the API in use:
var wiki = new O2MediaWikiAPI("http://www.o2platform.com/api.php");
wiki.login(userName, password);
var page = "Test"; // "Main_Page";
wiki.editPage(page,"Test content2");
var rawWikiText = wiki.raw(page);
var htmlText = wiki.html(page);
return rawWikiText.line().line() + htmlText;
You seem to be pushing the input data on HTTP POST, but it seems you should use HTTP GET.
From the MediaWiki API docs:
The API takes its input through
parameters in the query string. Every
module (and every action=query
submodule) has its own set of
parameters, which is listed in the
documentation and in action=help, and
can be retrieved through
action=paraminfo.
http://www.mediawiki.org/wiki/API:Data_formats

Categories