iT邦幫忙

0

.NET 6 Console application HttpClient PostAsync UTF-8 無法正確轉換中文

  • 分享至 

  • xImage

背景說明
在 .NET6 Console Application 嘗試透過 HttpClient 從 API 取得資料庫資料,
呼叫API端時有進行偵錯,可以看出成功取得資料,
但回到Console程式端,資料都變成亂碼,
並沒有按照UTF-8的方式Encode中文,
(有事先設定 Encoding.UTF8
HttpContent contentPost = new StringContent(json, Encoding.UTF8, "application/json"); )

以下是程式碼的部分:

WebAPI

[HttpPost]
        [Route("GetData")]
        public IActionResult GetData([FromBody] Parameter parameter)
        {
            string jsonData = "";

            try
            {
                //省略資料庫存取程式碼
                List<string> eqEventMsgs = 資料庫存取
                
                //轉成Json字串
                jsonData = JsonConvert.SerializeObject(eqEventMsgs);
                
                //回傳資料,jsonData資料中文顯示正確
                return Json(jsonData);
            }
            catch(Exception ex)
            {
                return Json(new ApiError("500", ex.Message));
            }
        }

Console Application

        /// <summary>
        /// 呼叫 API 取得資料庫資料
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="instID"></param>
        /// <returns></returns>
        public async Task GetDatas(string tableName, int instID)
        {
            string uriBase = "http://localhost:5000/GetData/";

            try
            {
                HttpClientService httpClient = new HttpClientService();

                #region 使用PostAsync

                httpClient.httpClientInstance.BaseAddress = new Uri(uriBase);

                // 準備傳送的參數
                var postData = new { Tablename = tableName, InstId = instID };
                // 將 data 轉為 json
                string json = JsonConvert.SerializeObject(postData);
                // 將轉為 string 的 json 依編碼並指定 content type 存為 httpcontent
                HttpContent contentPost = new StringContent(json, Encoding.UTF8, "application/json");

                //這邊取得結果全部變成亂碼
                HttpResponseMessage response = await httpClient.httpClientInstance.PostAsync(uriBase, contentPost);

                string finalRes = response.Content.ReadAsStringAsync().Result;

                #endregion

                byte[] bytes = Encoding.Default.GetBytes(finalRes);
                string myString = Encoding.UTF8.GetString(bytes);

                Console.WriteLine(myString);
            }
            catch (HttpRequestException e)
            {
                Console.WriteLine("\nException Caught!");
                Console.WriteLine("Message :{0} ", e.Message);
            }

        }
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

1
水無痕
iT邦新手 3 級 ‧ 2022-08-30 08:35:27
最佳解答

二個點:

  1. Web API 端預設不需要先做 JsonConvert.SerializeObject() 的動作 !
    因為不確定 return Json() 是什麼,也可以直接用 return Ok(eqEventMsgs);
    就會將 eqEventMsgs 進行 Json 序列化 !

  2. Console 端的finalRes 就是 Json 字串,該字串的確會看到 utf-8 字樣,可以直接進行 Json 反序列化變為物件 !
    用 Debug Mode 看,該物件內的 string property 都會被還原回來 !

edwang iT邦新手 4 級 ‧ 2022-08-31 08:08:45 檢舉

感謝水無痕大回復,
確實finalRes裡面是Json字串,
是說我用Postman去取得API資料都能正常回傳中文字,
但如果用Console回傳卻會取得以下亂碼內容
https://i.imgur.com/iiZSnuT.png
我的目標是再將這些資訊傳到另一支程式將Json字串轉為字串。
亂碼問題有其他修正方式嗎?
還是一定要再透過JsonConvert.DeserializerObject(string)做轉換?

水無痕 iT邦新手 3 級 ‧ 2022-08-31 18:11:09 檢舉
我的目標是再將這些資訊傳到另一支程式將Json字串轉為字串。

那我建議你直接 by pass 用原本的 stream 傳給另一支程式 !
你的程式就不用轉成 string / object !
讓另一支程式要去 反序列化 response body 就好 !

edwang iT邦新手 4 級 ‧ 2022-09-07 17:05:20 檢舉

感謝水無痕
我直接傳給下一支程式測試過可行~

1
I code so I am
iT邦高手 1 級 ‧ 2022-08-30 09:00:53

寫一個表單程式,測試OK。

        private async void buttonRun_Click(object sender, EventArgs e)
        {
            var Result = await GetHtml();
            richTextBoxResponse.Text = Result;
        }

        private async Task<string> GetHtml()
        {
            string html = "";
            using (var client = new HttpClient())
            {
                var response = await client.GetAsync(textBoxURL.Text);
                response.EnsureSuccessStatusCode();
                response.Content.Headers.ContentType.CharSet = "utf-8";
                html = await response.Content.ReadAsStringAsync();
            }
            return html;
        }
看更多先前的回應...收起先前的回應...
edwang iT邦新手 4 級 ‧ 2022-08-31 08:13:34 檢舉

感謝I code so I am回覆:
已嘗試使用以下方做轉換
response.Content.Headers.ContentType.CharSet = "utf-8";
但回傳的結果還是亂碼,
比較好奇的是我前面Console端httpcontent的部分,

 HttpContent contentPost = new StringContent(json, Encoding.UTF8, "application/json");

已設定使用Encoding.UTF8 為什麼還是不能成功轉換中文字呢?

使用ReadAsStringAsync接收response,會自動依據預設編碼轉成字串,這時候再 encode 已經無效了。

edwang iT邦新手 4 級 ‧ 2022-08-31 10:30:13 檢舉

但我試了I Code大的方法,還是一樣跳出亂碼
想請問有其他解決方法嗎?

HttpContent contentPost = new StringContent(json, Encoding.UTF8, "application/json");

HttpResponseMessage response = await httpClient.httpClientInstance.PostAsync(uriBase, contentPost);

//依照I Code 大的方法設定ContentType
response.Content.Headers.ContentType.CharSet = "utf-8";

//這邊取得結果還是亂碼
string finalRes = response.Content.ReadAsStringAsync().Result;

我測試無誤的專案如下:
https://github.com/mc6666/CS_HttpClient

edwang iT邦新手 4 級 ‧ 2022-09-07 17:07:10 檢舉

感謝I code so I am大,
測試專案可行,但目前還是採用PostAsync方法實作

我要發表回答

立即登入回答