Reputation: 5449
Hi I am creating an exception handling mechanisem in asp.net WebApi and I am confused about how the returned response message is created.Here is my code:
public class ExceptionHandlerAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
actionExecutedContext.Request.CreateErrorResponse(HttpStatusCode.Accepted, new HttpError
{
{ "Message" , "I am error"},
{ "StatusCode" , "20"}
});
}
}
[AllowAnonymous]
[HttpPost]
[Validate]
public IHttpActionResult Register(UserModel userRegistrationModel)
{
throw new AccessDeniedException("message" , new Exception("inner exception"));
}
public class AccessDeniedException : BaseException
{
public AccessDeniedException(string message, Exception exception)
: base(message, exception)
{
}
}
public class BaseException : Exception
{
public BaseException(string message , Exception exception) : base(message , exception)
{
}
}
Now I have registered the ExceptionHandlerAttributed in myfilter config and while debugging I realized that code in the method OnException runs.
The problem is that the response is this one:
"readyState": 4,
"responseText": "{\"message\":\"An error has occurred.\",\"exceptionMessage\":\"message\",\"exceptionType\":\"CodeArt.Common.Exceptions.AccessDeniedException\",\"stackTrace\":\" at System.Web.Http.ApiController.<InvokeActionWithExceptionFilters>d__1.MoveNext()\\r\\n--- End of stack trace from previous location where exception was thrown ---\\r\\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\\r\\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\\r\\n at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\\r\\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext()\",\"innerException\":{\"message\":\"An error has occurred.\",\"exceptionMessage\":\"inner exception\",\"exceptionType\":\"System.Exception\",\"stackTrace\":null}}",
"responseJSON": {
"message": "An error has occurred.",
"exceptionMessage": "message",
"exceptionType": "CodeArt.Common.Exceptions.AccessDeniedException",
"stackTrace": " at System.Web.Http.ApiController.<InvokeActionWithExceptionFilters>d__1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext()",
"innerException": {
"message": "An error has occurred.",
"exceptionMessage": "inner exception",
"exceptionType": "System.Exception",
"stackTrace": null
}
},
"status": 500,
"statusText": "Internal Server Error"
I was hopping of not sending the exception stacktrace and anything else related to the exception.All I wanted to send was the data set in the OnException method.
What I am doing wrong?
Upvotes: 3
Views: 1102
Reputation: 81660
You have to add the filter to global filters and set the response to the instance of response created:
actionExecutedContext.Response = actionExecutedContext.Request.CreateErrorResponse(HttpStatusCode.Accepted, new HttpError
{
{ "Message" , "I am error"},
{ "StatusCode" , "20"}
});
Just beware of the issue I raised a while back regarding non-consumed responses resulting in memory leak. Hence, you need to first do this:
if(actionExecutedContext.Response != null)
actionExecutedContext.Response.Dispose();
and then
actionExecutedContext.Response = ...
Upvotes: 5