Edgars Pivovarenoks
Edgars Pivovarenoks

Reputation: 1684

Overcoming ErrorInfo limitations in ASP.NET Boilerplate Framework exception conversion

I implemented custom IExceptionToErrorInfoConverter for ASP.NET Boilerplate to convert custom exceptions in Web API.

Problem is that ASP.NET Boilerplate has a strict interface, that must return the ErrorInfo type:

ErrorInfo Convert(Exception exception);

The problem is that the ErrorInfo structure does not fit my requirements so I would like to have my own error DTO.

Anyone has an idea how to circumvent ASP.NET Boilerplate's exception conversion?

Upvotes: 0

Views: 859

Answers (2)

Edgars Pivovarenoks
Edgars Pivovarenoks

Reputation: 1684

This is my complementary information based on Slava Utesinov's answer.

Indeed internally ASP.NET Boilerplate as one would suspect uses object when dealing with serializing DTOs, therefore assumption was solid.

Some sample code from ASP.NET Boilerplate's source:

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)
{ ... }

So after success I stepped up the problem to try and hide the original ErrorInfo member. Now, knowing that ASP.NET Boilerplate uses JSON.NET I found the feature of Conditional Property Serialization. By convention implementing bool ShouldSerialize[member name]() we can instruct the serializer to ignore a property.

So I ended up with following proof of concept code:

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; }
}

Pleas note, for some reason you must replace base class implementation to ignore base class members.

That resulted in the following JSON, as you can see there is no 'details' property but 'myField' is present.

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

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

Upvotes: 2

Slava Utesinov
Slava Utesinov

Reputation: 13498

You can try one trick. When ASP.NET Boilerplate creates a JSON response, it might serialize the error with all available properties via reflection and wrap it into MvcAjaxResponse object with other stuff.

You can try to create your own class, derived from ErrorInfo and replace it at IExceptionToErrorInfoConverter implementation:

[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};
    }
}

Upvotes: 2

Related Questions