10

I am trying to find a way how to transfer curl command to C#.

What i need is to obtain token from api and save it into file C:\...\x.json\

Then i want to declare token into variable, and use it into another curl POST request to take data to work with them.

Curl:

curl -X POST "https://example.com" 
-H "accept: application/json" 
-H "Content-Type: application/json" 
-d {"username":"username","password":"password"}

My current try:

static void Main(string[] args)
{
    using (var httpClient = new HttpClient())
    {
        using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://example.com"))
        {
            request.Headers.TryAddWithoutValidation("Accept", "application/json");

            request.Content = new StringContent("{\"username\":\"username\",\"password\":\"password\"}", Encoding.UTF8, "application/json");

            var response = await httpClient.SendAsync(request);
        }
    }                        
}

I tried several things, but none of them was working. This one is from curl.olsh.me but also i am getting some await error what i don't know what to do with it. (I am newbie in C#) :

The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.

curl -v output:

    • Trying 10.0.0.0...
    • TCP_NODELAY set
    • Connected to example.com (10.0.0.0) port 443 (#0)
    • ALPN, offering h2
    • ALPN, offering http/1.1
    • successfully set certificate verify locations:
    • CAfile: C:\Users\lvrabel\Downloads\curl-7.60.0-win64-mingw\curl-7.60.0-win64-mingw\bin\curl-ca-bundle.crt CApath: none
    • TLSv1.2 (OUT), TLS handshake, Client hello (1):
    • TLSv1.2 (IN), TLS handshake, Server hello (2):
    • TLSv1.2 (IN), TLS handshake, Certificate (11):
    • TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    • TLSv1.2 (IN), TLS handshake, Server finished (14):
    • TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    • TLSv1.2 (OUT), TLS change cipher, Client hello (1):
    • TLSv1.2 (OUT), TLS handshake, Finished (20):
    • TLSv1.2 (IN), TLS handshake, Finished (20):
    • SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
    • ALPN, server did not agree to a protocol
    • Server certificate:
    • subject: OU=Domain Control Validated; OU=PositiveSSL Wildcard; CN=*.example.com
    • start date: Dec 1 00:00:00 2016 GMT
    • expire date: Dec 1 23:59:59 2019 GMT
    • subjectAltName: host "example.com" matched cert's "*.example.com"
    • issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Domain Validation Secure Server
    • SSL certificate verify ok. < POST /cxf/IOTServices/v2/Login HTTP/1.1 < Host: example.com < User-Agent: curl/7.60.0 < accept: application/json < Content-Type: application/json < Content-Length: 64 <
    • upload completely sent off: 64 out of 64 bytes < HTTP/1.1 200 OK < Date: Mon, 24 Sep 2018 09:22:30 GMT < Content-Type: application/json < Date: Mon, 24 Sep 2018 09:22:31 GMT < Connection: close < Set-Cookie: TS0119a36f=015d568915873c94e852616fd92d5dd7a03a620f3cd2326781154684dfd7b31302f6fcb9822598d5a76466d0c6a25583fccbb30c7d; Path=/; Domain=.example.com < Transfer-Encoding: chunked < {"code":200,"status":"success","sessionId":"5cd92d80-bfdb-11e8-83c7-5b742f0c1244"}* Closing connection 0
    • TLSv1.2 (OUT), TLS alert, Client hello (1):
4
  • Your method sig should look like: static async void Main(string[] args). You add the async keyword. Commented Sep 21, 2018 at 11:55
  • Hi @Stuart, then i don't understand it, because when i change Main method then i got error : Program does not contain static Main method suitable for an entry point Commented Sep 21, 2018 at 11:59
  • You might want to define a task method, and then call that from within Main... Commented Sep 21, 2018 at 12:02
  • @LukášVrábel check my answer, that might solve your issue. Commented Sep 3, 2019 at 11:32

6 Answers 6

5

use this website https://curl.olsh.me/

using (var httpClient = new HttpClient())
{
    using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://example.com/"))
    {
        request.Headers.TryAddWithoutValidation("Accept", "application/json"); 

        request.Content = new StringContent("{\"username\":\"username\",\"password\":\"password\"}", Encoding.UTF8, "application/json"); 

        var response = await httpClient.SendAsync(request);
    }
}
Sign up to request clarification or add additional context in comments.

Comments

3
+200

As far as I know you need to convert username and password to bytes, and take it as base 64 string and pass it to header. When you use await, if it is a void method then you should add async modifier with Task in its signature OR in case the method should return what ever type than use async Task as shown in the example. In that case you need to fetch the result, using result as shown in the test example. You can read more on this topic in Microsoft docs.

Here is the code:

public async Task<HttpResponseMessage> CreateAuthorization(string url, string username, string password)
{
    HttpResponseMessage response;

    using (var httpClient = new HttpClient())
    {
        using (var request = new HttpRequestMessage(new HttpMethod("POST"), url))
        {
            request.Headers.TryAddWithoutValidation("Accept", "application/json");
            var authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{username}:{password}"));
            request.Headers.TryAddWithoutValidation("Authorization", $"Basic {authorization}");
            response = await httpClient.SendAsync(request);
        }
    }

    return response;
}

Here is example of testing it:

public void CreateAuthorizationTest()
{
    var response = CreateAuthorization("https://example.com", "username", "password");
    var result = response.Result;
    var o = result.Content.ReadAsStringAsync();

    if (result.IsSuccessStatusCode)
    {
        //do some thing if success
        // you can do deserialization what ever
        Console.WriteLine(o);
    }
    else
    {
        //do some thing if error
        Console.WriteLine(o);
    }
    //etc.
}

Links:

9 Comments

Can you show the request code? It's the passing of the post data that's problematic. I've been using application/x-www-form-urlencoded as well.
@user1274820 just to be sure the other answer got the bounty so I assume you got the answer. so I also assume that my answer is irrelevant. If you think I can contribute more let me know so I can look at it when I have time, it is late night at my location.
Wtf I gave the bounty to you... you were supposed to get it dude
I started another bounty - I can award it to you in 23 hours 😑 sorry about that man
No problems I am happy you solved it. The best luck forward
|
2

You have to make the main method async:

static async void Main(string[] args)

If you are using C# version < 7.1, then you cannot use any await directly in Main. In this case you have to define a Task and .Wait() for it (instead of await for it).

Task task = ....;
task.Wait();
var result = task.Result;

Comments

2

Async main methods is available in C# 7. If you're on an earlier version, you can handle the task 'manually' like this

var task = httpClient.SendAsync(request);
task.Wait();
var response = task.Result;
Console.WriteLine(response.Content.ReadAsStringAsync().Result);

14 Comments

Nice that is working, thank you for that. I do have respond from server right now, but sadly i see just this : StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers: Where should be also token, but i dont see it.
Actually more specifically, since 7.1
@LukášVrábel Since you're getting a 200 return code, the call is going through to the server. You could try to debug on the server side if you have access to it to see what is going on. If you don't have access to the server, you could try getting the call to work with Postman or something like that.
Sadly I don't have access to that server. Syntax of the token is something like this: 6fa3ea90-bc02-11e8-991a-d35512019464. That should be problem for Encoding right?
Can you post the output from curl in your question?
|
1

I use the System.Net.Http.Formatting.Extension

example:

using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
// Add NuGet package System.Net.Http.Formatting.Extension
namespace SimpleRestCall
{
    class Program
    {
        static CancellationTokenSource cts = new CancellationTokenSource();

        static readonly string sitePath = "https://example.com";
        static void Main(string[] args)
        {
            using (var client = new HttpClient { BaseAddress = new Uri(sitePath), Timeout = new TimeSpan(0, 1, 0) })
            {
                Task.Run(() => Login(client)).Wait();
            }
        }

        private static async Task Login(HttpClient client)
        {
            string path = ""; // if it's a controller path put it here
            LoginData postData = new LoginData { username = "username", password = "password" };
            string json;
            using (HttpResponseMessage resp = await client.PostAsJsonAsync(path, postData, cts.Token))
            {
                json = await resp.Content.ReadAsStringAsync();
            }
            Console.WriteLine(json);
            Console.WriteLine("Press a key to finish");
            string aa = Console.ReadLine();
        }

        private class LoginData
        {
            public string username { get; set; }
            public string password { get; set; }
        }
    }
}

Comments

1
+100

Update:

I got this response from server :

StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers: { Date: Tue, 25 Sep 2018 06:57:16 GMT Date: Tue, 25 Sep 2018 06:57:17 GMT Connection: close Set-Cookie: TS0119a36f=015d56898097bc7f5dccb374f352898f8806da5833c9f8a8ef4ff6ae2a2b1d4e78147fb79479f8bf85929406f34372c41c63572a89; Path=/; Domain=.example.com Transfer-Encoding: chunked Content-Type: application/json }

I think that there is some problem with encoding or idk. When i execute curl i get this output (the one i need):

{"code":200,"status":"success","sessionId":"350bf800-bfdb-11e8-991a-d35510009464"}

Current code:

    static void Main(string[] args)
    {
        using (var httpClient = new HttpClient())
        {
            using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.example.com"))
            {
                request.Headers.TryAddWithoutValidation("accept", "application/json");
                request.Content = new StringContent("{\"username\":\"user\",\"password\":\"pass\"}", Encoding.UTF8, "application/json");

                var task = httpClient.SendAsync(request);
                task.Wait();
                var response = task.Result;

                Console.WriteLine(response);
                Console.ReadKey();
            }
        }
    }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.