2016-10-04 7 views
2

私はIParameterInspectorを使用してウェブリクエストデータを記録しています。私は要求の期間を計算し、また入力と出力の内容を記録する必要があります。WCFサービスでIParameterInspectorを使用して、例外の場合でもWeb要求をログに記録する方法

例外が発生しない限り正常に動作します。例外の場合、AfterCallイベントは決して実行されません。

例外が発生したときにAfterCallを実行する機会はありますか?あるいは私はここに別のアプローチが必要ですか?

ここに私のコードの簡易版:

using System; 
using System.ServiceModel.Dispatcher; 

namespace WcfService1 
{ 
    public class LogOperationInspector : IParameterInspector 
    { 
     private string _serviceName; 

     public LogOperationInspector(string serviceName) 
     { 
      this._serviceName = serviceName; 
     } 

     public object BeforeCall(string operationName, object[] inputs) 
     { 
      return LogCallModel.GetLogModel("MyTestOperation", inputs); 
     } 

     public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState) 
     { 
      var callModel = correlationState as LogCallModel; 
      callModel.EndDate = DateTime.Now; 

      // Log Start Date and End Date and calculate duration 
     } 
    } 

    public class LogCallModel 
    { 
     public String OperationName { get; set; } 
     public DateTime StartDate { get; set; } 
     public DateTime EndDate { get; set; } 

     public static object GetLogModel(string operationName, object[] inputs) 
     { 
      var result = new LogCallModel(); 
      result.OperationName = operationName; 
      result.StartDate = DateTime.Now; 
      // Add some more properties for logging from the inputs field 

      return result; 
     } 
    } 
} 

答えて

1

私は成功した応答をAfterCallを使用しての標準のWCFのアプローチを使用することをお勧めします。例外の場合は、IErrorHandlerを実装し、その機能がエラー処理を担当するようにする必要があります。

public class LogOperationInspector : IParameterInspector 
{ 
    public object BeforeCall(string operationName, object[] inputs) 
    { 
     // Before Call 
    } 

    public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState) 
    { 
     // Sucessful response 
    } 
} 

public class LogErrorInspector : IErrorHandler 
{ 
    public void ProvideFault(Exception error, MessageVersion version, ref Message fault) 
    { 
     // Error Handling 
    } 

    public bool HandleError(Exception error) 
    { 
     // Error Handling 
    } 
} 

のみチャレンジ左はおそらく両方の可能なシナリオでBeforeCallの状態を共有したいということです。 AfterCallでは、通常CorrelationStateでこれを行うことができますが、ErrorHandlerではアクセスできません。これを可能にし、スレッドを安全に保つために、.NETメッセージ機能CallContextを使用することができます。この機能を使用することにより、の前に、ProvideFaultの間で要求コンテキストを共有することができます。

public class LogOperationInspector : IParameterInspector 
{ 
    public object BeforeCall(string operationName, object[] inputs) 
    { 
     CallContext.SetData("CallContext", CallObj); 
    } 

    public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState) 
    { 
     // Sucessful response 
    } 
} 

public class LogErrorInspector : IErrorHandler 
{ 
    public void ProvideFault(Exception error, MessageVersion version, ref Message fault) 
    { 
     var CallObj = CallContext.GetData("CallContext"); 
    } 

    public bool HandleError(Exception error) 
    { 
     // Error Handling 
    } 
} 
関連する問題