ASP.NET Web Service (ASMX) 是早期 .NET 實現 SOAP 服務的技術,雖已被 WCF/Web API/gRPC 取代,但維護舊系統時仍需掌握。本文演示創建簡單算術服務並由客戶端調用。
Visual Studio:右鍵專案 → Add → New Item → Web Service (ASMX) → 命名 Calculator.asmx
// Calculator.asmx.cs
using System.Web.Services;
[WebService(Namespace = "https://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class Calculator : System.Web.Services.WebService
{
[WebMethod(Description = "加法運算")]
public double Add(double a, double b) => a + b;
[WebMethod(Description = "減法運算")]
public double Subtract(double a, double b) => a - b;
[WebMethod(Description = "乘法運算")]
public double Multiply(double a, double b) => a * b;
[WebMethod(Description = "除法運算")]
public double Divide(double a, double b) {
if (b == 0) throw new ArgumentException("除數不能為零");
return a / b;
}
}
按 F5 運行,瀏覽器打開 https://localhost:port/Calculator.asmx,點擊方法名可測試調用,查看 SOAP 請求/回應格式。
// 1. 右鍵 References → Add Service Reference → Advanced → Add Web Reference
// 2. 輸入服務 URL → 命名空間 CalculatorService
// 3. 調用代碼
using ClientApp.CalculatorService;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
CalculatorSoapClient client = new CalculatorSoapClient();
double result = client.Add(3, 4); // 同步調用
TextBox1.Text = result.ToString(); // 顯示 7
}
}
// 添加服務引用 → 命名空間 CalculatorRef
using ClientApp.CalculatorRef;
public async Task CallAsync() {
CalculatorSoapClient client = new CalculatorSoapClient(CalculatorSoapClient.EndpointConfiguration.BasicHttpBinding_ICalculatorSoap);
double result = await client.AddAsync(10, 5); // 異步調用
// 處理結果...
}
public async Task CallAddAsync(double a, double b) {
string soapEnvelope = $@"
{a}
{b}
";
using (var client = new HttpClient()) {
client.DefaultRequestHeaders.Add("SOAPAction", "\"https://tempuri.org/Add\"");
var content = new StringContent(soapEnvelope, Encoding.UTF8, "text/xml");
var response = await client.PostAsync("https://localhost:port/Calculator.asmx", content);
string responseXml = await response.Content.ReadAsStringAsync();
// 解析 XML 獲取結果 (可用 XmlDocument, XDocument, 或正則)
XDocument doc = XDocument.Parse(responseXml);
XNamespace ns = "https://tempuri.org/";
return double.Parse(doc.Descendants(ns + "AddResult").First().Value);
}
}
| 問題 | 解決 |
|---|---|
| 跨域調用失敗 | Web.config 添加 <httpProtocol><customHeaders><add name="Access-Control-Allow-Origin" value="*" /></customHeaders></httpProtocol> |
| 最大接收訊息大小超限 | Web.config <binding maxReceivedMessageSize="2147483647"> |
| 序列化循環引用 | 實體類標記 [DataContract(IsReference=true)]、屬性 [DataMember] |
| 部署 IIS 驗證錯誤 | 啟用匿名驗證、應用程序池 .NET CLR 版本正確 |
遷移建議:新專案直接上 ASP.NET Core Web API;舊 ASMX 系統可逐步用 SoapCore 中間件在 Core 上承載,或建立 API Gateway 轉發。