I will explain a Nice exception handling mechanism in ASP.NET MVC. Whenever the exception generate it automatically redirect to the corresponding error page that i have mentioned at end of this comment.Please Create a class and paste the below code in that class.
using System.Web;
using System.Web.Mvc;
namespace App.Web
{
public class CustomHandleErrorAttribute : HandleErrorAttribute
{
public CustomHandleErrorAttribute()
{
}
public override void OnException(ExceptionContext filterContext)
{
if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
{
return;
}
if (new HttpException(null, filterContext.Exception).GetHttpCode() != 500)
{
return;
}
if (!ExceptionType.IsInstanceOfType(filterContext.Exception))
{
return;
}
if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
filterContext.Result = new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new
{
error = true,
message = filterContext.Exception.Message
}
};
}
else
{
var controllerName = (string)filterContext.RouteData.Values["controller"];
var actionName = (string)filterContext.RouteData.Values["action"];
var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
filterContext.Result = new ViewResult
{
ViewName = View,
MasterName = Master,
ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
TempData = filterContext.Controller.TempData
};
}
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = 500;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}
}
and then put the below code in Global.asax.cs
protected void Application_Error(object sender, EventArgs e)
{
var httpContext = ((MvcApplication)sender).Context;
var currentController = " ";
var currentAction = " ";
var currentRouteData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));
if (currentRouteData != null)
{
if (currentRouteData.Values["controller"] != null && !String.IsNullOrEmpty(currentRouteData.Values["controller"].ToString()))
{
currentController = currentRouteData.Values["controller"].ToString();
}
if (currentRouteData.Values["action"] != null && !String.IsNullOrEmpty(currentRouteData.Values["action"].ToString()))
{
currentAction = currentRouteData.Values["action"].ToString();
}
}
var ex = Server.GetLastError();
var controller = new ErrorController();
var routeData = new RouteData();
var action = "Index";
if (ex is HttpException)
{
var httpEx = ex as HttpException;
switch (httpEx.GetHttpCode())
{
case 404:
action = "NotFound";
break;
case 401:
action = "AccessDenied";
break;
}
}
httpContext.ClearError();
httpContext.Response.Clear();
httpContext.Response.StatusCode = ex is HttpException ? ((HttpException)ex).GetHttpCode() : 500;
httpContext.Response.TrySkipIisCustomErrors = true;
routeData.Values["controller"] = "Error";
routeData.Values["action"] = action;
controller.ViewData.Model = new HandleErrorInfo(ex, currentController, currentAction);
((IController)controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
}
and then Create a Controller for Catching the error like below
public class ErrorController : Controller
{
public ActionResult Index()
{
var error = ViewData.Model;
return View(error);
}
public ActionResult NotFound()
{
var error = ViewData.Model;
return View(error);
}
public ActionResult AccessDenied()
{
var error = ViewData.Model;
return View(error);
}
}
and then Create 3 views such as error.cshtml,NotFound.cshtml,AccessDenied.cshtml and paste the below mark up in each view or create a partial view for that and call in to each view. These three views are return the same model.
for example
<div><b>Controller:</b> @Model.ControllerName</div>
<div><b>Action Name :</b> @Model.ActionName</div>
<div><b>Exception:</b> @Model.Exception.Message</div>
<a href="#" style="color:Blue" id="clickMore">Click here to see more details</a>
<div id="moreDetails">
<div><b>Stack Trace:</b> @Model.Exception.StackTrace</div>
<div><b>Inner Exception:</b> @Model.Exception.InnerException</div>
</div>