Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC Custom Error Pages with Magical Unicorn

my question is regarding Pure.Kromes answer to this post. I tried implementing my pages' custom error messages using his method, yet there are some problems I can't quite explain.

a) When I provoke a 404 Error by entering in invalid URL such as localhost:3001/NonexistantPage, it defaults to the ServerError() Action of my error controller even though it should go to NotFound(). Here is my ErrorController:

    public class ErrorController : Controller
    {
        public ActionResult NotFound()
        {
            Response.TrySkipIisCustomErrors = true;
            Response.StatusCode = (int)HttpStatusCode.NotFound;
            var viewModel = new ErrorViewModel()
            {
                ServerException = Server.GetLastError(),
                HTTPStatusCode = Response.StatusCode
            };
            return View(viewModel);
        }

        public ActionResult ServerError()
        {
            Response.TrySkipIisCustomErrors = true;
            Response.StatusCode = (int)HttpStatusCode.InternalServerError;

            var viewModel = new ErrorViewModel()
            {
                ServerException = Server.GetLastError(),
                HTTPStatusCode = Response.StatusCode
            };
            return View(viewModel);
        }
    }

My error routes in Global.asax.cs:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });

        routes.MapRoute(
            name: "Error - 404",
            url: "NotFound",
            defaults: new { controller = "Error", action = "NotFound" }
            );

        routes.MapRoute(
            name: "Error - 500",
            url: "ServerError",
            defaults: new { controller = "Error", action = "ServerError" }
            );


And my web.config settings:

<system.web>
    <customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="/ServerError">
    <error statusCode="404" redirect="/NotFound" />
</customErrors>
...
</system.web>

<system.webServer>
    <httpErrors errorMode="Custom" existingResponse="Replace">
      <remove statusCode="404" subStatusCode="-1" />
      <error statusCode="404" path="/NotFound" responseMode="ExecuteURL" />
      <remove statusCode="500" subStatusCode="-1" />
      <error statusCode="500" path="/ServerError" responseMode="ExecuteURL" />
</httpErrors>
...

The Error views are located in /Views/Error/ as NotFound.cshtml and ServerError.cshtml.

b) One funny thing is, When a server error occurs, it does in fact display the Server Error view I defined, however it also outputs a default error message as well saying that the Error page could not be found.

Here's how it looks like:


Do you have any advice how I could fix these two problems? I really like Pure.Kromes approach to implementing these error messages, but if there are better ways of achieving this don't hestitate to tell me.

Thanks!

**EDIT : ** I can directly navigate to my views through the ErrorController by accessing /Error/NotFound or Error/ServerError.

The views themselves only contain some text, no markup or anything.

As I said, it actually works in some way, just not the way I intended it to work. There seems to be an issue with the redirect in the web.config, but I haven't been able to figure it out.

like image 993
FLClover Avatar asked Nov 03 '22 12:11

FLClover


1 Answers

there is one more issue with that setup, when you have more complex routes and have several segments ex.

http://localhost:2902/dsad/dadasdmasda/ddadad/dadads/ddadad/dadadadad/

I got server error ->

Sorry, an error occurred while processing your request.


Exception: An error occured while trying to Render the custom error view which you provided, for this HttpStatusCode. ViewPath: ~/Views/Error/NotFound.cshtml; Message: The RouteData must contain an item named 'controller' with a non-empty string value.
Source: 

my solution for that was to add additional route at the end after default route

        routes.MapRoute(
            "Default Catch all 404",
            "{controller}/{action}/{*catchall}",
            new { controller = "Error", action = "NotFound" }
        );

hope it could help someone:-)

like image 57
krknapik14 Avatar answered Nov 11 '22 16:11

krknapik14