【问题标题】:Is there a way to deserialize Exception object?有没有办法反序列化异常对象?
【发布时间】:2019-01-17 20:18:28
【问题描述】:

我正在开发 WCF REST 项目。在 WCF/服务器端,每当我的 catch 块中发生异常时,我都会在下面执行并在对客户端的响应中将异常作为 json 字符串发送。

public MyResponse GetData(MyRequest request)
{
   MyResponse response = new MyResponse();
   try
   {
       // do something
   }
   catch(Exception ex)
   { 
      response.success = false;
      response.ExceptionJSONString = Newtonsoft.Json.JsonConvert.SerializeObject(ex);
   }
   return response;
}

请在下面查看我的客户端

我的问题是有办法反序列化异常对象。我觉得你不能这样做,因为 Exception 类继承了 ISerializable。但只是想四处打听,看看有人这样做。

更新:我能够从客户端到服务器获取确切的异常对象,如下所示

在 DataContract 类下面创建

[DataContract]
public class MyExceptionJson
{
   [DataMember]
   public string JsonData { get; set; }

   [DataMember]
   public string AssemblyName { get; set; }

   [DataMember]
   public string TypeName { get; set; }

   public MyExceptionJson()
   {
      JsonData = string.Empty;
      AssemblyName = string.Empty;
      TypeName = string.Empty;
   }

   public MyExceptionJson(Exception exception)
   {
      JsonData = Newtonsoft.Json.JsonConvert.SerializeObject(exception);
      Type type = exception.GetType();
      AssemblyName = type.Assembly.GetName().Name;
      TypeName = type.FullName;
   }

    public Exception ToException()
    {
       if (string.IsNullOrEmpty(JsonData) == true ||
           string.IsNullOrEmpty(AssemblyName) == true ||
           string.IsNullOrEmpty(TypeName) == true)
         {
            return new Exception();
         }

       Type type = null;
      foreach (Assembly item in System.AppDomain.CurrentDomain.GetAssemblies())
      {
         AssemblyName assemblyName = item.GetName();
          if (assemblyName != null &&
              string.IsNullOrEmpty(assemblyName.Name) == false &&
              assemblyName.Name == AssemblyName)
            {
               type = item.GetType(TypeName);
               if (type != null)
                   break;
             }
        }
        //fail safe code
        if (type == null)
        {
           type = typeof(Exception);
        }
     object returnException = Newtonsoft.Json.JsonConvert.DeserializeObject(JsonData, type);
     return returnException as Exception;
     }
}

在我的响应类中添加了此类类型的属性,如下所示

[DataContract]
public class MyResponse 
{
   [DataMember]
   public bool Success { get; set; }

   [DataMember]
   public MyExceptionJson ExceptionDataAsJson { get; set; }
}

服务器:异常发生时

  MyResponse response = new MyResponse()
  {
     Success = false,
     ExceptionDataAsJson = null
  };

  try 
  {
     //code 
  }
  catch(Exception ex)
  {
      response.ExceptionDataAsJson = new MyExceptionJson(ex);
  }
  return response;

客户:当您收到回复时

 if (response != null && response.Success == false)
 {
  Exception ex = null;
  //something went wrong                    
  if (response.ExceptionDataAsJson != null)
  {
    ex = response.ExceptionDataAsJson.ToException();                        
  }
 }

【问题讨论】:

  • 为什么“ISerializable”排除反序列化选项?如果没有反序列化,序列化的任何东西都只是一堆二进制或字符垃圾。
  • @Ryan.. 在我的带有 WCF 服务的代码中,我能够将 exceptionjson 字符串发送给客户端,但在我的小提琴中,它甚至在序列化时抛出错误。看看小提琴有什么问题
  • @Ryan..你的工作..这就是答案...请回答这个帖子..我会接受它..谢谢
  • @Ziggler 根据您的要求发布为答案。
  • @RyanWilson.. 谢谢.. 我接受了...

标签: c# exception json.net deserialization


【解决方案1】:

你可以使用Newtonsoft.Json.JsonConvert.DeserializeObject<T> 所以把你的代码改成这样:

Exception ex = Newtonsoft.Json.JsonConvert.DeserializeObject<Exception>(upResponse.ExceptionJSONString);

【讨论】:

  • Ryan ....我们正在尝试在我们的项目中改进这个解决方案..而不是总是反序列化为异常,我们希望反序列化为我们从 WCF/服务器端收到的确切异常类型......我正在研究它...任何建议...
  • @Ziggler 所有异常都继承自Exception,所以我认为您可以将其转换为特定的Exception 类型。
  • 但是从我的 WCF/服务器端,我在 json 字符串中遇到异常...我觉得我需要以某种方式将异常类型传递给客户端,然后反序列化为该类型。但是这种方式需要检查每个来自服务器的异常类型
  • @Ziggler 即使您将确切类型的异常添加到您的 json 中,您也必须执行 if-else ifswitch 来决定要反序列化的类型,所以无论哪种方式收到响应时,您将不得不进行类型检查。
  • Ryan.. 是的,我也同意我需要使用条件运算符.. 这就是我要避免的......
猜你喜欢
  • 2019-12-26
  • 2021-10-24
  • 2011-02-10
  • 2011-02-03
  • 1970-01-01
  • 2018-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多