Reputation: 9603
As a catch-all means of handling errors, I added this to the BaseController in my MVC web application.
public class BaseController : Controller
{
protected override void OnException(ExceptionContext filterContext)
{
_logger.Error(filterContext.Exception, "Website error page displayed.");
TempData["ErrorMessage"] = "Unspecified error - please contact support";
filterContext.RouteData.Values["controller"] = "Error";
filterContext.Result = new ViewResult
{
ViewName = "Error",
};
filterContext.ExceptionHandled = true;
}
}
And I have a dedicated ErrorController that looks like this:
public class ErrorController : BaseController
{
[AllowAnonymous]
public ActionResult Error()
{
string errorMessage = "There has been an error";
if(TempData["ErrorMessage"] != null)
{
errorMessage = TempData["ErrorMessage"].ToString();
}
Logger.Warn("Error error page displayed with message {0}", errorMessage);
ViewBag.ErrorMessage = errorMessage;
return View("Error");
}
}
When an error is handled in part of the application and the user is redirected to the error page, this works fine:
if (!await UserManager.IsEmailConfirmedAsync(user.Id))
{
TempData["ErrorMessage"] = "You must have a confirmed email to log on.";
return RedirectToAction("Error", "Error");
}
However, if the error is unhandled and is routed through OnException
on BaseController
then the error View renders as expected, but the Error action on the controller is never hit. The error message assumes the default value, and breakpoints in the action don't get tripped.
Why is this? How can I correctly invoke the controller action from OnException
?
Upvotes: 4
Views: 1837
Reputation: 5778
As you go to defination and see filterContext.Result
is type of ActionResult
which is a return type compatible with both ViewResult and RedirectToRouteResult.
How ViewResult
functions is it just Renders a specified view to the response stream.
At the other side RedirectToAction
returns a RedirectToRouteResult
which is also derived from ActionResult
and it Performs an HTTP redirection to a URL that is determined by the routing engine, based on given route data.
So in your case you need redirection so that's the reason you have to use RedirectToAction("Error", "Error");
as it will return a RedirectToRouteResult
and redirect to the route you have specified.
Upvotes: 2