Tuesday, April 9, 2013

Returning an HTTP 403 Forbidden error with ASP.NET MVC

Sometimes it can be useful, in case of error, to return a custom error message to the user along with the HTTP 403 (Forbidden) status code.
This usually indicates that the access to the requested resource is denied for some reason and the server cannot proceed. Unlike the 401 Unauthorized status, which means an unauthorized access, correct credentials will not allow you to view the page.

To handle this scenario in ASP.NET MVC we can create a custom helper which must meet the following conditions:
  • It must be easy and straightforward to use
  • It must return a 403 status code along with the Forbidden status
  • It must not perform a redirect but the page URL should stay the same
  • It must display a custom view to the user
My HttpForbiddenResult class inherits from the HttpStatusCodeResult class which already exists in ASP.NET MVC. In this way, the framework will automatically set the status code and the description. The complete code of the class is the following:

public class HttpForbiddenResult : HttpStatusCodeResult
{
    public override void ExecuteResult(ControllerContext context)
    {
        base.ExecuteResult(context);

        // creates the ViewResult adding ViewData and TempData parameters
        ViewResult result = new ViewResult
        {
            ViewName = "AccessDenied",
            ViewData = context.Controller.ViewData,
            TempData = context.Controller.TempData
        };

        result.ExecuteResult(context);
    }

    // calls the base constructor with 403 status code
    public HttpForbiddenResult()
        : base(HttpStatusCode.Forbidden, "Forbidden")
    {
    }
}

I have also created a view called AccessDenied within the Shared folder, which contains a custom message for the users who will view the page:

@{
    ViewBag.Title = "Access Denied";
}

<h2>Access Denied</h2>

<p>Sorry, the access to this page is denied.</p>

In order to use the helper you need just the following lines of code:

public class HomeController : Controller
{
    public ActionResult DoSomething(string taskName)
    {
        // access denied if taskName is empty
        if (string.IsNullOrEmpty(taskName))
        return new HttpForbiddenResult();

        return View();
    }
}

If you visit the URL for the previous controller without the taskName parameter, you will see the following result:


Of course, with little modifications you can create a custom helper for all the HTTP error codes!

No comments:

Post a Comment