如何拦截WCF故障并返回自定义响应?

时间:2011-06-10 16:13:38

标签: wcf exception-handling

考虑以下非常基本的WCF服务实现:

public enum TransactionStatus 
{
    Success = 0,
    Error = 1
}

public class TransactionResponse
{
    public TransactionStatus Status { get; set; }
    public string Message { get; set; }
}


[ServiceContract]
[XmlSerializerFormat]
public interface ITestService
{
    [OperationContract]
    TransactionResponse DoSomething(string data);
}   

public class TestService : ITestService
{
    public TransactionResponse DoSomething(string data)
    {
        var result = ProcessData(data); // may throw InvalidOperationException
        return new TransactionResponse() 
        {
            Status = TransactionStatus.Success,
            Message = result                
        };            
    }

    private string ProcessData(string data) 
    {
        if (data = "foobar")
            throw new InvalidOperationException();

        return data;        
    }        
}

在DoSomething方法确实抛出InvalidOperationException的实例中,我想拦截错误并返回TransactionResponse对象,而不是让WCF使用客户端引发FaultException。如何在没有围绕巨大的try catch语句中的每个方法体的情况下执行此操作?有什么我可以挂进去的地方吗?我可以用某种属性或其他东西来做这件事吗?我可以使用ASP.NET MVC演示如何处理它的示例:

public class ApiController : BaseController
{
    protected override void OnException(ExceptionContext filterContext)
    {
        var ex = filterContext.Exception;
        var message = HttpContext.IsDebuggingEnabled ? ex.ToString() : ex.Message;

        _logger.Error("Error processing request for controller {0}, action {1}",
            filterContext.RequestContext.RouteData.Values["controller"],
            filterContext.RequestContext.RouteData.Values["action"]);

        _logger.Error(ex.ToString());
        filterContext.ExceptionHandled = true;
        filterContext.Result = ToXml(new ApiResult(false)
        {
            Message = message
        });
    }

    // ...
}

在MVC中使用上面的方法,我可以确保无论哪个控制器操作抛出异常,我都可以处理它并返回包含必要信息的格式正确的ActionResult。有没有办法用WCF做这种事情?

1 个答案:

答案 0 :(得分:7)

查看WCF IErrorHandler接口 - 它允许您集中定义服务实现中的一种方法来捕获所有异常并吞下它们,或将它们转换为WCF友好的SOAP异常。这将确保客户端和服务器之间的通道不会出现故障,例如,在此调用失败后仍可使用它。

我不明白为什么你想要“捕获”SOAP故障并将其转换为其他东西,但是......我也不知道WCF会给你的任何支持。基本假设是:捕获.NET异常并将其转换为可互操作的SOAP错误