Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show a custom 404 page in ASP.NET without redirect?

When a request is 404 in ASP.NET on IIS 7 i want a custom error page to be displayed. The URL in the address bar should not change, so no redirect. How can i do this?

like image 502
usr Avatar asked Sep 02 '09 13:09

usr


2 Answers

As a general ASP.NET solution, in the customErrors section in the web.config, add the redirectMode="ResponseRewrite" attribute.

<customErrors mode="On" redirectMode="ResponseRewrite">
  <error statusCode="404" redirect="/404.aspx" />
</customErrors>

Note: this internally uses a Server.Transfer() so the redirect must be an actual file on the webserver. It can't be an MVC route.

like image 56
warrickh Avatar answered Nov 08 '22 14:11

warrickh


I use an http module to handle this. It works for other types of errors, not just 404s, and allows you to continue using the custom errors web.config section to configure which page is displayed.

public class CustomErrorsTransferModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.Error += Application_Error;
    }

    public void Dispose()  {  }

    private void Application_Error(object sender, EventArgs e)
    {
        var error = Server.GetLastError();
        var httpException = error as HttpException;
        if (httpException == null)
            return;

        var section = ConfigurationManager.GetSection("system.web/customErrors") as CustomErrorsSection;
        if (section == null)
            return;

        if (!AreCustomErrorsEnabledForCurrentRequest(section))
            return;

        var statusCode = httpException.GetHttpCode();
        var customError = section.Errors[statusCode.ToString()];

        Response.Clear();
        Response.StatusCode = statusCode;

        if (customError != null)
            Server.Transfer(customError.Redirect);
        else if (!string.IsNullOrEmpty(section.DefaultRedirect))
            Server.Transfer(section.DefaultRedirect);
    }

    private bool AreCustomErrorsEnabledForCurrentRequest(CustomErrorsSection section)
    {
        return section.Mode == CustomErrorsMode.On ||
               (section.Mode == CustomErrorsMode.RemoteOnly && !Context.Request.IsLocal);
    }

    private HttpResponse Response
    {
        get { return Context.Response; }
    }

    private HttpServerUtility Server
    {
        get { return Context.Server; }
    }

    private HttpContext Context
    {
        get { return HttpContext.Current; }
    }
}

enable in your web.config in the same way as any other module

<httpModules>
     ...
     <add name="CustomErrorsTransferModule" type="WebSite.CustomErrorsTransferModule, WebSite" />
     ...
</httpModules>
like image 25
David Walker Avatar answered Nov 08 '22 14:11

David Walker