WSDL 不支援方法多載,直接在服務合約定義同名不同參數的作業會導致宿主啟動拋出 InvalidOperationException。WCF 提供 OperationContract.Name 屬性指定唯一作業名稱,實現邏輯多載。
[ServiceContract(Namespace = "https://ns")]
public interface IOverloadService
{
[OperationContract(Name = "SayHello1")]
string SayHello();
[OperationContract(Name = "SayHello2")]
string SayHello(string name);
[OperationContract(Name = "SayHello3")]
string SayHello(string firstName, string lastName);
}
public class OverloadService : IOverloadService
{
public string SayHello() => "Hello! (無參數)";
public string SayHello(string name) => $"Hello, {name}!";
public string SayHello(string first, string last) => $"Hello, {first} {last}!";
}
WSDL 將公開三個不同名稱的作業:SayHello1、SayHello2、SayHello3。
Visual Studio / svcutil 產生的 Proxy 會直接以 WSDL 作業名稱作為方法名:
public string SayHello1() { ... }
public string SayHello2(string name) { ... }
public string SayHello3(string first, string last) { ... }
失去 C# 編譯期多載優勢:呼叫端需記住不同方法名,無法享受 IntelliSense 多載提示。
修改產生的 Proxy 介面與類別,將方法重命名為同名 SayHello,保留 OperationContractAttribute 的 Name、Action、ReplyAction:
[ServiceContract]
public interface IOverloadService
{
[OperationContract(Name = "SayHello1", Action = ".../SayHello1", ReplyAction = ".../SayHello1Response")]
string SayHello();
[OperationContract(Name = "SayHello2", Action = ".../SayHello2", ReplyAction = ".../SayHello2Response")]
string SayHello(string name);
[OperationContract(Name = "SayHello3", Action = ".../SayHello3", ReplyAction = ".../SayHello3Response")]
string SayHello(string first, string last);
}
Proxy 類別同步修改方法名稱,內部仍呼叫 base.Channel.SayHello1() 等對應作業。此後客戶端可正常多載呼叫:proxy.SayHello()、proxy.SayHello("Tom")、proxy.SayHello("Tom", "Jerry")。
Action/ReplyAction 需與服務端一致,否則訊息路由失敗。WCF 透過 OperationContract.Name 解決 WSDL 不支援多載的限制。伺服端實作直觀,但客戶端 Proxy 預設扁平化,需手動調整或採用共用合約組件才能保留 C# 多載語法糖。權衡維護成本與易用性,建議優先考慮 DTO 參數合併方案。