WCF全局错误处理

时间:2017-05-03 16:37:29

标签: c# wcf

我试图使用IErrorHandler interfcae在WCF中实现全局错误处理,但我想返回(在未处理的异常情况下)一个简单的字符串 (这是我服务的返回类型)我怎么能实现这一点? IErrorHandler中的ProvideFault方法设置了' fault' Message类型的参数和Message类型ToString()生成类似响应的XML,因此这对我不起作用 (因为我的客户想要以特定的格式获得简单的字符串)。

感谢

1 个答案:

答案 0 :(得分:0)

根据documentation

  

IErrorHandler使您能够显式控制生成的SOAP错误

这不是用于更改服务的实际返回值。

如果我理解正确,您的服务已经返回一个字符串。如果发生错误,您希望服务返回特定字符串。

最简单的形式是:

public string YourServiceMethod(int someInput)
{
    try
    {
        // Do whatever the method does
    }
    catch(Exception ex)
    {
        // Log the exception, probably?
        return "This is the specific error message I want to return."
    }
}

如果你想避免在每个方法中编写相同的代码,一种方法是使用拦截器,例如使用Castle Windsor's dependency injection container

这意味着修改整个WCF服务以使用Windsor(或类似的DI框架),但由于其他许多原因,这是值得的。我将它用于我编写的每个WCF服务。这是关于如何在五分钟内将Windsor添加到WCF服务的tutorial

然后你会写一个叫做拦截器的类。它可能看起来像这样:

public class ErrorMessageInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        try
        {
            invocation.Proceed();
        }
        catch (Exception ex)
        {
            // log your exception
            invocation.ReturnValue = "Your specific error message.";
        }
    }
}

然后,当您使用容器注册服务时,您将执行此操作:

container.Register(
    Component.For<IInterceptor>().ImplementedBy<ServerLogInterceptor>()
       .Named("ErrorMessageInterceptor"));

container.Register(Component.For<IYourService,YourService>()
   .Interceptors("ErrorMessageInterceptor"));

其中IYourService是您的服务接口,YourService是实际的服务类。

这意味着每次激活YourService的实例时,都会创建ErrorMessageInterceptor的实例。所有对服务方法的调用都被拦截器的Intercept方法“拦截”。它基本上是在方法调用周围加try/catch而不直接将其添加到原始方法中。

如果你需要,你可以更具体。例如,您的拦截器可以检查invocation.Method.ReturnType以查看该方法是否返回一个字符串,然后只添加您的错误消息。

你可以用拦截器做一些很棒的事情。像这样的场景,你尝试小的东西是尝试使用它们的好机会。如果你在使用DI之前没有使用过它看起来很奇怪,但同样一旦你尝试它,你可能会发现它是一个非常有用的模式。