簡體   English   中英

C# - httpclient - json 正文 - 未使用 httpcontent 正確應用

[英]C# - httpclient - json body - Not getting applied appropriately using httpcontent

以下是我將返回響應狀態代碼和響應 output 元組的代碼。

private Tuple<int, string> API_Check(string URL, string reqtype, string reqbody, string split_username, string split_pwd)
    {
        string responsetxt="";
        HttpResponseMessage httpresult = new HttpResponseMessage();
        int statuscode = 0;
        ServicePointManager.Expect100Continue = true;
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
        ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
        HttpClient _httpClient = new HttpClient();
        var authString = Convert.ToBase64String(Encoding.UTF8.GetBytes(split_username+":" + split_pwd));
        _httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authString);
        try
        {
            using (var content = new StringContent(JsonConvert.SerializeObject(reqbody)))
            {
                if (reqtype == "GET")
                {
                    httpresult = _httpClient.GetAsync(URL).Result;
                }
                if (reqtype == "PUT")
                {
                    httpresult = _httpClient.PutAsync(URL, content).Result;
                    //httpresult = _httpClient.PutAsync()
                }
                if (reqtype == "POST")
                {
                    httpresult = _httpClient.PostAsync(URL, content).Result;
                }

                statuscode = (int)httpresult.StatusCode;
                responsetxt = httpresult.Content.ReadAsStringAsync().Result;
                return Tuple.Create(statuscode, responsetxt);
            }
        }
        catch (System.Net.WebException Excptn)
        {
            statuscode = 401;
            responsetxt = Excptn.Status.ToString();
            using (var stream = Excptn.Response.GetResponseStream())
            using (var reader = new StreamReader(stream))
            {
                MessageBox.Show(reader.ReadToEnd());
            }
        }
        return Tuple.Create(statuscode, responsetxt);
    }

由於某種原因,請求正文在調用期間未正確填寫。 對於此 Post 調用,我收到 401 Unauthorized ,這絕對不是授權錯誤,因為我收到的響應消息相當於空正文或無效輸入 json 格式。

當我嘗試使用 Postman 為端點命中相同的 reqbody 時,我得到 200 個有效響應。 此外,GetAsync 適用於不需要主體的類似 API。

我確認用戶名、密碼或端點 URL 沒有問題。

有沒有辦法,我可以避免使用 httpcontent 並使用字符串來通過 C# 擊中 API?

現在,由於我當前的 .Net 框架限制,我無法使用 HttpWebRequest。

你的代碼有很多問題:

  • 首先,您正在序列化已經是字符串的reqbody 聽起來你已經有一個 JSON 字符串,在這種情況下你不需要序列化它。
  • 不要使用.Result ,它會導致死鎖。 改用await
  • 使用 Valuetuple 而不是Tuple ,這可能是低效的。
  • 不要設置ServicePointManager.SecurityProtocol =... ,而是讓操作系統選擇最佳的安全協議。
  • 一般不要使用ServicePointManager ,因為它會影響來自您的應用程序的所有 HTTP 請求。 而是設置相關的HtppClient屬性,或者更好:使用HttpRequestMessage並直接在消息上設置它。
  • 如果您使用HttpRequestMessage ,您可以稍微簡化代碼,給它 HTTP 方法的類型
  • 您正在捕獲錯誤的異常類型。 您應該捕獲HttpRequestException ,從中可以獲取實際StatusCode
  • 默認情況下, HttpClient不會拋出不成功的代碼。 您需要明確處理它們。
  • 緩存HttpClient ,否則可能會導致套接字耗盡。
  • 創建一個new HttpResponseMessage並沒有多大意義。
HttpClient _httpClient = new HttpClient {
    DefaultRequestHeaders = {
        ExpectContinue = false,
    },
};

private async Task<(int, string)> API_Check(string URL, HttpMethod reqtype, string reqbody, string split_username, string split_pwd)
{
    var authString = Convert.ToBase64String(Encoding.UTF8.GetBytes(split_username + ":" + split_pwd));
    try
    {
        using (var content = new StringContent(reqbody))
        using (var request = new HttpRequestMessage(URL, reqtype))
        {
            message.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authString);
            if (reqtype != "GET")
                message.Content = content;

            using var httpresult = await _httpClient.SendAsync(URL, content);
            var statuscode = (int)httpresult.StatusCode;
            var responsetxt = await httpresult.Content.ReadAsStringAsync();
            if (!httpresult.IsSuccessStatusCode)
                MessageBox.Show(responsetxt);

            return (statuscode, responsetxt);
        }
    }
    catch (HttpRequestException ex)
    {
        var statuscode = ex.StatusCode ?? 0;
        var responsetxt = ex.Message;
        MessageBox.Show(responsetxt);
        return (statuscode, responsetxt);
    }
}

如果您實際上有一個 object 來序列化然后將方法更改為

private async Task<(int, string)> API_Check(string URL, HttpMethod reqtype, object reqbody, string split_username, string split_pwd)
{
....
....
        using (var content = new StringContent(JsonConvert.SerializeObject(reqbody)))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM