我想要一个方法,它在我的asp.net web api项目中捕获了所有未处理的异常。我发现这篇文章:How do I log ALL exceptions globally for a C# MVC4 WebAPI app?讨论了使用ExceptionFilterAttribute和OnException。
到目前为止,这是有效的,我能够捕获api控制器中抛出的异常,然后识别异常。 然后我想抛出一个HttpResponseException,其中StatusCode和Content特定于我捕获的原始异常。我该怎么做?
这是我到目前为止所做的:
public override void OnException(HttpActionExecutedContext context) {
HttpResponseMessage msg = new HttpResponseMessage();
if (context.Exception.GetType() == typeof(DBAccess.DeleteNotAllowed)) {
msg.StatusCode = HttpStatusCode.Forbidden;
msg.Content = new StringContent("Illegal action");
msg.ReasonPhrase = "Exception";
throw new HttpResponseException(msg);
} else {
//handle next exception type
}
}
当抛出DeleteNotAllowed异常时,它会按预期捕获,并将错误消息发送到客户端。但是,else语句会抛出另一个异常。
答案 0 :(得分:0)
最好的方法是使用Elmah。
它是我自2010年以来一直使用的最好的工具之一。它是异常处理最有用的工具。它还将为您提供一个易于使用的界面,以查看Web,e-amil和db上的错误。
答案 1 :(得分:0)
据我了解,您希望将所有服务器端异常翻译为更具人性化和有意义的异常吗?如果这是您想要的,那么您有两个选项,为所有可能的异常类型写if/else
或try/catch
,这将违反OCP - Open Closed Principle
,而不是这个,我建议你采用这种方法:让每个异常决定它自己的客户“翻译”,在OnException
中捕获它们并返回由具体异常给出的客户端消息和状态代码。
public class ApiException : Exception
{
public int FaultCode { get; private set; }
public ApiException(int faultCode, string message)
: base(message)
{
this.FaultCode = faultCode;
}
}
如您所见,它具有FaultCode
和Message
(继承自基础Exception
)属性,您需要ApiException
的每个具体实施者使用它的构造函数来传递它自己的属性状态代码和消息(稍后将在OnException
方法中翻译的那些)。
public override void OnException(HttpActionExecutedContext context)
{
HttpResponseMessage msg = new HttpResponseMessage();
if (context.Exception is ApiException)
{
ApiException apex = context.Exception as ApiException;
msg.StatusCode = apex.StatusCode;
msg.Content = new StringContent(apex.Message);
throw new HttpResponseException(msg);
}
}
这就是你的OnException
方法应该是什么样的。