雖然現代多用 WCF / Web API / gRPC,但維護舊系統時仍常需呼叫傳統 ASMX Web Service。若不想引入 Service Reference 產生的 Proxy 類別,可直接用 HttpWebRequest 手工發送 SOAP 訊息。本文示範完整流程:載入 XML 請求檔、設定 HTTP Header (SOAPAction)、發送並接收回應。
https://localhost/websrv/dsmp.asmxSyncOrderRelation (CMPP 3.0 訂購關係同步)
00110318384464
1.5.0
SyncOrderRelationReq
0
0011
400
0
1
13456781234
1
13456781234
SP
1
1
419000
-YYXXYYXX
3
MTA2NjIxNDQgREE=
using System;
using System.IO;
using System.Net;
using System.Xml;
public class AsmxCaller
{
public XmlDocument CallSyncOrderRelation(string requestXmlPath, string serviceUrl)
{
// 1. 載入請求 XML
var requestDoc = new XmlDocument();
requestDoc.Load(requestXmlPath);
// 2. 序列化到 MemoryStream 取得位元組陣列
using var ms = new MemoryStream();
requestDoc.Save(ms);
byte[] payload = ms.ToArray();
// 3. 建立 HttpWebRequest
var request = (HttpWebRequest)WebRequest.Create(serviceUrl);
request.Method = "POST";
request.ContentType = "text/xml; charset=utf-8";
request.Headers.Add("SOAPAction", "\"sim.SyncOrderRelation\""); // 必須雙引號包裹
request.Credentials = CredentialCache.DefaultCredentials; // 整合驗證
request.ContentLength = payload.Length;
request.Timeout = 30000; // 30 秒
request.ReadWriteTimeout = 30000;
// 4. 寫入請求流
using (var reqStream = request.GetRequestStream())
{
reqStream.Write(payload, 0, payload.Length);
}
// 5. 取得回應並解析
using var response = (HttpWebResponse)request.GetResponse();
using var respStream = response.GetResponseStream();
using var reader = new StreamReader(respStream, System.Text.Encoding.UTF8);
string responseXml = reader.ReadToEnd();
var responseDoc = new XmlDocument();
responseDoc.LoadXml(responseXml);
// 6. 可選:存檔留證
responseDoc.Save("SyncOrderRelationResp.xml");
return responseDoc;
}
}
| 項目 | 說明 |
|---|---|
| SOAPAction Header | ASMX 必須,格式通常為 "Namespace.MethodName",需雙引號包裹。可從 .asmx?wsdl 或抓包確認。 |
| Content-Type | SOAP 1.1 固定 text/xml; charset=utf-8;SOAP 1.2 應為 application/soap+xml。 |
| 編碼 | 請求 XML 宣告 encoding="utf-8",寫入流與讀取回應皆指定 UTF-8,避免中文亂碼。 |
| 例外處理 | 網路錯誤拋 WebException,需檢查 ex.Response 讀取 SOAP Fault 細節。 |
| 大量資料 | 請求/回應超過預設限制需設定 request.MaximumResponseHeadersLength、HttpWebRequest.GetRequestStream() 分塊寫入。 |
HttpClient.PostAsync + StringContent,支援 async/await、連線池、更易測試。ChannelFactory<T> 動態建立 Proxy,不需專案加入 Service Reference。
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("SOAPAction", "\"sim.SyncOrderRelation\"");
var content = new StringContent(File.ReadAllText(requestXmlPath), Encoding.UTF8, "text/xml");
var response = await client.PostAsync(serviceUrl, content);
string responseXml = await response.Content.ReadAsStringAsync();