Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is Error.cshtml called in ASP.NET MVC?

I've read a dozen similar questions on StackOverflow, but I can't seem to grasp this. With regards to the custom errors node in the web.config and the HandleErrorAttribute, how does the Error.cshtml ever get called? Ultimately the answer to this question may be the answer to one of those several questions already out there regarding ASP.NET MVC error handling. But, fact of the matter is, I don't know which one.

like image 244
LJM Avatar asked Aug 07 '12 17:08

LJM


People also ask

What is Cshtml in MVC?

What is a CSHTML file? A file with . cshtml extension is a C# HTML file that is used at server side by Razor Markup engine to render the webpage files to user's browser.

How do I show Cshtml?

Right click the Index. cshtml file and select View in Browser. You can also right click the Index. cshtml file and select View in Page Inspector.


1 Answers

Inside your Global.asax you have the following method:

public static void RegisterGlobalFilters(GlobalFilterCollection filters) {     filters.Add(new HandleErrorAttribute()); } 

This registers the HandleErrorAttribute as global action filter. This means that this handler is automatically applied to all controller actions. Now let's take a look at how this attribute is implemented by looking at the source code:

[SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", Justification = "This attribute is AllowMultiple = true and users might want to override behavior.")] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class HandleErrorAttribute : FilterAttribute, IExceptionFilter {      private const string _defaultView = "Error";      private readonly object _typeId = new object();      private Type _exceptionType = typeof(Exception);     private string _master;     private string _view;      public Type ExceptionType {         get {             return _exceptionType;         }         set {             if (value == null) {                 throw new ArgumentNullException("value");             }             if (!typeof(Exception).IsAssignableFrom(value)) {                 throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,                     MvcResources.ExceptionViewAttribute_NonExceptionType, value.FullName));             }              _exceptionType = value;         }     }      public string Master {         get {             return _master ?? String.Empty;         }         set {             _master = value;         }     }      public override object TypeId {         get {             return _typeId;         }     }      public string View {         get {             return (!String.IsNullOrEmpty(_view)) ? _view : _defaultView;         }         set {             _view = value;         }     }      public virtual void OnException(ExceptionContext filterContext) {         if (filterContext == null) {             throw new ArgumentNullException("filterContext");         }         if (filterContext.IsChildAction) {             return;         }          // If custom errors are disabled, we need to let the normal ASP.NET exception handler         // execute so that the user can see useful debugging information.         if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled) {             return;         }          Exception exception = filterContext.Exception;          // If this is not an HTTP 500 (for example, if somebody throws an HTTP 404 from an action method),         // ignore it.         if (new HttpException(null, exception).GetHttpCode() != 500) {             return;         }          if (!ExceptionType.IsInstanceOfType(exception)) {             return;         }          string controllerName = (string)filterContext.RouteData.Values["controller"];         string actionName = (string)filterContext.RouteData.Values["action"];         HandleErrorInfo 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;          // Certain versions of IIS will sometimes use their own error page when         // they detect a server error. Setting this property indicates that we         // want it to try to render ASP.NET MVC's error page instead.         filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;     } } 

The source code contains comments and is more than self explanatory. The first thing it checks is whether you have enabled custom errors in your web.config (i.e. <customErrors mode="On">). If you haven't it does nothing => YSOD. If you have enabled custom errors then it renders the Error view passing it a model containing the exception stacktrace and other useful information.

like image 146
Darin Dimitrov Avatar answered Sep 27 '22 17:09

Darin Dimitrov