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".
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.
[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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With