简体   繁体   English

将POST卷入C#

[英]curl POST into C#

I am trying to find a way how to transfer curl command to C#. 我试图找到一种方法如何将curl命令传递给C#。

What i need is to obtain token from api and save it into file C:\\...\\x.json\\ 我需要的是从api获取令牌并将其保存到文件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. 然后我想将token声明为变量,并将其用于另一个curl POST请求以获取数据以使用它们。

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. 这个是来自curl.olsh.me,但我也得到一些等待错误,我不知道该怎么办。 (I am newbie in C#) : (我是C#的新手):

The 'await' operator can only be used within an async method. 'await'运算符只能在异步方法中使用。 Consider marking this method with the 'async' modifier and changing its return type to 'Task'. 考虑使用'async'修饰符标记此方法并将其返回类型更改为'Task'。

curl -v output: 卷曲-v输出:

    • Trying 10.0.0.0... 试试10.0.0.0 ......
    • TCP_NODELAY set TCP_NODELAY设置
    • Connected to example.com (10.0.0.0) port 443 (#0) 连接到example.com(10.0.0.0)端口443(#0)
    • ALPN, offering h2 ALPN,提供h2
    • ALPN, offering http/1.1 ALPN,提供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 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(OUT),TLS握手,客户端问候(1):
    • TLSv1.2 (IN), TLS handshake, Server hello (2): TLSv1.2(IN),TLS握手,服务器问候(2):
    • TLSv1.2 (IN), TLS handshake, Certificate (11): TLSv1.2(IN),TLS握手,证书(11):
    • TLSv1.2 (IN), TLS handshake, Server key exchange (12): TLSv1.2(IN),TLS握手,服务器密钥交换(12):
    • TLSv1.2 (IN), TLS handshake, Server finished (14): TLSv1.2(IN),TLS握手,服务器完成(14):
    • TLSv1.2 (OUT), TLS handshake, Client key exchange (16): TLSv1.2(OUT),TLS握手,客户端密钥交换(16):
    • TLSv1.2 (OUT), TLS change cipher, Client hello (1): TLSv1.2(OUT),TLS更改密码,客户端问候(1):
    • TLSv1.2 (OUT), TLS handshake, Finished (20): TLSv1.2(OUT),TLS握手,已完成(20):
    • TLSv1.2 (IN), TLS handshake, Finished (20): TLSv1.2(IN),TLS握手,已完成(20):
    • SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 使用TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256进行SSL连接
    • ALPN, server did not agree to a protocol ALPN,服务器不同意协议
    • Server certificate: 服务器证书:
    • subject: OU=Domain Control Validated; subject:OU =域控制验证; OU=PositiveSSL Wildcard; OU = PositiveSSL通配符; CN=*.example.com CN = *。example.com
    • start date: Dec 1 00:00:00 2016 GMT 开课日期:2016年12月1日00:00:00 GMT
    • expire date: Dec 1 23:59:59 2019 GMT 到期日:格林威治标准时间12月1日23:59:59 2019
    • subjectAltName: host "example.com" matched cert's "*.example.com" subjectAltName:host“example.com”匹配cert的“* .example.com”
    • issuer: C=GB; 发行人:C = GB; ST=Greater Manchester; ST =大曼彻斯特; L=Salford; L =索尔福德; O=COMODO CA Limited; O = COMODO CA Limited; CN=COMODO RSA Domain Validation Secure Server CN = COMODO RSA域验证安全服务器
    • SSL certificate verify ok. SSL证书验证确定。 < 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 < <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; 上传完全被发送:64个字节中的64个<HTTP / 1.1 200 OK <日期:星期一,2018年9月24日09:22:30 GMT <Content-Type:application / json <日期:星期一,2019年9月24日09:22: 31 GMT <连接:关闭<Set-Cookie:TS0119a36f = 015d568915873c94e852616fd92d5dd7a03a620f3cd2326781154684dfd7b31302f6fcb9822598d5a76466d0c6a25583fccbb30c7d; Path=/; 路径= /; Domain=.example.com < Transfer-Encoding: chunked < {"code":200,"status":"success","sessionId":"5cd92d80-bfdb-11e8-83c7-5b742f0c1244"}* Closing connection 0 Domain = .example.com <Transfer-Encoding:chunked <{“code”:200,“status”:“success”,“sessionId”:“5cd92d80-bfdb-11e8-83c7-5b742f0c1244”} *关闭连接0
    • TLSv1.2 (OUT), TLS alert, Client hello (1): TLSv1.2(OUT),TLS警报,客户问候(1):

use this website https://curl.olsh.me/ 使用这个网站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);
    }
}

Async main methods is available in C# 7. If you're on an earlier version, you can handle the task 'manually' like this C#7中提供了异步主要方法。如果您使用的是早期版本,则可以像这样“手动”处理任务

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

You have to make the main method async : 你必须使main方法async

static async void Main(string[] args)

If you are using C# version < 7.1, then you cannot use any await directly in Main . 如果您使用的是C#版本<7.1,那么您不能在Main直接使用任何等待。 In this case you have to define a Task and .Wait() for it (instead of await for it). 在这种情况下,您必须为它定义一个Task.Wait() (而不是await它)。

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

I use the System.Net.Http.Formatting.Extension 我使用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; }
        }
    }
}

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; StatusCode:200,ReasonPhrase:'OK',版本:1.1,内容:System.Net.Http.StreamContent,Headers:{Date:Tue,25 Sep 2018 06:57:16 GMT Date:Tue,25 Sep 2018 06:57 :17 GMT连接:close Set-Cookie:TS0119a36f = 015d56898097bc7f5dccb374f352898f8806da5833c9f8a8ef4ff6ae2a2b1d4e78147fb79479f8bf85929406f34372c41c63572a89; Path=/; 路径= /; Domain=.example.com Transfer-Encoding: chunked Content-Type: application/json } Domain = .example.com Transfer-Encoding:chunked Content-Type:application / json}

I think that there is some problem with encoding or idk. 我认为编码或idk存在一些问题。 When i execute curl i get this output (the one i need): 当我执行curl时,我得到这个输出(我需要的那个):

{"code":200,"status":"success","sessionId":"350bf800-bfdb-11e8-991a-d35510009464"} { “代码”:200, “状态”: “成功”, “的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();
            }
        }
    }

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. 据我所知,您需要将用户名和密码转换为字节,并将其作为基本64字符串并将其传递给标头。 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. 当你使用await时,如果它是一个void方法,那么你应该在其签名OR中添加带有Task的async修饰符,以防该方法应该返回任何类型而不是使用async Task,如示例所示。 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. 您可以在Microsoft文档中阅读有关此主题的更多信息。

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: 链接:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM