2014-02-15 21 views
1

在Web服務和ASP.NET Web API發生異常返回JSON響應異常,像下面:重新創建是在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 

回答

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; 
+0

如何將變量e從類型ExceptionResponse更改爲類型SqlException?在我的程序中,我有一個catch塊來查找SqlException。 – Tony

+0

你可以明確地施放它。因爲SqlException是Exception的派生類。嘗試檢查此:http://social.msdn.microsoft.com/Forums/vstudio/en-US/bdaeb0c6-1d9d-44c2-92c7-6cdda411a5e7/exception-casting-to-sqlexception?forum=csharpgeneral – 2014-02-17 05:23:11

+0

例外可以是JSON響應中指定的任何類型。例如,它可能是NotImplementedException或IOException。我如何在運行時投射物體? – Tony

0

最後,我發現了一個例子,從Github展示如何重建SQL異常使用反射。

public static class SqlExceptionCreator 
{ 
    public static SqlException Create(string message, int errorCode) 
    { 
     SqlException exception = Instantiate<SqlException>(); 
     SetProperty(exception, "_message", message); 

     var errors = new ArrayList(); 
     var errorCollection = Instantiate<SqlErrorCollection>(); 
     SetProperty(errorCollection, "errors", errors); 

     var error = Instantiate<SqlError>(); 
     SetProperty(error, "number", errorCode); 

     errors.Add(error); 
     SetProperty(exception, "_errors", errorCollection); 

     return exception; 
    } 


    private static T Instantiate<T>() where T : class 
    { 
     return System.Runtime.Serialization.FormatterServices.GetUninitializedObject(typeof(T)) as T; 
    } 

    private static void SetProperty<T>(T targetObject, string fieldName, object value) 
    { 
     var field = typeof(T).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); 
     if (field != null) 
     { 
      field.SetValue(targetObject, value); 
     } 
     else 
     { 
      throw new InvalidOperationException("No field with name " + fieldName); 
     } 
    } 
}