WebAPI如何在(.NET)客户端反序列化异常

Joh*_*ohn 8 c# json asp.net-web-api asp.net-web-api2

我有一个webAPI 2控制器,目前它正在抛出异常,并且这是在响应消息中发送回客户端.500内部服务器错误,它的自我序列化的例外,我可以在fiddler中看到它的json表示.(json粘贴在下面)

我一直在尝试找到一种方法将此异常反序列化为.NET异常对象,但不断收到错误:

"找不到会员'ClassName'."

目前在我的客户端我试图通过以下代码反序列化异常.

if (apiResponse.ResponseCode.Equals(500)) // Unhandled exception on server
{
    var exceptionObject = await response.Content.ReadAsAsync<Exception>();
}
Run Code Online (Sandbox Code Playgroud)

如何在客户端应用程序上正确反序列化此异常对象?理想情况下,我应该能够取回原始的System.InvalidOperationException`对象.

下面是我试图在fiddler中捕获的反序列化的响应:

HTTP/1.1 500内部服务器错误缓存控制:无缓存Pragma:no-cache内容类型:application/json; charset = utf-8 Expires:-1 Server:Microsoft-IIS/10.0 X-AspNet-Version:4.0.30319 X-Powered-By:ASP.NET Date:Wed,30 Sep 2015 13:43:42 GMT Content-Length :1556

{"Message":"发生了错误.","ExceptionMessage":"UrlHelper.Link必须不返回null.","ExceptionType":"System.InvalidOperationException","StackTrace":"在System.Web.Http. Results.CreatedAtRouteNegotiatedContentResult1.Execute()\r\n at System.Web.Http.Results.CreatedAtRouteNegotiatedContentResult1.ExecuteAsync(CancellationToken cancellationToken)\ r \n在System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext()\ r \n ---从抛出异常的上一个位置的堆栈跟踪结束---\r \n \n System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)\ r \n在System.Web.Http.Controllers.ActionFilterResult.d__上的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \n中.MoveNext()\ r \n ---从抛出异常的上一个位置开始的堆栈跟踪结束---在系统中的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)\ r \n中的\ r \n. System.Web.Http.Filters.AuthorizationFilterAttribute.d__2中的Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \n.MoveNext()\ r \n ---从抛出异常的上一个位置开始的堆栈跟踪结束---在System.Runtime上的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)\ r \n中的\ r \n \n \n System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()"}中的.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \n

ger*_*rmi 6

感谢Serg Rogovtsev的评论,我现在知道你所拥有的不是一个Exception而是一个HttpError.因此,你必须这样处理它:

var exceptionObject = await response.Content.ReadAsAsync<System.Web.Http.HttpError>();
Run Code Online (Sandbox Code Playgroud)

不过,我仍然不相信这是个好主意.500状态代码通常意味着出现意外错误,并且没有任何东西可以在服务器端捕获它.如果您可以控制服务器,我强烈建议您在那里处理此类错误.客户端无论如何都无法做任何事情,所以它只需要某种错误通知.

旧答案(在评论之前HttpError):

序列化Exception看起来像这样:

{
    "ClassName":"System.Exception",
    "Message":"some exception",
    "Data":null,
    "InnerException":null,
    "HelpURL":null,
    "StackTraceString":null,
    "RemoteStackTraceString":null,
    "RemoteStackIndex":0,
    "ExceptionMethod":null,
    "HResult":-2146233088,
    "Source":null,
    "WatsonBuckets":null
}
Run Code Online (Sandbox Code Playgroud)

你所拥有的只是一个格式化的错误消息,其中包含有关异常的信息.

顺便说一下:我不会尝试在客户端捕获服务器端异常.您需要处理服务器上的错误并向客户端提供足够的信息以通知用户发生的情况.

  • 是的,WebAPI将异常包装在HttpError中。 (2认同)