2013-03-05 26 views
1

我有一个SoapExtension。它记录我所有的web服务请求和响应。我认为项目中有超过一千个webservice调用。我的问题是我无法登录请求,如果我的web服务调用结束超时或httpexceptions如403,404。我也需要记录这些例外情况。如何处理SoapExtension中的超时异常

这是我的SoapExtension

public class SoapLogger : SoapExtension 
{ 
    Stream orgStream; 
    Stream newStream; 
    LogItem logItem; 

    // When the SOAP extension is accessed for the first time, the XML Web 
    // service method it is applied to is accessed to store the file 
    // name passed in, using the corresponding SoapExtensionAttribute.  
    public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute) 
    { 
     return 0; 
    } 

    // The SOAP extension was configured to run using a configuration file 
    // instead of an attribute applied to a specific XML Web service 
    // method. 
    public override object GetInitializer(Type WebServiceType) 
    { 
     return 0; 
    } 

    // Receive the file name stored by GetInitializer and store it in a 
    // member variable for this specific instance. 
    public override void Initialize(object initializer) 
    { 
     logItem = new LogItem(); 
    } 

    // Save the Stream representing the SOAP request or SOAP response into 
    // a local memory buffer. 
    public override Stream ChainStream(Stream stream) 
    { 
     orgStream = stream; 
     newStream = new MemoryStream(); 
     return newStream; 
    } 

    // If the SoapMessageStage is such that the SoapRequest or 
    // SoapResponse is still in the SOAP format to be sent or received, 
    // save it out to a file. 
    public override void ProcessMessage(SoapMessage message) 
    { 
     switch (message.Stage) 
     { 
      case SoapMessageStage.BeforeSerialize: 
       break; 
      case SoapMessageStage.AfterSerialize: 
       WriteOutput(); 
       break; 
      case SoapMessageStage.BeforeDeserialize: 
       WriteInput(message); 
       break; 
      case SoapMessageStage.AfterDeserialize: 
       CheckException(message); 
       break; 
      default: 
       throw new Exception("invalid soap stage"); 
     } 
    } 

    public void CheckException(SoapMessage message) 
    { 

     logItem.WebClassName = message.MethodInfo.DeclaringType.FullName; 
     logItem.WebMethodName = message.MethodInfo.Name; 

     MethodBase method = FindMethod(logItem.WebMethodName); 

     logItem.MethodName = method != null ? method.Name : ""; 
     logItem.ClassName = method != null ? method.DeclaringType.Name : ""; 

     logItem.Exception = message.Exception != null ? message.Exception.Message : ""; 

     LogToDB(logItem); 
    } 

    MethodBase FindMethod(string webMethodName) 
    { 
     try 
     { 
      StackFrame[] stackFrames = new StackTrace().GetFrames(); 

      int i; 
      for (i = 0; i < stackFrames.Length; i++) 
      { 
       if (stackFrames[i].GetMethod().Name == webMethodName) break; 
      } 
      return i < stackFrames.Length - 1 ? stackFrames[i + 1].GetMethod() : null; 
     } 
     catch 
     { 
      return null; 
     } 
    } 

    void LogToDB(LogItem logItem) 
    { 
     // I am logging logItem to db 
    } 

    public void WriteOutput() 
    { 
     newStream.Position = 0; 

     logItem.Request = CopyString(newStream); 
     logItem.StartTime = DateTime.Now; 

     newStream.Position = 0; 
     Copy(newStream, orgStream); 
     newStream.Position = 0; 
    } 

    public void WriteInput(SoapMessage message) 
    { 
     Copy(orgStream, newStream); 
     newStream.Position = 0; 

     logItem.Response = CopyString(newStream); 
     logItem.EndTime = DateTime.Now; 

     newStream.Position = 0; 
    } 

    void Copy(Stream from, Stream to) 
    { 
     TextReader reader = new StreamReader(from); 
     TextWriter writer = new StreamWriter(to); 
     writer.WriteLine(reader.ReadToEnd()); 
     writer.Flush(); 
    } 

    string CopyString(Stream from) 
    { 
     TextReader reader = new StreamReader(from); 
     return reader.ReadToEnd(); 
    } 

} 
+0

ASMX是一种过时的技术,并且不应该被用于新的开发WCF应该用于Web服务客户端和服务器的所有新开发。一个提示:微软已经退役了[ASMX Forum](http://social.msdn.microsoft.com/Forums/en-US/asmxandxml/threads)在其他方面,WCF给你一个比ASMX更好的日志记录故事。 – 2013-03-05 14:49:52

回答

-2

下面的文本可能会帮助您解决您的问题。

“的解决方案的SoapExtension

最流行的方法来解决这个问题(我已经发现迄今)是编写一个自定义的SoapExtension子类,其中privodes你到的SOAPMessage在不同的低级别的访问当发生未处理的异常时,SoapException可以在响应SoapMessage中被捕获(通过Exception属性),然后SoapException的InnerException属性包含实际的未处理的异常,此时你可以在日志中记录例外,所以当你从技术支持部门得到这封电子邮件时,你有一些事情要继续。

但是,如果你曾经开发过一个真正的面向公众的Web服务(就像我们的),你很快就会同意,仅仅记录异常是不够的。通常情况下,您需要更多地控制SoapException本身的内容并将其发送回调用方。 SoapExtension子类方法使您能够修改SoapException,但处于非常低的级别。具体来说,它已经被反序列化为其代表性的SOAP错误XML,并且您必须执行一些奇特的流操作以将任何自定义内容插入该错误(例如:添加细节元素)。在我看来,这是一个黑客而不是一个非常优雅的解决方案。相反,我们应该在抛出之前对SoapException进行更多的控制。理想情况下,如果我们可以自己创建并抛出SoapException,那么我们可以更有效地控制SOAP错误的结果(如错误代码和细节)。然后,我们就不会有拦截和操纵原始SOAP消息本身打扰“

请访问链接了解更多信息: http://beyondthispoint.blogspot.co.uk/2008/04/managing-unhandled-exceptions-in-aspnet.html

+0

这个链接也可以帮助你:http://stackoverflow.com/questions/2180228/handle-exceptions-in-web-services-with -elmah – 2013-03-05 14:38:10

+0

-1:我不明白如何回答问题 – 2013-03-05 14:49:08

+0

-1:这不是我正在寻找的。 – 2013-03-05 16:03:50