2013-03-05 57 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