Web API 异常包装器

Dan*_*-NP 2 c# exception-handling httpresponse asp.net-web-api

我正在使用 WebAPI 调用一些第三方方法:

public class SessionsController : ApiController
{
    public DataTable Get(int id)
    {
        return Services.TryCall(es => es.GetSessionList(id).Tables[0]);
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在包装此服务的所有调用:

internal static class Services
{
    internal static IExternalService ExternalService { get; set; }

    internal static T TryCall<T>(Func<IExternalService,T> theFunction)
    {
        try
        {
            return theFunction(ExternalService);
        }
        catch (FaultException<MyFaultDetail> e)
        {
            var message = new HttpResponseMessage(HttpStatusCode.NotImplemented);
            message.Content = new StringContent(e.Detail.Message);
            throw new HttpResponseException(message);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当抛出异常时,它会被捕获并准备好消息。通过重新抛出,我收到一条新的错误消息:

处理 HTTP 请求导致异常。有关详细信息,请参阅此异常的 'Response' 属性返回的 HTTP 响应。

如何在没有 Visual Studio 抱怨的情况下正确返回此异常?当我跳过错误时,浏览器会得到 501 错误结果。该方法Request.CreateResponse()在我的包装方法中不可用。

Bhu*_*ake 5

好吧,虽然这可能有效,但我建议您ExceptionFilterAttribute为此创建一个。这样,您就不必使用相同的臃肿代码来保护每个方法的异常。

例如:

    public class FaultExceptionFilterAttribute : ExceptionFilterAttribute 
    {
        public override void OnException(HttpActionExecutedContext context)
        {
            if (context.Exception is FaultException)
            {
                context.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

您可以通过多种方式使用此过滤器:

1. 通过行动

要将过滤器应用于特定操作,请将过滤器作为属性添加到操作:

public class SampleController : ApiController
{
    [FaultExceptionFilter]
    public Contact SampleMethod(int id)
    {
       //Your call to a method throwing FaultException
        throw new FaultException<MyFaultDetail>("This method is not implemented");
    }
}
Run Code Online (Sandbox Code Playgroud)

2. 由控制器:

要将过滤器应用于控制器上的所有操作,请将过滤器作为属性添加到控制器类:

[FaultExceptionFilter]
public class SampleController : ApiController
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

3. 全球

要将过滤器全局应用于所有 Web API 控制器,请将过滤器的实例添加到 GlobalConfiguration.Configuration.Filters集合中。此集合中的例外过滤器适用于任何 Web API 控制器操作。

GlobalConfiguration.Configuration.Filters.Add(new FaultExceptionFilterAttribute());
Run Code Online (Sandbox Code Playgroud)

如果您使用“ASP.NET MVC 4 Web 应用程序”项目模板来创建您的项目,请将您的 Web API 配置代码放在WebApiConfig类中,该类位于以下App_Start文件夹中:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Filters.Add(new FaultExceptionFilterAttribute());

        // Other configuration code...
    }
}
Run Code Online (Sandbox Code Playgroud)