38
votes

In my ASP.NET web application, I have defined custom error pages in my web.config file as follows:

<customErrors mode="On" defaultRedirect="~/default.html">
     <error statusCode="404" redirect="~/PageNotFound.html" />
</customErrors>

In the case of a 404 error, my site redirects to the default.html page, but it passes "aspxerrorpath" as a query string parameter to the custom error page as follows:

http://www.example.com/default.html?aspxerrorpath=/somepathcausederror/badpage.aspx

I don't want that behavior. I want the redirect URL to simply read:

http://www.example.com/default.html

Is there a way to achieve this?

11

11 Answers

72
votes

If you supply your own query string variable when specifying the path, then .NET will NOT tack on the "aspxerrorpath". Who knew?

For example:

<customErrors mode="On" defaultRedirect="errorpage.aspx?error=1" >

This will do the trick. I had to add this to a bunch of apps since URLScan for IIS by default rejects anything with "aspxerrorpath" in it anyway.

11
votes

In the global.asax, catch the 404 error and redirect to the file not found page. I didn't require the aspxerrorpath and it worked a treat for me.

void Application_Error(object sender, EventArgs e)
{
    Exception ex = Server.GetLastError();
    if (ex is HttpException && ((HttpException)ex).GetHttpCode() == 404)
    {
        Response.Redirect("~/filenotfound.aspx");
    }
    else
    {
        // your global error handling here!
    }
}
6
votes

You could just send your own url params to the error page

<customErrors mode="On" defaultRedirect="~/default.html?404"> 
               <error statusCode="404" redirect="~/PageNotFound.html?404" /> 
</customErrors>
2
votes

My first thought would be to create a HttpHandler which catches url's with aspxerrorpath in it, and strips it. You could probably do the same with the rewrite module in IIS7 as well.

2
votes

I think you'd instead implement/use the Application_Error event in Global.asax, and do your processing/redirects there.

Providing you call Server.ClearError in that handler, I don't think it will use the customErrors config at all.

2
votes

I use javascript like

if (location.search != "") { window.location.href = "/404.html"; } 
1
votes

Add redirectMode="ResponseRewrite" in the Custom Error like this,

<customErrors mode="On" defaultRedirect="~/NotFound">
     <error statusCode="404" redirect="~/NotFound" redirectMode="ResponseRewrite"/>
</customErrors>

this solution works for me.

0
votes

If you remove aspxerrorpath=/ and you use response redirect during error handling you'll get exception there will be redirection loop.

0
votes

The best solution (more a workaround..) I implemented since now to prevent aspxerrorpath issue continuing to use ASP.NET CustomErrors support, is redirect to the action that implements Error handling.

These are some step of my solution in an ASP.NET MVC web app context:

First enable custom errors module in web.config

<customErrors mode="On" defaultRedirect="~/error/500">
  <error statusCode="404" redirect="~/error/404"/>
</customErrors>

Then define a routing rule:

routes.MapRoute(
   name: "Error",
   url: "error/{errorType}/{aspxerrorpath}",
   defaults: new { controller = "Home", action = "Error", errorType = 500, aspxerrorpath = UrlParameter.Optional },
);

Finally implement following action (and related views..):

public ActionResult Error(int errorType, string aspxerrorpath)
{
   if (!string.IsNullOrEmpty(aspxerrorpath)) {
      return RedirectToRoute("Error", errorType);
   }

   switch (errorType) {
      case 404:
           return View("~/Views/Shared/Errors/404.cshtml");

       case 500:
        default:
           return View("~/Views/Shared/Errors/500.cshtml");
    }
}
0
votes

In my case, i prefer not use Web.config. Then i created code above in Global.asax file:

protected void Application_Error(object sender, EventArgs e)
    {
        Exception ex = Server.GetLastError();

        //Not Found (When user digit unexisting url)
        if(ex is HttpException && ((HttpException)ex).GetHttpCode() == 404)
        {
            HttpContextWrapper contextWrapper = new HttpContextWrapper(this.Context);

            RouteData routeData = new RouteData();
            routeData.Values.Add("controller", "Error");
            routeData.Values.Add("action", "NotFound");

            IController controller = new ErrorController();
            RequestContext requestContext = new RequestContext(contextWrapper, routeData);
            controller.Execute(requestContext);
            Response.End();
        }
        else //Unhandled Errors from aplication
        {
            ErrorLogService.LogError(ex);
            HttpContextWrapper contextWrapper = new HttpContextWrapper(this.Context);

            RouteData routeData = new RouteData();
            routeData.Values.Add("controller", "Error");
            routeData.Values.Add("action", "Index");

            IController controller = new ErrorController();
            RequestContext requestContext = new RequestContext(contextWrapper, routeData);
            controller.Execute(requestContext);
            Response.End();
        }
    }

And thtat is my ErrorController.cs

public class ErrorController : Controller
{
    // GET: Error
    public ViewResult Index()
    {
        Response.StatusCode = 500;
        Exception ex = Server.GetLastError();
        return View("~/Views/Shared/SAAS/Error.cshtml", ex);
    }

    public ViewResult NotFound()
    {
        Response.StatusCode = 404;
        return View("~/Views/Shared/SAAS/NotFound.cshtml");
    }
}

And that is my ErrorLogService.cs

//common service to be used for logging errors
public static class ErrorLogService
{
    public static void LogError(Exception ex)
    {
        //Do what you want here, save log in database, send email to police station
    }
}
0
votes

If you want to resolve or handle error request you can insert into Handler try catch statement. like this:

try {
  //  Block of code that generate error
}
catch(Exception e) {
  //  Block of code to handle errors ||| HERE you can put error in your response and handle it without get xhr redirect error.
}