0

I have a MVC3 site were I'm trying to build a custom errorpage for a small site that access content from a database.

In my config I got:

<system.web>
  <customErrors mode="On">
    <error statusCode="404" redirect="/404" />
    <error statusCode="500" redirect="/error/500.html" />
  </customErrors>

The /404 route works when I access it directly in the browser.

Now the standard "404 page not found" shows.

In my controller I got:

public ActionResult ShowPage(int test)
{
     var page = _rep.GetPage(test);

     if(page == null)
         return HttpNotFound();    
     //....
}

What might be missing here? Feels like its something missing in the config

Lasse Edsvik
  • 9,070
  • 16
  • 73
  • 109

2 Answers2

2

For custom errors I always put the following method in global.asax, this will activate my error controller (base on this SO answer https://stackoverflow.com/a/5229581/426840):

protected void Application_Error()
        {
            var exception = Server.GetLastError();
            var httpException = exception as HttpException;

            // Don't execute error controller for custom error mesages when custom error is disabled
            if (!HttpContext.Current.IsCustomErrorEnabled) return;

            Response.Clear();
            Server.ClearError();

            Response.StatusCode = 500;

            // Avoid IIS messing with custome errors https://stackoverflow.com/a/1719474/426840
            // Also https://stackoverflow.com/a/2345742/426840 for web.config
            Response.TrySkipIisCustomErrors = true;

            if (httpException != null)
            {
                Response.StatusCode = httpException.GetHttpCode();
            }

            var routeData = new RouteData();
            routeData.Values["controller"] = "Error";
            routeData.Values["action"] = Response.StatusCode != 404 ? "Index" : "NotFound";
            routeData.Values["exception"] = exception;
            routeData.Values["logId"] = logId;

            IController errorsController = new ErrorController();

            var rc = new RequestContext(new HttpContextWrapper(Context), routeData);

            errorsController.Execute(rc);
        }

The error controller:

public class ErrorController : AuthorizedController
    {
        public ActionResult Index(string logId)
        {
            if (Request.IsAjaxRequest())
            {
                return new HttpStatusCodeResult(Response.StatusCode, Response.StatusDescription);
            }

            ViewBag.HttpStatusCode = Response.StatusCode;
            ViewBag.HttpStatusMessage = Response.StatusDescription;
            ViewBag.LogId = logId;

            return View("Error");
        }

        public ActionResult NotFound(string logId)
        {
            if (Request.IsAjaxRequest())
            {
                return new HttpStatusCodeResult(Response.StatusCode, Response.StatusDescription);
            }

            ViewBag.HttpStatusCode = Response.StatusCode;
            ViewBag.HttpStatusMessage = Response.StatusDescription;
            ViewBag.LogId = logId;

            return View("NotFound");
        }
    }

Web.config:

<customErrors mode="On" />

<system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <!-- Avoid IIS messing with custom errors https://stackoverflow.com/a/2345742/426840 -->
    <httpErrors existingResponse="PassThrough" />

  </system.webServer>

This works for 404, but also other for all other errors.

Community
  • 1
  • 1
Robin van der Knaap
  • 4,060
  • 2
  • 33
  • 48
1

The HttpNotFound result returns an empty view. You need to throw an exception

if(page == null)
    throw new HttpException(404, "Not found")
Alex
  • 7,728
  • 3
  • 35
  • 62
  • I changed to that, and the default http IIS errorpage shows (and 404 status on the page ofc). But no redirect to my /404 route – Lasse Edsvik Sep 13 '13 at 06:41