现在的位置: 首页 > 综合 > 正文

WebService的AOP & 简单事务控制

2011年03月04日 ⁄ 综合 ⁄ 共 2023字 ⁄ 字号 评论关闭
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");
   }
  }

抱歉!评论已关闭.