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; }
}
}
}