重新创建在JSON响应中序列化的异常

时间:2014-02-15 09:18:35

标签: c# asp.net json object asp.net-web-api

Web服务中发生异常,ASP.NET Web API在JSON响应中返回异常,如下所示:

HTTP/1.1 500 Internal Server Error
Content-Type: application/json; charset=utf-8

{ "Message":"An error has occurred.", 
  "ExceptionMessage":"Incorrect syntax near 'FooBar'.",
  "ExceptionType":"System.Data.SqlClient.SqlException", 
  "StackTrace":"at System.Web.Http.ApiController.blah.blah.blah" }

我想在客户端重新创建异常。我想将响应转换为SqlException对象(在下面的示例中),然后抛出异常。一些博客提到使用Activator.CreateInstance()和Type.GetType()在运行时创建一个对象,字符串中的类型名称,有些人提到使用动态。但是,我无法确定如何正确使用它。如果有人能教育我,我将不胜感激。谢谢!

public class ExceptionResponse
{
    public string Message { get; set; }
    public string ExceptionType { get; set; }
    public string ExceptionMessage { get; set; }
    public string StackTrace { get; set; }
}

ExceptionResponse response = httpContent.ReadAsAsync<ExceptionResponse>().Result;
Type exceptionType = Type.GetType(response.ExceptionType);
throw Activator.CreateInstance(exceptionType, new object[]);

// Visual Studio indicates error: The type caught or throw must be derived from System.Exception

2 个答案:

答案 0 :(得分:0)

据我所知,您尝试处理一个异常,该异常通过http作为JSON格式的消息进行回收。因此,您可以尝试序列化(解析)HTTP响应并创建ExceptionResponse的新实例。例如:

using System.Web.Script.Serialization;

您的异常类将如下所示:

public class ExceptionResponse : Exception {
    public string ExceptionType { get; set; }
    public string ExceptionMessage { get; set; }
}

调用:

var httpResponse = @"{ ""Message"":""An error has occurred."", ""ExceptionMessage"":""Incorrect syntax near 'FooBar'."", ""ExceptionType"":""System.Data.SqlClient.SqlException"",  ""StackTrace"":""at System.Web.Http.ApiController.blah.blah.blah"" }";

var e = new JavaScriptSerializer().Deserialize<ExceptionResponse>(httpResponse);
throw e;

答案 1 :(得分:0)

最后,我从Github找到了一个示例,展示了如何使用反射重新创建SQL异常。 public static class SqlExceptionCreator {     public static SqlException Create(string message,int errorCode)     {         SqlException异常=实例化&lt; SqlException&gt;();         SetProperty(例外,&#34; _message&#34;,消息);         var errors = new ArrayList();         var errorCollection = Instantiate&lt; SqlErrorCollection&gt;();         SetProperty(errorCollection,&#34;错误&#34;,错误);         var error = Instantiate&lt; SqlError&gt;();         SetProperty(错误,&#34;数字&#34;,errorCode);         errors.Add(误差);         SetProperty(例外,&#34; _errors&#34;,errorCollection);         返回异常;     }     private static T Instantiate&lt; T&gt;()其中T:class     {         将System.Runtime.Serialization.FormatterServices.GetUninitializedObject(typeof(T))作为T返回;     }     private static void SetProperty&lt; T&gt;(T targetObject,string fieldName,object value)     {         var field = typeof(T).GetField(fieldName,BindingFlags.NonPublic | BindingFlags.Instance);         if(field!= null)         {             field.SetValue(targetObject,value);         }         其他         {             抛出新的InvalidOperationException(&#34; No name with name&#34; + fieldName);         }     } }