0

I have an MVC C# App and I need to display a specific view to the user when an error occurs.

So if the error is code=200, code=404, code=500 or any other error I just have to display the Error View located in ~/Views/Shared/Error.cshtml with a general message.

So my question: is it enough to add this in the global.asax

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
}

or do I also need to modify my web.config this way:

<customErrors mode="RemoteOnly">
    <error statusCode="404" redirect="~/Views/Shared/Error.cshtml"/>
    <error statusCode="500" redirect="~/Views/Shared/Error.cshtml"/>
</customErrors>

only one of the options is necessary or do I have to add the two of them?

maccettura
  • 10,514
  • 3
  • 28
  • 35
Pablo Tobar
  • 614
  • 2
  • 13
  • 37
  • `200` is not an error code. – maccettura Jun 27 '17 at 20:19
  • Also, you do not want to redirect to a `.cshtml` file, you need to redirect to an `Action` that returns a `View`. – maccettura Jun 27 '17 at 20:21
  • so the RegisterGlobalFilters option is the one I need? – Pablo Tobar Jun 27 '17 at 20:30
  • No, you need to create an `ErrorController` and an `Index` action of that controller. Then change your web.config to redirect to `~/Error`. Look at [this answer](https://stackoverflow.com/a/13905859/2457029) for examples. – maccettura Jun 27 '17 at 20:33
  • why not to use the registerGlobalFilter and in the web.config defines customErrors mode="on"...with that I suppose it will show the default error page located in Shared folder – Pablo Tobar Jun 27 '17 at 21:26

3 Answers3

1

So my question: is it enough to add this in the global.asax

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
}

No because HandleErrorAttribute will only catch error code 500 (Internal server error).

If you want to catch 404's (page not found) in addition to 500 the best way to do this is to use httpErrors because they will also catch 404's that do not match any of your defined routes.

Custom errors will only catch 404's that match a route. For example, a 404 from: http://example.com/someNonExistantFile.html will not be caught by custom errors (assuming no route exists that matches the URL). A 404 from http://example.com/ControllerName/someNonExistentAction will be caught by custom errors.

I setup httpErrors like this in web.config system.webserver section:

<httpErrors errorMode="Custom" existingResponse="Replace">
  <remove statusCode="400" subStatusCode="-1" />
  <remove statusCode="403" subStatusCode="-1" />
  <remove statusCode="404" subStatusCode="-1" />
  <remove statusCode="500" subStatusCode="-1" />
  <error statusCode="400" path="/Error/BadRequest" responseMode="ExecuteURL"/>
  <error statusCode="403" path="/Error/NotAuthorized" responseMode="ExecuteURL" />
  <error statusCode="404" path="/Error/NotFound" responseMode="ExecuteURL" />
  <error statusCode="500" path="/Error" responseMode="ExecuteURL" />
</httpErrors>

Then in my Error controller I set the http response code accordingly. Doing that prevents google and others from indexing your error pages.

Here is my ErrorController that I use:

[AllowAnonymous]
public class ErrorController : Controller
{
    public ActionResult Index()
    {
        Response.StatusCode = 500;
        return View("Error");
    }

    public ViewResult BadRequest()
    {
        Response.StatusCode = 400;
        return View("BadRequest");
    }

    public ViewResult NotFound()
    {
        Response.StatusCode = 404;
        return View("NotFound");
    }

    public ViewResult NotAuthorized()
    {
        Response.StatusCode = 403;
        return View("NotAuthorized");
    }
}
jpishko
  • 1,070
  • 1
  • 10
  • 19
1
You can use very simple approach here.

You can use  **Application_Error()** events and write it in **Global.asax** 
file.Its called automatically whenever system generates any type of error

Note : Create "ErrorController" and inside that make one view with name 
"Errors.cshtml"


protected void  Application_Error(object sender, EventArgs e)
{
        if (null != Context && null != Context.AllErrors)
        {
            Exception exception = Server.GetLastError().GetBaseException();

              RouteData routeData = new RouteData();
                routeData.Values.Add("controller", "Error");
                if (exception == null)
                {
                    routeData.Values.Add("action", "Index");
                }
                else
                {
                    routeData.Values.Add("action", "Errors");
                    routeData.Values.Add("exceptionValue", exception);
                }

                Response.TrySkipIisCustomErrors = true;
                IController errorController = new ErrorsController();
                errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
            }

  }
Dilip Oganiya
  • 1,504
  • 12
  • 20
0

You can create custom filter in base control and then apply that filter in every controller, so when any error is occur it will catch in common logic and render defined view/html.

Please have a look at below thread. I have described how to handle server as well as client side error in attribute.

Error handeling in MVC