Есть ли способ десериализации объекта Exception? - PullRequest
0 голосов
/ 17 января 2019

Я работаю над проектом WCF REST. На стороне WCF / сервера всякий раз, когда происходит исключение в моем блоке перехвата, я делаю это ниже и отправляю исключение в виде строки 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;
}

Пожалуйста, смотрите ниже для моей стороны клиента

enter image description here

Мой вопрос, есть ли способ десериализации объекта Exception . Я чувствую, что вы не можете сделать, так как класс 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();                        
  }
 }

1 Ответ

0 голосов
/ 17 января 2019

Вы можете просто использовать Newtonsoft.Json.JsonConvert.DeserializeObject<T> Поэтому измените свой код на это:

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