Python Request/cURL to C# POST request - c#

I need help with simple POST request to discussion forum. I have right datas, it works in Python also when I write as cURL command and run it with GitBash. Problem is that's not work in C#.
I need help from you, because I don't know how write right code in C#, which i need.
Here is a Python code:
import requests
headers = {
'Content-type': 'application/x-www-form-urlencoded',
'Cookie': 'cookie_notice=1'
}
data = 'id=44&typ=0&parent=-1&login=User&password=password&text=test22\ntest33'
response = requests.post('address.php', headers=headers, data=data)
Here is a cURL:
curl 'address.php' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Cookie: cookie_notice=1' -d "id=44&typ=0&parent=-1&login=User&heslo=password&text=test22"
I've try compile with this: https://curl.olsh.me/
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "http://address.php/"))
{
request.Headers.TryAddWithoutValidation("Cookie", "cookie_notice=1");
request.Content = new StringContent("id=44&typ=0&parent=-1&login=User&heslo=password&text=test22", Encoding.UTF8, "application/x-www-form-urlencoded");
var response = await httpClient.SendAsync(request);
}
}
The program runs this C# code without any errors, but in discussion forum isn't my contribution.
Thanks for the Answer !

The problem is that the HttpClient ignores request Cookie header because it relies on HttpClientHandler and its CookieContainer. The solution is telling HttpClient that you will set cookies via headers
var httpClient = new HttpClient(new HttpClientHandler { UseCookies = false }))

Related

'invalid_grant' error on API call with RestSharp

I need to convert that curl request to c#. Im using RestSharp. curl request:
> curl -X POST -i https://gw.api.alphabank.eu/sandbox/auth/token \
-u "{{client_id}}:{{client_secret}}" \
-d "grant_type=client_credentials&scope=account-info-setup"
I tried the following code but I end up with 'invalid_grant' error as a response.
Any ideas what i'm doing wrong?
My code:
var client = new RestClient(url);
var request = new RestRequest();
request.Method = Method.POST;
client.Authenticator = new HttpBasicAuthenticator(ABclientID, ABclientSecret);
request.AddParameter("grant_type", "client_credentials");
request.AddParameter("scope", "account-info-setup");
request.OnBeforeDeserialization = resp => { resp.ContentType = "application/x-www-form-urlencoded"; };
IRestResponse response = client.Execute(request);
this sample code is generated by Postman and it's working for my api which accepts application/x-www-form-urlencoded, can you add your parameters like this? Or create and make your request works on Postman and generate to C#-RestSharp it's usually works for me with minor changes.
var client = new RestClient("url");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("userId", "1234");
request.AddParameter("count", "5");
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
Turns out "invalid_grant" meant wrong credentials. I was giving wrong client-secret.
Request was succesfull after correcting the client_secret.

Is there a way to pass this contenttype "application/x-www-form-urlencoded;v=2.0" in C#?

I am trying to replicate in C# the following code in CURL. Note that this code is working correctly with curl. I am using this https://curl.olsh.me/ to create the request.
curl -k -u "Default User:robotics" -H "Content-Type: application/x-www-form-urlencoded;v=2.0" -d "value=TRUE" "https://localhost/rw/rapid/symbol/RAPID/T_ROB1/EGMDemo/run_egm/data?mastership=implicit"
I have tried to translate this command to c# and when arriving to the line:
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded;v=2.0");
I receive an exception that application/x-www-form-urlencoded;v=2.0 is not valid.
How can I pass this content type? If it is not possible with httpclient is there any other way to do it?
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = (requestMessage, certificate, chain, policyErrors) => true;
using (var httpClient = new HttpClient(handler))
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://localhost/rw/rapid/symbol/RAPID/T_ROB1/EGMDemo/run_egm/data?mastership=implicit"))
{
var base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes("Default User:robotics"));
request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}");
request.Content = new StringContent("value=TRUE");
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded;v=2.0");
var response = await httpClient.SendAsync(request);
}
}
You can try to directly use
request.Content.Headers.Add("Content-Type", "application/x-www-form-urlencoded;v=2.0");
MediaTypeHeaderValue provide support only for standard media type as defined for HTTP/1.1
EDIT mistake :)

C# GitHub SCIM API // Difference between cURL and HttpClient

I'm facing a strange error with the usage of the GITHUB API.
When I contact them with cURL it's like:
curl.exe -H "Accept: application/vnd.github.cloud-9-preview+json+scim" -H "Authorization: Bearer TOKEN" https://api.github.com/scim/v2/organizations/[ORG]/Users
When I try to take it to C#, if became:
using (var cl = new HttpClient())
{
cl.DefaultRequestHeaders.Add("Accept", "application/vnd.github.cloud-9-preview+json+scim");
cl.DefaultRequestHeaders.Add("Authorization", "Bearer " + "TOKEN");
var val = cl.GetStringAsync("https://api.github.com/scim/v2/organizations/[ORG]/Users").Result;
}
When I run my cURL everything works fine but when I try the same on C# I got a 403 Error.
Could it be related to the "Accept" non standard field?
I find out that the GITHUB API requires to have the User-Agent header Set.
Setting it as "curl" made it.
using (var cl = new HttpClient())
{
cl.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/vnd.github.cloud-9-preview+json+scim"));
cl.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "token");
cl.DefaultRequestHeaders.UserAgent.Add(new System.Net.Http.Headers.ProductInfoHeaderValue("curl", "7.46.0"));
var val = cl.GetStringAsync("https://api.github.com/scim/v2/organizations/[ORG]/Users").Result;
}

Curl request written in C# doesn't work

I'm trying to write a specific curl request in C#, and I keep getting a 500 server error response from the server. This curl request essentially makes a post request to an API by the company Highwinds. This request sends json data, and sets the Auth Bearer token header.
This is the curl request that works fine (note that I've replaced my actual bearer token with {token} and my actual account id with {accountId} to obfuscate that info):
curl -H "Authorization: Bearer {token}" -H "Content-Type: application/json" -d "#data.json" "https://striketracker.highwinds.com/api/accounts/{accountId}/purge"
Here's the C# code that gives me a generic 500 server error from the Highwinds API (note that I've replaced my actual bearer token with {token}, my actual account id with {accountId}, and the url in the json string with {url}, in order to obfuscate that personal info):
var accountId = "{accountId}";
var purgeURI = string.Format("https://striketracker.highwinds.com/api/accounts/{0}/purge", {accountId});
var query =
#"{""list"": [{""url"": ""{url}"",""recursive"": true}]}";
var token = {token};
using (var httpClient = new HttpClient())
{
var url = new Uri(purgeURI);
using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, url))
{
httpRequestMessage.Headers.Add(System.Net.HttpRequestHeader.Authorization.ToString(),
string.Format("Bearer {0}", token));
httpRequestMessage.Content = new StringContent(query,
Encoding.UTF8,
"application/json");
await httpClient.SendAsync(httpRequestMessage).ContinueWith(task =>
{
var response = task.Result;
var blah = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
});
}
}
Thanks!
*Update: The following line of code was added to remove the Expect header that HttpRequest adds to a request by default. After removing this header I was able to get Highwinds API to accept the request without bombing.
"request.ServicePoint.Expect100Continue = false;"
My best recommendation would be to proxy both requests through something like tcpmon http://archive.apache.org/dist/ws/tcpmon/1.0/ (Basically run the server and point to local host and have tcpmon redirect the request to striketracker.highwinds.com). Try it from curl and from your source and you should be able to see what's different between the requests.

How to use OAuth2 in RestSharp

After a couple of days sorting out OAuth2 at the server-end (Spring java) I started working on the client written in C#. I am using RestSharp to call my web API but I am having real difficulty with the OAuth2. There is hardly any documentation and the few examples I found online do not work. Can someone provide me a code sample that is up to date and that I can use?
So far I have the following:
var client = new RestClient("http://example.com/myapi/oauth/token");
RestRequest request = new RestRequest() { Method = Method.POST };
request.AddHeader("Content-Type", "application/json");
request.AddParameter("grant_type", "client_credentials");
request.AddParameter("client_id", "client-app");
request.AddParameter("client_secret", "secret");
var response = client.Execute(request);
I am simply running this code in debug mode and when I look into the response I get unauthorized.
When I do curl on the console with the same parameters it works fine but it seems I can't make this to work in C#. Here is the curl command:
curl -H "Accept: application/json" client-app:secret#example.com/myapi/oauth/token -d grant_type=client_credentials
By the way, I have replaced my true API urls and other information with placeholders.
See RFC 6749 - 4.4.2. Client Credentials - Access Token Request
Here is the basic format of the request
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
Your cURL request
curl -H "Accept: application/json" \
-d grant_type=client_credentials \
client-app:secret#example.com/myapi/oauth/token
The reason your cURL command works
Default Content-Type (if not specified) with POST (default when you use -d switch) is application/x-www-form-urlencoded
Default authentication type, if not specified, is Basic. The username and password are passed either through the -u option or in the URL
-u username:password (client-app:secret)
-- or put it in the url --
client-app:secret#example.com/myapi/oauth/token
You could also specify the auth type with --basic or --digest
You can use the -v switch in your cURL command to see all the headers involved in the request.
RestSharp fix:
Set the Content-Type to application/x-www-form-urlencoded
Add the Basic authentication
client.Authenticator = new HttpBasicAuthenticator("client-app", "secret");
Get rid of
request.AddParameter("client_id", "client-app");
request.AddParameter("client_secret", "secret");
Set the Accept header to application/json
I am able to get both of the following functions worked.
public RestClient getClient2(string user, string token)
{
RestClient client = new RestClient();
client.BaseUrl = new Uri(baseUrl);
client.Authenticator = new HttpBasicAuthenticator(user, token);
//client.Authenticator = new OAuth2UriQueryParameterAuthenticator(token); //works
//client.Authenticator = new OAuth2AuthorizationRequestHeaderAuthenticator(token); // doesn't work
return client;
}
public GitHubUser GetGitHubUser2()
{
RestRequest request = new RestRequest();
request.Resource = "/users/huj";
request.RootElement = "GitHubUser";
RestClient client = getClient2(myUser, myToken);
return Execute<GitHubUser>(client, request);
}
/// <summary>
/// http://stackoverflow.com/questions/30133937/how-to-use-oauth2-in-restsharp
/// </summary>
/// <returns>GitHubUser</returns>
public GitHubUser GetGitHubUser3()
{
//RestRequest request = new RestRequest(Method.POST); //empty data
RestRequest request = new RestRequest();
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddHeader("Accept", "application/json");
request.AddParameter("grant_type", "client_credentials");
request.Resource = "/users/huj";
request.RootElement = "GitHubUser";
RestClient client = getClient2(myUser, myToken);
return Execute<GitHubUser>(client, request);
}

Categories

Resources