克服ABP Framework异常转换中的ErrorInfo限制

时间:2016-07-05 12:14:40

标签: c# aspnetboilerplate

我为ASP.NET Boilerplate实现了自定义IExceptionToErrorInfoConverter,以便在Web API中转换自定义异常。

问题是ABP有严格的接口,必须返回ErrorInfo类型:

ErrorInfo Convert(Exception exception);

问题是ErrorInfo结构不符合我的要求所以我想有自己的错误DTO。

任何人都知道如何规避ABP异常转换?

2 个答案:

答案 0 :(得分:2)

你可以尝试一招。可能是,当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};
    }
}

答案 1 :(得分:1)

感谢@ slava-utesinov accepted answer (in this QA),这是我的补充信息。

事实上内部ABP在处理序列化DTO时会怀疑使用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
}