Преодоление ограничений ErrorInfo в преобразовании исключений ABP Framework
Я реализовал кастом IExceptionToErrorInfoConverter
для ASP.NET Boilerplate для преобразования пользовательских исключений в веб-API.
Проблема в том, что ABP имеет строгий интерфейс, который должен вернуть ErrorInfo
тип:
ErrorInfo Convert(Exception exception);
Проблема в том, что ErrorInfo
структура не соответствует моим требованиям, поэтому я хотел бы иметь свою собственную ошибку DTO.
У кого-нибудь есть идеи, как обойти преобразование исключений ABP?
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};
}
}
Это моя дополнительная информация, благодаря @slava-utesinov принятому ответу (в этом QA).
Действительно внутри ABP, как можно было бы предположить, использует object
поэтому при работе с сериализацией DTO предположение было твердым.
Пример кода из источника 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, я обнаружил функцию условной сериализации свойств. По соглашению 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
}