若要确保将来更轻松地将新的 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(这是默认配置),则无法将其迁移到原始地址上的单个 WCF 终结点,该终结点肯定会与所有 ASP.NET Web 服务的现有客户端兼容。 此外,选择 SOAP 1.2 而不是 1.1 将更严重地限制服务的客户端。
服务开发
WCF 允许您定义服务协定,可以通过将 ServiceContractAttribute 应用于接口或类来实现。 建议将特性应用于接口而不是类,因为这样做会创建一个协定的定义,该协定可以由任意数量的类实现。 ASP.NET 2.0 支持将属性应用于 WebService 接口和类的选项。 但是,如前所述,ASP.NET 2.0 中存在缺陷,当该属性应用于接口而不是类时,该属性的 WebService Namespace 参数不起作用。 由于通常建议通过使用http://tempuri.org
特性的Namespace参数修改服务的命名空间(从默认值WebService开始),因此应该通过将ServiceContractAttribute属性应用于接口或类来继续定义ASP.NET Web服务。
在定义这些接口的方法中,代码尽可能少。 允许它们将其工作委托给其他类。 然后,新的 WCF 服务类型还可以将其实质性工作委托给这些类。
使用
MessageName
的 WebMethodAttribute 参数为服务的操作提供显式名称。[WebMethod(MessageName="ExplicitName")] string Echo(string input);
这样做很重要,因为 ASP.NET 中操作的默认名称不同于 WCF 提供的默认名称。 通过提供显式名称,可以避免依赖默认名称。
不要使用多态方法实现 ASP.NET Web 服务作,因为 WCF 不支持使用多态方法实现作。
使用 SoapDocumentMethodAttribute 为“SOAPAction HTTP 标头”提供显式值,以便将 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 服务支持使用 Internet Information Services (IIS)的 ACL,WCF 不这样做,因为 ASP.NET Web 服务依赖于 IIS 进行托管,WCF 不一定必须托管在 IIS 中。
请考虑使用 ASP.NET 2.0 角色提供程序来授权访问服务的资源。