using System; using System.Web.Services; using System.Web.Services.Protocols; using System.IO; namespace SunLibrary.Web { /* **********服务器端配置********** 在WebService项目中,增加Soap扩展有两种方式,web.config配置或WebMethod配置(推荐使用WebMethod方式只扩展必要的接口) 1.web.config配置将对所有WebMethod发生作用。!!但是,无法配置Attribute的自定义属性!! 方法:增加SunLibrary.dll程序集作为引用,并且在web.config加入如下声明 <?xml version="1.0" encoding="utf-8" ?> <configuration> <system.web> ... <webServices> <soapExtensionTypes> <add type="SunLibrary.Web.SunSoapExtension,SunLibrary" priority="1" group="0"/> </soapExtensionTypes> </webServices> ... </system.web> </configuration> 2.WebMethod配置将对单独的WebMethod发生作用 方法:在WebMethod定义前加上如下属性 [SunLibrary.Web.SunSoapExtensionAttribute(ZipOutput=false,UnzipInput=false)] **********客户端配置********** 在引用WebService的项目中,增加Soap扩展,方法如下: 增加SunLibrary.dll程序集作为引用,编辑该引用的Reference.cs文件,为代理类的每个函数增加属性: [SunLibrary.Web.SunSoapExtensionAttribute(ZipOutput=false,UnzipInput=false)] **********补充说明********** 支持Soap压缩和其他特性,通过配置Attribute属性使其中的一个或多个属性生效,服务器端和客户端要成套搭配 */ /// <summary> /// Soap扩展的配置参数 /// </summary> public struct SunSoapExtensionConfig { public bool zipOutput; public bool unzipInput; } /// <summary> /// 提供Soap扩展的框架,派生类只需重载BeforeDeserialize/AfterDeserialize/BeforeSerialize/AfterSerialize函数完成特定处理 /// </summary> public class SunSoapExtension : SoapExtension { #region 构造函数 public SunSoapExtension() { } #endregion #region 成员变量 /// <summary> /// 定义输入输出流 /// </summary> protected Stream networkStream,newStream; /// <summary> /// 保存配置属性 /// </summary> protected SunSoapExtensionConfig config; #endregion #region 重载函数 public override Stream ChainStream( Stream stream ) { networkStream = stream; newStream = new MemoryStream(); return newStream; } public override object GetInitializer(LogicalMethodInfo methodInfo,SoapExtensionAttribute attribute) { return ((SunSoapExtensionAttribute)attribute).Config; } public override object GetInitializer(Type WebServiceType) { return config; } public override void Initialize(object initializer) { config = (SunSoapExtensionConfig)initializer; } public override void ProcessMessage(SoapMessage message) { switch (message.Stage) { case SoapMessageStage.BeforeSerialize: BeforeSerialize( message ); break; case SoapMessageStage.AfterSerialize: AfterSerialize( message ); break; case SoapMessageStage.BeforeDeserialize: BeforeDeserialize( message ); break; case SoapMessageStage.AfterDeserialize: AfterDeserialize( message ); break; default: throw new Exception("invalid stage"); } } #endregion #region 需要派生类重载的虚函数(响应消息) public virtual void BeforeSerialize(SoapMessage message) { } public virtual void AfterSerialize(SoapMessage message) { newStream.Position = 0; if (config.zipOutput) api.GZipCompress(newStream,networkStream); else api.StreamCopy(newStream, networkStream); } public virtual void BeforeDeserialize(SoapMessage message) { if (config.unzipInput) api.GZipDeCompress(networkStream,newStream); else api.StreamCopy(networkStream, newStream); newStream.Position = 0; } public virtual void AfterDeserialize(SoapMessage message) { } #endregion } /// <summary> /// Soap扩展的属性 /// </summary> [AttributeUsage(AttributeTargets.Method)] public class SunSoapExtensionAttribute : SoapExtensionAttribute { private int priority = 1; private SunSoapExtensionConfig config; public override Type ExtensionType { get { return typeof(SunSoapExtension); } } public override int Priority { get { return priority; } set { priority = value; } } public bool ZipOutput { get { return config.zipOutput; } set { config.zipOutput = value; } } public bool UnzipInput { get { return config.unzipInput; } set { config.unzipInput = value; } } public SunSoapExtensionConfig Config { get { return config; } } } }