How to handle 404 Not Found Error in Asp.Net core?

Asp.net-core By Sagar Jaybhay

Different Ways to handle status code errors in asp.net core by sagar jaybhay

If resources are not found for specific value or id.

In this, we need to redirect user to custom error page where he can find the error message that for corresponding value he didn’t found any information in our scenario student not found for the corresponding student id. Means in this we need to display an error message in a way that end user will understand that whatever he looking for is not found on the server.

In our home controller in Details method we check the is there any student present for corresponding studentid on database if it found null then we redirect our user to custom error page.

Code in controller

public ViewResult Details(int id)
        {
            HmDetailsVM hmDetailsVM = new HmDetailsVM();
            hmDetailsVM.student = _repository.GetStudents(id);

            if (hmDetailsVM.student == null)
            {
                return View("ErrorPage",id);
            }

            hmDetailsVM.DivisonOfStudent = "9-A";
            ViewBag.TitleNew = "Student Info";
            return View(hmDetailsVM);
        }

Code in Html View:

@model  int


@{
    ViewData["Title"] = "ErrorPage";
}

<h1>Custom Error Page</h1>


<div class="row alert-danger">
    
    For Student You Looking For is Not Found On The server whose StudentID:@Model
    
    
</div>

The URL does not match with any route means whatever URL user entered is not present on that controller or our route map.  Means if you entered some URL like https://domain.com/something/unexpected which is not present on your domain then we need to address this

So in this we are going to handle 404 pages not found error by centralize way. Below are the 3 middle-wares are used to handle status code errors.

We know that configure method in startup class which handles our http request processing pipeline.

UseStatusCodePages

This middleware comes with the default response handler with status code 400 to 599 which do not have response body. We rarely use this in real world application because it’s simple and only text response. In production scenario we need to display some custom page error message so StatusCodePagesWithRedirect and UseStatusCodePagesWithRexecute are used.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            DeveloperExceptionPageOptions pageOptions = new DeveloperExceptionPageOptions {SourceCodeLineCount = 10};
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage(pageOptions);
            }
            else
            {
                app.UseStatusCodePages();
            }

            app.UseStaticFiles();
            app.UseHsts();
            app.UseMvc(routes =>
            {
                routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}");
            });
        }

Output of UseStatusCodePages

UseStatusCodePagesWithRedirects

In this middleware when we have no success URL then we can use this to redirect the user to our custom error page by giving URL to this method parameter. In this middleware we pass controller name and action name to this middleware. So if any URL doesn’t match it will redirect our route to custom Error page.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            DeveloperExceptionPageOptions pageOptions = new DeveloperExceptionPageOptions {SourceCodeLineCount = 10};
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage(pageOptions);
            }
            else
            {
                app.UseStatusCodePagesWithRedirects("/Error/StatusCodeHandle");
            }

            app.UseStaticFiles();
            app.UseHsts();
            app.UseMvc(routes =>
            {
                routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}");
            });

Now, this is Simple But if we want to show different messages based on status code then we need to modify above method a bit as follows.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            DeveloperExceptionPageOptions pageOptions = new DeveloperExceptionPageOptions {SourceCodeLineCount = 10};
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage(pageOptions);
            }
            else
            {
                app.UseStatusCodePagesWithRedirects("/Error/{0}");
            }

            app.UseStaticFiles();
            app.UseHsts();
            app.UseMvc(routes =>
            {
                routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}");
                //routes.MapRoute(name: "default", template: "sagar/{controller=Home}/{action=Index}/{id?}");
            });

        }

And controller code like below

[Route("Error/{StatusCode}")]
        public IActionResult StatusCodeHandle(int statusCode)
        {
            switch (statusCode)
            {
                case 404:
                    ViewBag.ErrorMessasge = $"I am having {statusCode}" +" Error code Message";
                    break;
                    
            }
            

            return View(statusCode);
        }

Steps to handle 404 Error

1) Include status code page in the startup class’s configure method.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            DeveloperExceptionPageOptions pageOptions = new DeveloperExceptionPageOptions {SourceCodeLineCount = 10};
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage(pageOptions);
            }
            else
            {
                app.UseStatusCodePagesWithRedirects("/Error/{0}");
            }

            app.UseStaticFiles();
            app.UseHsts();
            app.UseMvc(routes =>
            {
                routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}");
                //routes.MapRoute(name: "default", template: "sagar/{controller=Home}/{action=Index}/{id?}");
            });
            
        }

2. Implement Error controller means you need to add Error Controller in your project with a method.

3. Add a corresponding view to that error controllers method.

What is the difference between UseStatusCodePagesWithRedirects and UseStatusCodePagesWithReExecute?

UseStatusCodePagesWithRedirects and UseStatusCodePagesWithReExecute these both methods are static methods and used to send custom error page with different messages based on status code.

But the key difference between them is that when you use UseStatusCodePagesWithRedirects it will first send 302 response to browser and after that again it will give 200 response to browser which is not good behavior as per end-user the output which it produces is correct and good but the way it does is something not good.

Also it will change the URL which we enter in our application I hit the URL https://localhost:44387/foo/boo but the output URL is completely different. See below image and responses present in the network tab.

So see in above image it issues redirect so the URL in the address bar changes.

Also it returns a success status code when actually error occurred which isn’t semantically correct.

In UseStatusCodePagesWithReExecute the response is the same but when you see the response from server first it sends 404 response only and our URL is not changed.

In UseStatusCodePagesWithReExecute it re-executes the pipeline and return original status code 404.

It re-executes the pipeline and not issue a redirect request, we also preserve the original URL in the address bar.

Sagar Jaybhay, from Maharashtra, India, is currently a Senior Software Developer. He has continuously grown in the roles that he has held in the more than seven years he has been with this company. Sagar Jaybhay is an excellent team member and prides himself on his work contributions to his team and company as a whole.

Related posts