2013-03-05 4 views
1

SoapExtension이 있습니다. 내 모든 웹 서비스 요청 및 응답을 기록합니다. 나는 프로젝트에서 1000 개가 넘는 웹 서비스 호출이 있다고 생각한다. 내 웹 서비스 호출이 403, 404 같은 시간 초과 또는 httpexceptions로 끝나는 경우 내 문제는 내가 로그 요청을 못할 수 있습니다. 이러한 종류의 예외도 기록해야합니다. 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가 사용되어야 함 힌트 : Microsoft는 [ASMX 포럼] (http://social.msdn.microsoft.com/Forums/en-US/asmxandxml/threads) MSDN에서 WCF는 ASMX보다 로깅 스토리를 더 잘 제공합니다. –

답변

-2

입니다 다음 텍스트는 당신이 당신의 문제를 해결하는 데 도움이 될 수 있습니다.

는 "SoapExtension 솔루션

(내가 지금까지 발견 한 것을)이 문제를 해결하는 가장 인기있는 방법은 당신에게 다른에서 SOAPMessage 메세지에 대한 낮은 레벨의 액세스를 privodes하는 사용자 정의 SoapExtension 서브 클래스를 코딩하는 것입니다

무 처리 예외가 발생하면 SoapException을 SoapMessage (Exception 속성을 통해)에 캡처 할 수 있으며 SoapException의 InnerException 속성에는 처리되지 않은 실제 예외가 포함되어 있습니다. 예외적으로 예외가 발생하지 않도록 기술 지원 부서에서 보낸 이메일을 받으면 계속할 항목이 있습니다.

그러나 실제 공개 웹 서비스 (우리와 마찬가지로)를 개발 한 적이 있다면 간단히 예외를 기록하는 것만으로는 충분하지 않다는 것에 빨리 동의하게됩니다. 종종 호출자에게 다시 보내지는 SoapException 자체의 내용을 좀 더 제어하기를 원할 때가 있습니다. SoapExtension 서브 클래스 접근법은 SoapException을 수정할 수있는 능력을 제공하지만 매우 낮은 수준입니다. 특히, 대표적인 SOAP 오류 XML로 이미 deserialize되어 있으며 사용자 정의 컨텐츠를 해당 오류에 삽입하기 위해 멋진 스트림 조작을해야합니다 (예 : detail 요소 추가). 제 의견으로는, 이것은 해킹이며 매우 유쾌한 해결책은 아닙니다. 대신 Throw하기 전에 SoapException을보다 잘 제어해야합니다. 이상적으로 우리가 SoapException을 스스로 생성하여 던질 수 있다면, SOAP 코드를 생성하는 (오류 코드와 세부 사항과 같은) 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 –

+0

-1 : 질문에 대답하는 방법을 모르겠다. –

+0

-1 : 내가 검색 한 내용이 아닙니다. –