0

I'm developing new web site in asp net mvc 5. And I want to create custom 404 page where users who tried to access old url will be redirected. The problem is that I want to create view for this error page and take parameters from url trying to identify what product users tried to access. But I haven't found solution how to create it. All examples with editing webconfig like this:

 <defaultRedirect="~/Errors/NotFound" mode="Off">
          <error statusCode="404" redirect="~/Errors/NotFound" />      
  </customErrors>

will not pass parameters. I tried to disable custom errors and make changes in Global.asax :

public void Application_Error(object sender, EventArgs e)
        {

            Exception exception = Server.GetLastError();
            Response.Clear();

            HttpException httpException = exception as HttpException;
            if (httpException != null)
            {
                if(httpException.GetHttpCode() == 404)
                {                    
                    var rd = new RouteData();
                    rd.Values["controller"] = "Errors";
                    rd.Values["action"] = "NotFound";
                    rd.Values.Add("queryString", HttpContext.Current.Request.Url.AbsolutePath);

                    IController c = new ErrorsController();
                    c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
                }

            }
        }

But it still returns standart error page

enter image description here

dantey89
  • 2,167
  • 24
  • 37
  • I haven't seen that way of redirecting to an error page before. Have you tried using `return RedirectToAction("NotFound", "Errors");`? – Lars Kristensen Jun 07 '16 at 13:19
  • Also, what happens if you just enter the URL to your error page, `http://localhost:57623/Errors/NotFound`? – Lars Kristensen Jun 07 '16 at 13:20
  • I don't believe that passing parameters works (at least not in every case - keep in mind that if the error happens in IIS the redirect happens before ASP.NET is even called). However, [this article](https://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging) goes over the options as they apply to custom pages and logging. Do note that it is unusual to pass parameters because the best practice is to log the error and show a generic page for each status code - otherwise hackers can use the output from your website (the parameters) to find a vulnerability. – NightOwl888 Jun 07 '16 at 18:20

3 Answers3

0

You can try this:

RouteValueDictionary rvd = new RouteValueDictionary(){
{   
    { "Controller", "Errors" },
    { "Action", "NotFound" }
};
rvd["queryString"] = HttpContext.Current.Request.Url.AbsolutePath;
Response.RedirectToRoute(rvd);

Hope it makes sense.

SamGhatak
  • 1,487
  • 1
  • 16
  • 27
  • Bad thing is that this code will return status code 200 – dantey89 Jun 07 '16 at 14:02
  • 1
    You have to set the status back to 404 inside the `ErrorsController` `NotFound` action... – SamGhatak Jun 07 '16 at 14:21
  • Will it? It should cause a endless loop if you have an exception in the NotFound action, so it should reach the `Application_Error` .... I don't think it works that way only with the status set as 404... – SamGhatak Jun 07 '16 at 14:41
0

You should edit web.config like this:

   <system.web>
     <customErrors mode="On" defaultRedirect="~/Error">
      <error redirect="~/Error/NotFound" statusCode="404" />
     </customErrors>
   </system.web>
Ali Soltani
  • 9,589
  • 5
  • 30
  • 55
0

The solution was easier than I thought. When you setting custom error in webconfig

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

the requested url will be in QueryString so it is anough to get it like this:

public ActionResult NotFound()
        {                
            var requestedString = Request.QueryString["aspxerrorpath"];   
            return View();
        }
dantey89
  • 2,167
  • 24
  • 37
  • 1
    That xml doesn't look valid. The top element should be: ``. Also, it seems wrong that the default error page is a "Not Found" page. I would recommend you create a general "Error ocurred" page, and a specific one for 404. – Lars Kristensen Jun 09 '16 at 06:25
  • And one more thing, in your comment for SamGhatak's answer, you mention returning status code 200 when expecting a 404. But I think your approach would also return status code 200. There are several ways to return specific status codes. Have a look at this question: http://stackoverflow.com/questions/2948484/how-to-get-mvc-action-to-return-404 – Lars Kristensen Jun 09 '16 at 06:34
  • @LarsKristensen , About 404 status. Asp net core manualy setst 302 error when using webconfig and this is horrible. I looked at link that you posted, but I don't know where it should we written to throw 404 exception instead 302`s error throwed by asp net core – dantey89 Jun 10 '16 at 07:17
  • Status 302 is not an error, but status "Found" which is used for redirecting, which is what you do when you redirect to your error controller (In Web.config, `redirectMode` is set to `ResponseRedirect` if you don't specify it explicitly). To return a response with Status 404, add this to your `NotFound` Action, just before returning the view; `Response.StatusCode = 404;` – Lars Kristensen Jun 10 '16 at 07:53