WebService一般都是走HTTP, 一般通过HttpModule拦截就可以。但是要自行编码解码,很难得到详细信息。而且WebMethod抛出的Exception被包装过,不能象普通页面一样通过Context.Error直接拿到它的错误。
WebService没有直接继承CBO,要想实现AOP性质的WebMethod拦截和处理,可以通过SoapExtension(Soap扩展)
Soap扩展要继承SoapExtension类,使用方式有两种:
1. 使用SoapExtensionAttribute在WebMethod前为每个方法定制标记。
2. 在Web.xml中统一标记。
<system.web>
<webServices>
<soapExtensionTypes>
<add type = "Utility.LogExtension,Utility" priority="1" group="0"/>
</soapExtensionTypes>
</webServices>
</system.web>
一个WebMethod中,SoapExtension.ProcessMessage()方法会被多次调用。从而得到在方法执行前后的参数,返回结果,异常。
通过拦截WebMethod, Log/Trace/Transaction控制都可以自动完成。不需要不停的try/catch了!
下面是[LogExtension]的部分:
public override void ProcessMessage(SoapMessage message)
{
switch (message.Stage)
{
case SoapMessageStage.BeforeSerialize: //can get return value
if(message.Exception == null && message.MethodInfo.ReturnType != typeof(void))
outValue = Convert.ToString(message.GetReturnValue());
break;
case SoapMessageStage.AfterSerialize: //the last step
if (message.Exception == null)
Log.Info(GetLog(message));
else
Log.Warning(GetLog(message));
break;
case SoapMessageStage.BeforeDeserialize:
break;
case SoapMessageStage.AfterDeserialize://can get parameters
int n = message.MethodInfo.Parameters.Length;
inParams = new string[n];
for(int i = 0;i<n;i++)
inParams[i] = Convert.ToString(message.GetInParameterValue(i));
break;
default:
throw new Exception("invalid stage");
}
}
下面是[TransExtension]事务控制的部分:
public override void ProcessMessage(SoapMessage message)
{
switch (message.Stage)
{
case SoapMessageStage.BeforeSerialize: //step 3. can get return value
if(message.Exception == null)
DbHelper.Inst.Commit();
else
DbHelper.Inst.Rollback();
DbHelper.Inst.Close();
break;
case SoapMessageStage.AfterSerialize: //step 4
case SoapMessageStage.BeforeDeserialize://step 1
break;
case SoapMessageStage.AfterDeserialize://step 2. can get parameters
DbHelper.Inst.BeginTransaction();
break;
default:
throw new Exception("invalid stage");
}
}
WebService没有直接继承CBO,要想实现AOP性质的WebMethod拦截和处理,可以通过SoapExtension(Soap扩展)
Soap扩展要继承SoapExtension类,使用方式有两种:
1. 使用SoapExtensionAttribute在WebMethod前为每个方法定制标记。
2. 在Web.xml中统一标记。
<system.web>
<webServices>
<soapExtensionTypes>
<add type = "Utility.LogExtension,Utility" priority="1" group="0"/>
</soapExtensionTypes>
</webServices>
</system.web>
一个WebMethod中,SoapExtension.ProcessMessage()方法会被多次调用。从而得到在方法执行前后的参数,返回结果,异常。
通过拦截WebMethod, Log/Trace/Transaction控制都可以自动完成。不需要不停的try/catch了!
下面是[LogExtension]的部分:
public override void ProcessMessage(SoapMessage message)
{
switch (message.Stage)
{
case SoapMessageStage.BeforeSerialize: //can get return value
if(message.Exception == null && message.MethodInfo.ReturnType != typeof(void))
outValue = Convert.ToString(message.GetReturnValue());
break;
case SoapMessageStage.AfterSerialize: //the last step
if (message.Exception == null)
Log.Info(GetLog(message));
else
Log.Warning(GetLog(message));
break;
case SoapMessageStage.BeforeDeserialize:
break;
case SoapMessageStage.AfterDeserialize://can get parameters
int n = message.MethodInfo.Parameters.Length;
inParams = new string[n];
for(int i = 0;i<n;i++)
inParams[i] = Convert.ToString(message.GetInParameterValue(i));
break;
default:
throw new Exception("invalid stage");
}
}
下面是[TransExtension]事务控制的部分:
public override void ProcessMessage(SoapMessage message)
{
switch (message.Stage)
{
case SoapMessageStage.BeforeSerialize: //step 3. can get return value
if(message.Exception == null)
DbHelper.Inst.Commit();
else
DbHelper.Inst.Rollback();
DbHelper.Inst.Close();
break;
case SoapMessageStage.AfterSerialize: //step 4
case SoapMessageStage.BeforeDeserialize://step 1
break;
case SoapMessageStage.AfterDeserialize://step 2. can get parameters
DbHelper.Inst.BeginTransaction();
break;
default:
throw new Exception("invalid stage");
}
}