預計採用 Windows Communication Foundation:簡化未來移轉
為確保未來 ASP.NET 新應用程式更容易移轉至 WCF,請遵循上述建議和下列建議。
通訊協定
停用 ASP.NET 2.0 的 SOAP 1.2 支援:
<configuration>
<system.web>
<webServices >
<protocols>
<remove name="HttpSoap12"/>
</protocols>
</webServices>
</system.web>
</configuration>
建議這樣做,因為 WCF 需要透過使用不同端點,以讓訊息符合不同通訊協定 (如 SOAP 1.1 和 SOAP 1.2)。 如果 ASP.NET 2.0 Web 服務設定為同時支援 SOAP 1.1 和 SOAP 1.2 (預設設定),則無法向前移轉至原始位址上,一定會與 ASP.NET Web 服務所有現有用戶端相容的單一 WCF 端點。 此外,選擇 SOAP 1.2 而非 1.1,也會嚴重限制服務的用戶端群。
服務開發
WCF 可藉由將 ServiceContractAttribute 套用至介面或類別,來定義服務合約。 建議將此屬性套用至介面而非類別,因為這樣做會建立可由任意類別數目以各種方式實作的合約定義。 ASP.NET 2.0 支援將 WebService 屬性套用至介面和類別。 不過,如上述,ASP.NET 2.0 中有缺失,當 WebService 屬性套用至介面而非類別時,該屬性的 Namespace 參數會沒有作用。 因為一般建議修改服務的命名空間預設值 http://tempuri.org
,所以應該可以繼續使用 WebService 屬性的 Namespace 參數,將 ServiceContractAttribute 屬性套用至介面或類別,來定義 ASP.NET Web 服務。
在定義這些介面的方法中,盡可能不使用程式碼。 將它們的工作委派至其他類別。 然後,新的 WCF 服務型別也可以將它們的實質性工作委派至這些類別。
使用
MessageName
的 WebMethodAttribute 參數,為服務的作業提供明確名稱。[WebMethod(MessageName="ExplicitName")] string Echo(string input);
這樣做很重要,因為 ASP.NET 中作業的預設名稱與 WCF 所提供的預設名稱不同。 藉由提供明確名稱,可以避免依賴預設名稱。
不要實作使用多型方法的 ASP.NET Web 服務作業,因為 WCF 不支援使用多型方法的作業。
使用 SoapDocumentMethodAttribute,為用來將 HTTP 要求傳送至方法的 SOAPAction HTTP 標頭,提供明確值。
[WebMethod] [SoapDocumentMethod(RequestElementName="ExplicitAction")] string Echo(string input);
採用這個方法,會避免依賴 ASP.NET 和WCF 使用 SOAPAction 預設值。
避免使用 SOAP 擴充功能。 如果需要 SOAP 擴充功能,請判斷其用途是否為 WCF 已提供的功能。 如果是這種情況,請重新考慮不立即採用 WCF 的選項。
狀態管理
避免在服務中維護狀態。 維護狀態不僅容易損害應用程式的延展性,而且 ASP.NET 和 WCF 的狀態管理機制也非常不同,儘管 WCF 支援 ASP.NET 相容性模式中的 ASP.NET 機制。
例外狀況處理
在設計服務所傳送和接收資料型別的結構時,也請設計各種例外狀況類型的結構,這些是您希望向用戶端告知可能會在服務中發生的例外狀況。
[Serializable]
[XmlRoot(Namespace="ExplicitNamespace", IsNullable=true)]
public partial class AnticipatedException
{
private string anticipatedExceptionInformationField;
public string AnticipatedExceptionInformation
{
get {
return this.anticipatedExceptionInformationField;
}
set {
this.anticipatedExceptionInformationField = value;
}
}
}
提供這些類別自我序列化為 XML 的能力:
public XmlNode ToXML()
{
XmlSerializer serializer = new XmlSerializer(
typeof(AnticipatedException));
MemoryStream memoryStream = new MemoryStream();
XmlTextWriter writer = new XmlTextWriter(
memoryStream, UnicodeEncoding.UTF8);
serializer.Serialize(writer, this);
XmlDocument document = new XmlDocument();
document.LoadXml(new string(
UnicodeEncoding.UTF8.GetChars(
memoryStream.GetBuffer())).Trim());
return document.DocumentElement;
}
然後,類別就可以用來為明確擲回的 SoapException 執行個體提供詳細資料:
AnticipatedException exception = new AnticipatedException();
exception.AnticipatedExceptionInformation = "…";
throw new SoapException(
"Fault occurred",
SoapException.ClientFaultCode,
Context.Request.Url.AbsoluteUri,
exception.ToXML());
這些例外狀況類別隨時可由 WCF FaultException<TDetail> 類別重複使用,以擲回新的 FaultException<AnticipatedException>(anticipatedException);
安全性
以下是一些安全性考量事項:
避免使用 ASP.NET 2.0 設定檔,因為服務移轉至 WCF 時,使用它們會限制使用 ASP.NET 整合模式。
避免使用 ACL 控制存取服務,因為 ASP.NET Web 服務支援 ACL 使用 Internet Information Services (IIS),但 WCF 卻不支援 (ASP.NET Web 服務仰賴 IIS 進行裝載,而 WCF 不一定要裝載於 IIS)。
考慮使用 ASP.NET 2.0 角色提供者,來授權存取服務資源。