gpt4 book ai didi

c# - WCF 客户端错误处理

转载 作者:太空狗 更新时间:2023-10-29 17:51:47 26 4
gpt4 key购买 nike

我正在使用一个笨重的 WCF 服务器,它偶尔会抛出各种异常,并且还会以 string 的形式返回一些错误。 .我根本无法访问服务器代码。

我想覆盖内部 WCF 客户端请求调用方法并处理服务器返回的所有内部异常和硬编码错误并引发 Fault发生错误时的事件,伪:

class MyClient : MyServiceSoapClient
{
protected override OnInvoke()
{
object result;
try
{
result = base.OnInvoke();
if(result == "Error")
{
//raise fault event
}
catch
{
//raise fault event
}
}
}

所以当我调用myClient.GetHelloWorld() ,它通过我重写的方法。

如何实现?
我知道我不必使用生成的客户端,但我不想再次重新实现所有合约,我想使用生成的 ClientBase子类或至少它的 channel 。
我需要的是控制内部请求调用方法。

更新

我读了这个answer , 看起来它是我正在寻找的部分内容,但我想知道是否有办法附加 IErrorHandler仅限消费者(客户端)代码,我想将其添加到 ClientBase<TChannel>以某种方式实例。

更新

This文章看起来也很有前途,但行不通。 applied 属性似乎没有生效。我找不到添加 IServiceBehavior 的方法到客户端。

更新

我尝试附加 IErrorHandler通过IEndpointBehavior.ApplyClientBehavior调用:

public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.CallbackDispatchRuntime.ChannelDispatcher.ErrorHandlers
.Add(new ErrorHandler());
}

(clientRuntime是一个参数),但是还是会直接跳过MyErrorHandler抛出异常.
ApplyDispatchBehavior根本没有被调用。

结论

我需要实现两个方面:

  1. 包装所有可能在 BaseClient<TChannel> 的生命周期内发生的异常并决定是处理它们还是扔掉它们。这应该负责所有操作(我正在使用的服务公开了几十个)
  2. 解析所有服务器回复并为其中一些回复抛出异常,因此它们会像语句 1 中那样被转发。

最佳答案

您可以使用和修改 Exception Handling WCF Proxy Generator ,更具体地说,它使用的基类。它的基本思想(也检查 this description)是通过捕获连接故障并重试失败的操作来提供连接弹性。可以想象,为此目的,它需要能够捕获抛出的异常,并且还可以检查调用的结果。

主要功能由 ExceptionHandlingProxyBase<T> 给出基类,您使用它代替 ClientBase<T> .这个基类有一个 Invoke方法如下,你需要修改它。

简化版 Invoke :

protected TResult Invoke<TResult>(string operationName, params object[] parameters)                              
{
this.Open();
MethodInfo methodInfo = GetMethod(operationName);
TResult result = default(TResult);
try
{
this.m_proxyRecreationLock.WaitOne(this.m_proxyRecreationLockWait);
result = (TResult)methodInfo.Invoke(m_channel, parameters);
}
catch (TargetInvocationException targetEx) // Invoke() always throws this type
{
CommunicationException commEx = targetEx.InnerException as CommunicationException;
if (commEx == null)
{
throw targetEx.InnerException; // not a communication exception, throw it
}
FaultException faultEx = commEx as FaultException;
if (faultEx != null)
{
throw targetEx.InnerException; // the service threw a fault, throw it
}

//... Retry logic

}
return result;
}

您需要修改 throw targetEx.InnerException;部分根据需要处理异常,显然还应该根据您的需要检查返回值。除此之外,如果您不希望出现连接问题,您可以保留重试逻辑或将其丢弃。 Invoke 还有另一个变体对于 void返回方法。

哦,顺便说一句,它也适用于双工 channel ,还有另一个基类。

如果您不想使用生成器(它甚至可能无法在较新版本的 VS 中工作),那么您可以只使用来自 here 的基类作为示例,并从您的服务接口(interface)生成带有 T4 的实际实现类。

关于c# - WCF 客户端错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33734660/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com