Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC 5 Custom Error Page

I am using a custom authorize attribute in a ASP.NET MVC 5 application like following:

public class CustomAuthorizeAttribute : AuthorizeAttribute {     protected override void HandleUnauthorizedRequest(AuthorizationContext context)     {         if (context.HttpContext.Request.IsAuthenticated)         {             context.Result = new System.Web.Mvc.HttpStatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);                         }         else         {             base.HandleUnauthorizedRequest(context);         }     } } 

In system.web section of my web.config I mentioned error paths like:

<system.web>     <customErrors mode="On" defaultRedirect="/Error/Error">       <error statusCode="403" redirect="/Error/NoPermissions"/>     </customErrors> </system.web> 

But I am never redirected to my custom error page at /Error/NoPermissions. Instead the browser display the general error page saying "HTTP Error 403.0 - Forbidden".

like image 323
Haider Avatar asked May 09 '14 12:05

Haider


People also ask

How do I enable custom errors in web config MVC?

The first step is to enable customErrors using its mode attribute that can have one of the following three values: On: Specifies that custom errors are enabled. If no defaultRedirect is specified, users see a generic error page e.g. Error. cshtml in ASP.NET MVC application.


2 Answers

[1]: Remove all 'customErrors' & 'httpErrors' from Web.config

[2]: Check 'App_Start/FilterConfig.cs' looks like this:

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

[3]: in 'Global.asax' add this method:

public void Application_Error(Object sender, EventArgs e) {     Exception exception = Server.GetLastError();     Server.ClearError();      var routeData = new RouteData();     routeData.Values.Add("controller", "ErrorPage");     routeData.Values.Add("action", "Error");     routeData.Values.Add("exception", exception);      if (exception.GetType() == typeof(HttpException))     {         routeData.Values.Add("statusCode", ((HttpException)exception).GetHttpCode());     }     else     {         routeData.Values.Add("statusCode", 500);     }      Response.TrySkipIisCustomErrors = true;     IController controller = new ErrorPageController();     controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));     Response.End(); } 

[4]: Add 'Controllers/ErrorPageController.cs'

public class ErrorPageController : Controller {     public ActionResult Error(int statusCode, Exception exception)     {          Response.StatusCode = statusCode;          ViewBag.StatusCode = statusCode + " Error";          return View();     } } 

[5]: in 'Views/Shared/Error.cshtml'

@model System.Web.Mvc.HandleErrorInfo @{     ViewBag.Title = (!String.IsNullOrEmpty(ViewBag.StatusCode)) ? ViewBag.StatusCode : "500 Error"; }  <h1 class="error">@(!String.IsNullOrEmpty(ViewBag.StatusCode) ? ViewBag.StatusCode : "500 Error"):</h1>  //@Model.ActionName //@Model.ControllerName //@Model.Exception.Message //@Model.Exception.StackTrace 

:D

like image 133
ubik404 Avatar answered Sep 22 '22 12:09

ubik404


Thanks everyone, but problem is not with 403 code. Actually the problem was with the way i was trying to return 403. I just changed my code to throw an HttpException instead of returning the HttpStatusCodeResult and every things works now. I can return any HTTP status code by throwing HttpException exception and my customErrors configuration catches all of them. May be HttpStatusCodeResult is not doing the exact job I expected it to do.

I just replaced

context.Result = new System.Web.Mvc.HttpStatusCodeResult((int)System.Net.HttpStatusCode.Forbidden); 

with

throw new HttpException((int)System.Net.HttpStatusCode.Forbidden, "Forbidden"); 

That's it.

Happy coding.

like image 41
Haider Avatar answered Sep 18 '22 12:09

Haider