簡體   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