繁体   English   中英

将POST卷入C#

[英]curl POST into C#

我试图找到一种方法如何将curl命令传递给C#。

我需要的是从api获取令牌并将其保存到文件C:\\ ... \\ x.json \\

然后我想将token声明为变量,并将其用于另一个curl POST请求以获取数据以使用它们。

卷曲:

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

我目前的尝试:

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);
        }
    }                        
}

我尝试了几件事,但没有一件工作。 这个是来自curl.olsh.me,但我也得到一些等待错误,我不知道该怎么办。 (我是C#的新手):

'await'运算符只能在异步方法中使用。 考虑使用'async'修饰符标记此方法并将其返回类型更改为'Task'。

卷曲-v输出:

    • 试试10.0.0.0 ......
    • TCP_NODELAY设置
    • 连接到example.com(10.0.0.0)端口443(#0)
    • ALPN,提供h2
    • ALPN,提供http / 1.1
    • 成功设置证书验证位置:
    • 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握手,客户端问候(1):
    • TLSv1.2(IN),TLS握手,服务器问候(2):
    • TLSv1.2(IN),TLS握手,证书(11):
    • TLSv1.2(IN),TLS握手,服务器密钥交换(12):
    • TLSv1.2(IN),TLS握手,服务器完成(14):
    • TLSv1.2(OUT),TLS握手,客户端密钥交换(16):
    • TLSv1.2(OUT),TLS更改密码,客户端问候(1):
    • TLSv1.2(OUT),TLS握手,已完成(20):
    • TLSv1.2(IN),TLS握手,已完成(20):
    • 使用TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256进行SSL连接
    • ALPN,服务器不同意协议
    • 服务器证书:
    • subject:OU =域控制验证; OU = PositiveSSL通配符; CN = *。example.com
    • 开课日期:2016年12月1日00:00:00 GMT
    • 到期日:格林威治标准时间12月1日23:59:59 2019
    • subjectAltName:host“example.com”匹配cert的“* .example.com”
    • 发行人:C = GB; ST =大曼彻斯特; L =索尔福德; O = COMODO CA Limited; CN = COMODO RSA域验证安全服务器
    • 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 <
    • 上传完全被发送: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; 路径= /; Domain = .example.com <Transfer-Encoding:chunked <{“code”:200,“status”:“success”,“sessionId”:“5cd92d80-bfdb-11e8-83c7-5b742f0c1244”} *关闭连接0
    • TLSv1.2(OUT),TLS警报,客户问候(1):

使用这个网站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);
    }
}

C#7中提供了异步主要方法。如果您使用的是早期版本,则可以像这样“手动”处理任务

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

你必须使main方法async

static async void Main(string[] args)

如果您使用的是C#版本<7.1,那么您不能在Main直接使用任何等待。 在这种情况下,您必须为它定义一个Task.Wait() (而不是await它)。

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

我使用System.Net.Http.Formatting.Extension

例:

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; }
        }
    }
}

更新:

我从服务器得到了这个回复:

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; 路径= /; Domain = .example.com Transfer-Encoding:chunked Content-Type:application / json}

我认为编码或idk存在一些问题。 当我执行curl时,我得到这个输出(我需要的那个):

{ “代码”:200, “状态”: “成功”, “的sessionId”: “350bf800-bfdb-11e8-991a-d35510009464”}

当前代码:

    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();
            }
        }
    }

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

这是代码:

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;
}

以下是测试它的示例:

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.
}

链接:

暂无
暂无

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

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