0
votes

I built a custom Exception and I'm throwing an instance of this class whenever I consider that the my application is in an 'exceptional state'. This exception is being thrown in an application logic class (service in my case). Now, I also have the default ASP MVC exception redirection in place, but in case of these custom exceptions, I don't want it to redirect to the 'Error' page, but to show a message in a div (for example in my Layout.cshtml page). I was thinking on adding the exception message to TempData["ApplicationError"]. I want to write this code only once, not all over my controller action methods. So, in my base controller class I overridden protected void OnException(ExceptionContext filterContext) and my code looks like this:

protected override void OnException(ExceptionContext filterContext)
    {
        if (filterContext.Exception is InvalidOperationException)
            TempData["ApplicationError"] = filterContext.Exception.Message;
        else
            base.OnException(filterContext);
    }

My problem is that I still get redirected to the default error page when this exception is thrown. I DON'T want this to happen. What I want is to display the custom exception's message in a friendly div on the same view the user is on. Do you have any ideas on how can I achieve this?

2

2 Answers

0
votes

What i did in a similar situation in, I added a property to my ViewModel( i added to the base class where all other viewmodels are inheriting from) for error messsage and success message. Whenever there is an error (either application / system) i set value to this property and show this in my view. I will always return the viewmodel from controller thus not letting error page to be displayed.

public class BaseViewModel
{
  public string ErrorMessage { set;get;}
  public string SuccessMessage {set;get;}
  public bool IsValid { set;get;}
} 

public class UserViewModel: BaseViewModel
{
  // user properties
}

And in my controller

public ActionResult Get(int id)
{

  UserViewModel ovjUser;
  try
  {
    objUser=MyService.GetUser(id);
    if(!objUser.IsValid)
    {
       objUser.ErrorMessage="This User Account is not Valid";
    }
  }
  catch(Exception ex)
  {
   // log error
    objUser.ErrorMessage="Application is buzy now!.Pls try later";
  }
  return View(objUser);
}
0
votes

Try indicating that you have handled the exception by setting the ExceptionHandled property:

protected override void OnException(ExceptionContext filterContext)
{
    if (filterContext.Exception is InvalidOperationException)
    {
        filterContext.ExceptionHandled = true;
        var viewResult = new ViewResult();
        viewResult.ViewData["ApplicationError"] = filterContext.Exception.Message;
        filterContext.Result = viewResult;
    }
}

An important aspect is that since there was an exception inside the controller action, it didn't get to the point where an action result was returned. So you no longer know whether the action had to render a view, return JSON, redirect or whatever. So you could assume it wanted to render a view by setting the filterContext.Result property. Obviously if you had a view model associated to this view you won't be able to reconstruct it. So make sure that your view is organized in such a manner that if there's something inside ViewData["ApplicationError"] don't even attempt to do anything with your view model as you won't have it => remember your application crashed in the middle of the execution of the action.