2017-05-03 132 views
0

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

感谢

+0

如果我理解正确 - 您的服务方法已经返回一个字符串。如果发生异常,您希望从服务中返回特定字符串? –

+0

@ScottHannen确实如此。我想从全局错误处理程序中执行此操作。 – eitanby

+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之前看起来很奇怪,但是同样一旦你尝试了它,你可能会发现它是一个非常有用的模式。

+0

嗨, 坦克这个想法我真的不想在这个方向,但它是有意义的 和我已经改变我的代码使用城堡,所以它看起来像我的需求的好选择。 – eitanby