Whi*_*uit 3 .net error-handling wcf
我已经使用 IErrorHandler 实现了一些基本的 WCF 错误处理,我可以在其中获取堆栈跟踪并记录它,但是我还想从导致异常的类中记录一些其他信息。
例如,假设我的服务中有以下课程:
Class Foo
Public User As String
Public PhoneNumber As String
Public Function Bar() As Boolean
Dim c As Collection 'intentionally not set to an object to cause an error below
c.Add(PhoneNumber)
Return True
End Function
End Class
Run Code Online (Sandbox Code Playgroud)
我发现了以下错误:
Public Function HandleError(ByVal [error] As System.Exception) As Boolean Implements ystem.ServiceModel.Dispatcher.IErrorHandler.HandleError
'Log ex.tostring to event log
'How can I access User and PhoneNumber?
Return False
End Function
Run Code Online (Sandbox Code Playgroud)
我现在有了错误的堆栈跟踪。但是我如何才能访问 User 和 PhoneNumber?虽然堆栈跟踪很有帮助,但在错误报告系统中引用导致错误的基础数据是最重要的。
我做了类似的事情,但我没有在我的IErrorHandler扩展点中记录方法调用参数。相反,我最终在IOperationInvoker那里实现了自定义和处理参数日志记录。这是一个可能有用的代码片段:
public class MyOperationBehavior : IOperationBehavior
{
public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
{
// intentionally empty.
}
public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
{
// intentionally empty.
}
public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
// create a name for this operation for logging purposes.
string operationName;
if (operationDescription.SyncMethod != null)
operationName = operationDescription.SyncMethod.DeclaringType.FullName + "." + operationDescription.Name;
else if (operationDescription.BeginMethod != null)
operationName = operationDescription.BeginMethod.DeclaringType.FullName + "." + operationDescription.Name;
else operationName = operationDescription.Name;
dispatchOperation.Invoker = new MyOperationInvoker(operationName, dispatchOperation.Invoker);
}
public void Validate(OperationDescription operationDescription)
{
// intentionally empty.
}
}
Run Code Online (Sandbox Code Playgroud)
.
public class MyOperationInvoker : IOperationInvoker
{
private readonly IOperationInvoker defaultInvoker;
private readonly string operationName;
public MyOperationInvoker(string operationName, IOperationInvoker defaultInvoker)
{
if(defaultInvoker == null)
throw new ArgumentException("DefaultInvoker can not be null.");
this.defaultInvoker = defaultInvoker;
this.operationName = operationName;
}
public object[] AllocateInputs()
{
return defaultInvoker.AllocateInputs();
}
public object Invoke(object instance, object[] inputs, out object[] outputs)
{
Exception error = null;
DoMySuperAwesomePreProcessing(operationName, inputs);
try
{
return defaultInvoker.Invoke(instance, inputs, out outputs);
}
catch (Exception ex)
{
error = ex;
throw;
}
finally
{
DoMySuperAwesomePostProcessing(operationName, inputs, error);
}
}
public bool IsSynchronous
{
get { return defaultInvoker.IsSynchronous; }
}
Run Code Online (Sandbox Code Playgroud)
所以基本上它会通过 调用它通常会调用的任何东西defaultInvoker,但是在调用之前和之后,它有机会与实例、输入、输出和异常进行交互(如果有的话)。
在那个后期处理点,如果我发现了一个错误,我最终会记录它,包括方法名称、所有输入参数以及所有记录的异常方法,因此我们可以尝试用相同的方法重现问题输入。
我也还仍然有一个自定义的IErrorHandler用于记录未处理的异常实现,我只是不从那里记录的参数,而不是我从上面的代码登录的参数。
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
719 次 |
| 最近记录: |