C# equivalent of requests.post() function - python-requests

I'm converting some python scripts to its C# equivalent. When I run the following script (using requests module), the sever is happy and there is no issue with it:
auth_header = {'Authorization': 'Bearer ' + access_token}
r = requests.post(api_url + '/v1/instances', headers=auth_header, json =params)
However, when I run the following C# equivalent code, the server returns "405 METHOD NOT ALLOWED":
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(api_url);
client.DefaultRequestHeaders.Authorization = new
System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", access_token);
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue(#"application/json"));
string jsonDumps = JsonConvert.SerializeObject(parameters);
var content = new StringContent(jsonDumps, Encoding.UTF8,#"application/json");
var postResult = client.PostAsync(#"v1/pipelines", content).Result; // ERROR:
//StatusCode: 405, ReasonPhrase: 'METHOD NOT ALLOWED'.
It is notable that there is no issue when I run the GET method:
var response = client.GetAsync(#"v1/pipelines").Result;
I do not have access to the sever code. I tried to use Fiddler (similar to wire shark) to see what the python code is sending to the server but using Fiddler causes the python script failed to work properly stating that SSLError: CERTIFICATE_VERIFY_FAILED].

At a quick glance, the C# code looks correct. However, I think you're posting to two different endpoints: Python to /v1/instances and C# to /v1/pipelines. Try swapping them and seeing what happens.

Related

how to change dotnet core outgoing http request hostname from the default localhost

I am able to successfully send requests to a sandbox via postman, given by a provider following their specs (see images below)
Successful request (see below)
In order to do that, aside from the respective headers and parameters (see image 2) I have to add a ssl/Tls certificate (.pfx) given that the server requires a 2 way handshake so it needs SSl client certificate:
Authorization (see below).
Headers (see below)
Body (see below)
Now, I am trying to do ir programatically using dotnet core 6, but I keep running into the same problem:
And here is my code:
public static string GetAccessToken(IConfiguration _config)
{
string UserName = Environment.GetEnvironmentVariable("USER_NAME");
string Password = Environment.GetEnvironmentVariable("PASSWORD");
var client = new RestClient("https://connect2.xyz.com/auth/token");
var request = new RestRequest();
X509Certificate2 FullChainCertificate = new X509Certificate2("Path/to/Cert/cert.pfx", "test");
client.Options.ClientCertificates = new X509CertificateCollection() { FullChainCertificate };
client.Options.Proxy = new WebProxy("connect2.xyz.com");
var restrequest = new RestRequest();
restrequest.Method = Method.Get;
restrequest.AddHeader("Accept", "*/*");
restrequest.AddHeader("Cache-Control", "no-cache");
restrequest.AddHeader("Content-Type", "application/x-www-form-urlencoded");
restrequest.AddHeader("Authorization", "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes($"{UserName}:{Password}")));
restrequest.AddParameter("grant_type", "client_credentials");
RestResponse response = client.Execute(restrequest);
AccessTokenPointClickCare accessToken = JsonConvert.DeserializeObject<AccessTokenPointClickCare>(response.Content);
string strToken = accessToken.access_token;
return strToken;
}
Now, as the error seems to show, it has to do with the certificates (apparently), but I don't know if something in the code is wrong, or if I'm missing something, etc...
It is worth noting that this code did run in someone else's pc with the same set-up, but of course with that person's own pfx, but for the rest, it is essentially the same, and not to mention that it does work on my postman.
Finally, as the title on this question, the only thing I can think it might also be affecting the request is the host. If I reference the postman, there is a field where I have to place the host name of the server https://connect2.xyz.com/auth/token
So made it work by changing to a new Windows 10. Researching in other Stackoverflow threads found the answer: .NET CORE 5 '''HandshakeFailure'" when making HTTPS request
So I conclude it has to do with the cyphers

Connection closed from Facebook using http requests from ASP.net

I'm trying to make some GETs to the Facebook rest api from an ASP.net core application, but I get every time an exception because the remote host closed the connection. I tried like fourty different solutions that I found in similar questions but none of them worked. I changed the security protocol to Tls 1.2 but still got the same issue; I also tried using web client instead of http client. Then I tought it might have been the proxy of my office but cUrl worked fine; using postman I didn't get any error (even with tsl set to 1.0).
Another attempt was to try changing the keep-alive duration to avoid time-outs.
Here's the code with the HttpClient:
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
using (var httpClient = new HttpClient()){
httpClient.DefaultRequestHeaders.Add("Connection", "Keep-Alive");
httpClient.DefaultRequestHeaders.Add("Keep-Alive", "3600");
var request = new HttpRequestMessage(HttpMethod.Get,
"https://graph.facebook.com/v10.0/me?fields=id%2Cemail%2Cfirst_name%2Clast_name&access_token=" + socialLoginModel.accessToken);
request.Headers.Add("Accept", "application/json");
request.Headers.Add("User-Agent", "BriQ");
var response = await httpClient.SendAsync(request);
}
And here's the code with the WebClient:
using(var wb = new WebClient()){
var response = wb.DownloadString("https://graph.facebook.com/v10.0/me?fields=id%2Cemail%2Cfirst_name%2Clast_name&access_token=" + socialLoginModel.accessToken);
}
I'm completely out of ideas. Maybe it's something really stupid that's causing the exception but I can't figure it out alone
I'm not sure about which exception that you exactly got.
But as far as I know, if you're using .NET Core and the problem is caused by the SSL/TLS handshake failure error, then, unfortunately, setting the ServicePointManager may not work...
Because the ServicePointManager only affects the HttpWebRequest which is the default implementation of HttpClient on .NET Framework. Starting with .NET Core 2.1, the SocketsHttpHandler provides the implementation used by HttpClient.
Hence, I suppose the way to fix the issue is handling the SocketsHttpHandler:
using (var handler = new SocketsHttpHandler())
{
handler.SslOptions = new SslClientAuthenticationOptions{EnabledSslProtocols = SslProtocols.Tls12};
using (var httpClient = new HttpClient(handler))
{
// your code
}
}
Alternatively, if you prefer HttpClientHandler, you could do in this way:
using (var handler = new HttpClientHandler())
{
httpClientHandler.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
using (var httpClient = new HttpClient(handler))
{
// your code
}
}
Refs:
How to use TLS 1.2 in ASP.NET Core 2.0
HttpClient Class

Deno : Create bare hand HTTP Server: Deno.read keeps reading the connection

I was trying to a build a HTTP server using deno, but my code seems to misbehave
const listner = Deno.listen({port: 3000});
const decoder = new TextDecoder("utf-8");
const encoder = new TextEncoder();
for await(var conn of listner){
var p = new Uint8Array(1000);
while(await Deno.read(conn.rid,p)){
console.log(decoder.decode(p));
}
console.log("While loop ended");
conn.write(encoder.encode("Hello"));
conn.close();
}
The code never reaches "While loop ended".
As Deno.read must return null when there is nothing to read.
I do not want to use the standard lib http server.
I wanted to do create it from scratch as I wanted to understand its working.
Please can you cite me how one will create bare hello world HTTP server, by simply reading the world request and then sending hello world response ?

Download Stream with RestSharp and ResponseWriter

I donwnload a stream with RestSharp by using the ResponseWriter.
var client = new RestClient
var request = new RestRequest();
// ...
request.ResponseWriter = (ms) => {
// how to detect the status code
};
var response = client.Execute(request);
How can I found out the HTTP Status Code in the ResponseWriter?
Is there a better way to download a Stream?
You can check response.StatusCode and response.StatusDescription after executing the request.
Interestingly, if you use the DownloadData method as described here https://github.com/restsharp/RestSharp/wiki/Other-Usage-Examples there is no way to access this information as far as I can tell.
Currently You can use property AdvancedResponseWriter instead ResponseWriter.
The main difference is that AdvancedResponseWriter in addition to Response Stream gets IHttpResponse and You can check Response Status.
It should be working properly from version 106.6.
https://github.com/restsharp/RestSharp/issues/1207

Do I need to investigate HTTP 401 cached by Fiddler during the HttpWebRequest post to ASP.NET WebApi server

I am totally new to WebApi and WebRequests and other things.
After hours of googling, finally, I managed to do POST using C# and HttpWebRequest.
When I do HttpWebRequest in debug mode using Visual Studio I do not get any exceptions.
My app work as I accept , I get data to webApi server and also get back data.
To be sure how my app communicate with WebApi server I start Fiddler Web Debugger.
During the POST to WebApi, Fiddler chace 401 errors
{"Message":"Authorization has been denied for this request."}
Steping step by step in debuger I fund that following lines of code doing 401 error
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
wr.Credentials = new NetworkCredential(username, password);
wr.Method = "POST";
wr.ContentType = "application/json";
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(body);
wr.ContentLength = byteArray.Length;
using (System.IO.Stream dataStream = wr.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length); //After this line of code Fidler Chace HTTP 401
}
Later in code when I do wr.GetResponse() I do get status 200OK.
My questions are :
Do I need to redesign my code to avoid this error in Fiddler ?
Is there other methods to fill HttpWebRequest whit jsonSting beside using GetRequestStream() ?
If your service is enabled with Windows Authentcation, then in Fiddler, you can select the option to automatically authenticate using your logged on credentials by going here:
Composer tab -> Options tab -> Automatically Authenticate
Also, why not use HttpClient from System.Net.Http?...It has a much better and easy programming model...example:
HttpClientHandler handler = new HttpClientHandler();
handler.UseDefaultCredentials = true;
HttpClient client = new HttpClient(handler);
client.BaseAddress = new Uri("http://localhost:9095/");
HttpResponseMessage response = client.PostAsJsonAsync<Customer>("api/values", cust).Result;

Resources