I'm trying to throw an HTTP 403 error code back at the client. I've read that HttpException is the cleanest way to accomplish this, but it's not working for me. I throw the exception from within a page like this:
throw new HttpException(403,"You must be logged in to access this resource.");
However, this will only give a standard ASP.Net stack trace(with 500 error) when CustomErrors is off. If CustomErrors is on, then this will not redirect to the page I have setup to be displayed when a 403 error occurs. Should I forget about HttpException and instead set all the HTTP codes myself? How do I fix this?
The custom errors part of my Web.Config is this:
<customErrors mode="On" defaultRedirect="GenericErrorPage.html">
<error statusCode="403" redirect="Forbidden.html" />
</customErrors>
Instead of getting Forbidden.html, I'll get GenericErrorPage.html
You need to override Application error like this:
protected void Application_Error()
{
var exception = Server.GetLastError();
var httpException = exception as HttpException;
Response.Clear();
Server.ClearError();
var routeData = new RouteData();
routeData.Values["controller"] = "Errors";
routeData.Values["action"] = "General";
routeData.Values["exception"] = exception;
Response.StatusCode = 500;
if (httpException != null)
{
Response.StatusCode = httpException.GetHttpCode();
switch (Response.StatusCode)
{
case 403:
routeData.Values["action"] = "Http403";
break;
case 404:
routeData.Values["action"] = "Http404";
break;
}
}
IController errorsController = new ErrorsController();
var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
errorsController.Execute(rc);
}
Then you've got to add the errorsController:
public class ErrorsController : Controller
{
public ActionResult General(Exception exception)
{
ViewBag.ErrorCode = Response.StatusCode;
ViewBag.Message = "Error Happened";
//you should log your exception here
return View("Index");
}
public ActionResult Http404()
{
ViewBag.ErrorCode = Response.StatusCode;
ViewBag.Message = "Not Found";
return View("Index");
}
public ActionResult Http403()
{
ViewBag.Message = Response.StatusCode;
ViewBag.Message = "Forbidden";
return View("Index");
}
}
And last create a view in for errorsController. I created just one view called index in Views/Errors/.