首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# HttpWebRequest POST 發送 XML 完整實作:編碼處理、串流寫入、回應讀取

     編輯:關於C#

核心實作:標準 POST XML

public string PostXml(string url, string xmlContent)
{
    if (string.IsNullOrEmpty(url)) throw new ArgumentException("URL 不可為空");
    if (string.IsNullOrEmpty(xmlContent)) throw new ArgumentException("XML 內容不可為空");

    byte[] buffer = Encoding.UTF8.GetBytes(xmlContent); // 必須與 XML 宣告 encoding 一致

    var request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "POST";
    request.ContentType = "text/xml; charset=utf-8"; // 關鍵:指定 charset
    request.ContentLength = buffer.Length;
    request.Timeout = 30000; // 30 秒
    request.ReadWriteTimeout = 30000;

    // 寫入請求串流
    using (var reqStream = request.GetRequestStream())
    {
        reqStream.Write(buffer, 0, buffer.Length);
    }

    // 讀取回應
    using (var response = (HttpWebResponse)request.GetResponse())
    using (var respStream = response.GetResponseStream())
    using (var reader = new StreamReader(respStream, Encoding.UTF8)) // 依回應實際編碼調整
    {
        return reader.ReadToEnd();
    }
}

編碼陷阱與解決

現象原因解決
中文亂碼請求/回應編碼不一致 (XML 宣告 utf-8,但 GetBytes 用 Unicode/Default)統一用 Encoding.UTF8,ContentType 加 charset=utf-8
伺服器回傳 415 Unsupported Media TypeContent-Type 錯誤確認 text/xml 或 application/xml,依 API 文件調整
大量資料 Timeout預設 100 秒可能不足設定 Timeout、ReadWriteTimeout,或分批傳送
Keep-Alive 導致連線耗盡預設 KeepAlive=true,高併發時連線池滿request.KeepAlive = false 或調大 ServicePointManager.DefaultConnectionLimit

進階版:支援自動偵測回應編碼、GZip 解壓、Cookie 容器

public string PostXmlAdvanced(string url, string xmlContent, CookieContainer cookies = null)
{
    byte[] buffer = Encoding.UTF8.GetBytes(xmlContent);

    var request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "POST";
    request.ContentType = "text/xml; charset=utf-8";
    request.ContentLength = buffer.Length;
    request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; // 自動解壓
    request.CookieContainer = cookies ?? new CookieContainer();
    request.KeepAlive = false; // 短連線,避免佔用

    using (var reqStream = request.GetRequestStream())
        reqStream.Write(buffer, 0, buffer.Length);

    using (var response = (HttpWebResponse)request.GetResponse())
    {
        // 依回應 Header 判斷編碼
        Encoding respEncoding = Encoding.UTF8;
        string contentType = response.ContentType;
        if (!string.IsNullOrEmpty(contentType))
        {
            var match = Regex.Match(contentType, @"charset\s*=\s*([\w-]+)", RegexOptions.IgnoreCase);
            if (match.Success)
            {
                try { respEncoding = Encoding.GetEncoding(match.Groups[1].Value); }
                catch { /* fallback UTF-8 */ }
            }
        }

        using (var respStream = response.GetResponseStream())
        using (var reader = new StreamReader(respStream, respEncoding))
            return reader.ReadToEnd();
    }
}

同步 vs 非同步 (現代 .NET 建議)


// .NET 4.5+ / .NET Core 使用 HttpClient (推薦)
private static readonly HttpClient _httpClient = new HttpClient();

public async Task PostXmlAsync(string url, string xmlContent)
{
    var content = new StringContent(xmlContent, Encoding.UTF8, "text/xml");
    var response = await _httpClient.PostAsync(url, content);
    response.EnsureSuccessStatusCode();
    return await response.Content.ReadAsStringAsync();
}

HttpClient 優點: 非同步原生、連線池自動管理、支援 `await`、可攜性佳。舊專案維護才用 `HttpWebRequest`。

背景說明

原文提到發送 UTF-8 XML 時,使用 `Encoding.Unicode`/`Default`/`ASCII` 皆失敗,改用 `UTF8` 成功。並提供完整流程說明:建立 HttpWebRequest → 設定 Header/ContentType → 寫入 RequestStream → 取得 Response → 讀取 ResponseStream。

參考資源

原文連結:https://www.bianceng.cn/Programming/csharp/201410/45576.htm

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved