如何反序列化Simple.OData.Client错误

时间:2015-09-03 14:46:16

标签: json exception json-deserialization

我正在为我的客户端/服务器休息调用使用一个很棒的包,名为Simple.OData.Client,但是我在从返回的错误中提取详细信息时遇到了问题。

有没有人知道将这些json响应反序列化为适当的异常类型的简单方法?

示例WebRequestException响应:

{
  "error":{
    "code":"","message":"An error has occurred.","innererror":{
      "message":"An error occurred while updating the entries. See the inner exception for details.","type":"System.Data.Entity.Infrastructure.DbUpdateException","stacktrace":"   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at Jbssa.FreightRates.Server.Controllers.RegionsController.<Post>d__3.MoveNext() in F:\\tfs2013\\New Tech Apps\\Dev\\Jbssa.FreightRates\\src\\Server\\Jbssa.FreightRates.Server\\Controllers\\RegionsController.cs:line 42\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__3`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()","internalexception":{
        "message":"An error occurred while updating the entries. See the inner exception for details.","type":"System.Data.Entity.Core.UpdateException","stacktrace":"   at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.<UpdateAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Data.Entity.Core.Objects.ObjectContext.<ExecuteInTransactionAsync>d__3d`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesToStoreAsync>d__39.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.<ExecuteAsyncImplementation>d__9`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesInternalAsync>d__31.MoveNext()","internalexception":{
          "message":"Cannot insert duplicate key row in object 'scoFreightRate.Region' with unique index 'IX_Code'. The duplicate key value is (R1).\r\nThe statement has been terminated.","type":"System.Data.SqlClient.SqlException","stacktrace":"   at System.Data.SqlClient.SqlCommand.<>c__DisplayClass16.<ExecuteDbDataReaderAsync>b__17(Task`1 result)\r\n   at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()\r\n   at System.Threading.Tasks.Task.Execute()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.<ExecuteAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.<UpdateAsync>d__0.MoveNext()"
        }
      }
    }
  }
}

1 个答案:

答案 0 :(得分:0)

使用以下网站http://json2csharp.com/时,这比我想象的要容易一些。

我现在有以下&#34; ExceptionTranslator&#34;,我为我的项目实施的东西,但认为这个想法可能会帮助其他人。

public class WebRequestExceptionTranslator : IExceptionTranslator
{
    public IExceptionModel Translate(Exception ex, out bool handled)
    {
        handled = false;

        var wre = ex as WebRequestException;
        if (wre != null)
        {
            var model = new ExceptionModel();
            try
            {
                var jobject = JsonConvert.DeserializeObject<RootObject>(wre.Response);
                if (jobject.error != null)
                {
                    model.Message = jobject.error.message;
                    var inner = jobject.error.innererror;
                    string message = string.Empty;
                    while (inner != null)
                    {
                        message = inner.message.Replace("See the inner exception for details.", "Click Details for more information.");
                        inner = inner.internalexception;                            
                        if (inner == null)
                            model.Description = message;
                        else
                            model.Message = message;
                    }
                    handled = true;
                    return model;
                }
            }
            catch 
            {
                // this generated an exception, let another exception translator deal with it.
            }
        }
        return null;
    }

    class Innererror
    {
        public string message { get; set; }
        public string type { get; set; }
        public string stacktrace { get; set; }
        public Innererror internalexception { get; set; }
    }

    class Error
    {
        public string code { get; set; }
        public string message { get; set; }
        public Innererror innererror { get; set; }
    }

    class RootObject
    {
        public Error error { get; set; }
    }
}