2016-07-05 28 views
0

我爲ASP.NET Boilerplate實現了自定義IExceptionToErrorInfoConverter以轉換Web API中的自定義異常。克服ABP Framework異常轉換中的ErrorInfo限制

問題是,ABP具有嚴格的接口,即必須返回ErrorInfo類型:

ErrorInfo Convert(Exception exception); 

問題是,ErrorInfo結構不符合我的要求,所以我想有我自己的錯誤DTO。

任何人有一個想法如何規避ABP異常轉換?

回答

1

你可以嘗試一個把戲。可能是,當Abp創建json響應時,它會通過反射序列化它的所有可用的屬性,並用其他東西包裝到MvcAjaxResponse對象中,也就是說,您可以嘗試創建自己的類,從ErrorInfo開始創建自己的類並將其替換爲IExceptionToErrorInfoConverter實施:

[Serializable] 
public class MyErrorInfo : ErrorInfo 
{ 
    public string MyProperty1 { get; set; } 
    public int MyProperty2 { get; set; } 
} 

public class MyExceptionToErrorInfoConverter : IExceptionToErrorInfoConverter 
{ 
    public IExceptionToErrorInfoConverter Next { set { } }   

    public ErrorInfo Convert(Exception exception) 
    { 
     return new MyErrorInfo{ MyProperty1 = "test", MyProperty2 = 1}; 
    } 
} 
0

這是我的補充信息感謝@ slava-utesinov accepted answer (in this QA)

事實上,在處理序列化DTO時,人們會懷疑內部ABP使用object,因此假設是可靠的。

從ABP源的一些示例代碼:

public static string ToJsonString(this object obj, bool camelCase = false, bool indented = false) 
{ ... } 

protected override JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior) 
{ ... } 

所以成功後,我加強了對問題的嘗試和原來隱藏ERRORINFO成員。現在,知道ABP使用Json.NET,我發現了Conditional Property Serialization的功能。按照慣例實現bool ShouldSerialize[member name](),我們可以指示序列化程序忽略一個屬性。

所以我結束了下面的概念證明代碼:

public class ErrorInfoEx : ErrorInfo 
{ 
    public new string Details { get; set; } 
    public bool ShouldSerializeDetails() { return false; } 

    public ErrorInfoEx(int code, string message) : base(code, message) { } 
    public string MyField { get; set; } 
} 

普萊斯注意到,由於某種原因,你必須更換基類實現忽略基類成員。

導致出現以下JSON,因爲您可以看到沒有'details'屬性但'myField'存在。

{ 
    "success":false, 
    "result":null, 
    "error": 
     { 
      "myField":"123", 

      "code":420, 
      "message":"Validation failed", 
      "validationErrors": 
       [{ 
        "message":"'Order Number' should not be empty.", 
        "members":["OrderNumber"] 
       }] 
     }, 
     "unAuthorizedRequest":false 
}