Kev
Kev

Reputation: 119806

ASP.NET MVC3 still looks for Error.aspx/.cshtml despite specifying my own view

I have my ASP.NET MVC 3 application configured to redirect to an Errors controller with two actions -

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

I have a couple of views that are rendered from each of the action methods:

In my ErrorsController ApplicationError action I do the following:

public ActionResult ApplicationError()
{
    Response.StatusCode = 500;
    return View();
}

This works and my ApplicationError.cshtml view is rendered, whatever exception happened is logged, all good.

However in ELMAH I see this extra error being logged:

System.InvalidOperationException The view 'Error' or its master was not found or no view engine supports the searched locations. The following locations were searched: ~/Views/Throw/Error.aspx ~/Views/Throw/Error.ascx ~/Views/Shared/Error.aspx ~/Views/Shared/Error.ascx ~/Views/Throw/Error.cshtml ~/Views/Throw/Error.vbhtml ~/Views/Shared/Error.cshtml ~/Views/Shared/Error.vbhtml

Why is ASP.NET MVC still hunting for these views when I've already handled the error and my own view is successfully located and rendered?

Additional Information:

Upvotes: 4

Views: 1632

Answers (1)

JimmiTh
JimmiTh

Reputation: 7449

I think, although you've replaced HandleErrorAttribute with a derived class (ElmahHandleErrorAttribute), your custom attribute's OnException is probably still calling base.OnException - i.e. HandleErrorAttribute.OnException.

HandleErrorAttribute.OnException ignores the web.config settings completely (other than letting ASP.NET display the standard YSOD if customErrors are off), and sets the result of the action to a ViewResult with status code 500, and View set to "Error" (the default, when a View property hasn't been set on the attribute).

I.e., I'm guessing that something like this happens:

  1. You throw an exception
  2. ElmahHandleErrorAttribute picks it up, logs the exception, calls base.OnException
  3. HandleErrorAttribute.OnException sets the result of the action to ViewResult with View set to "Error"
  4. The ViewEngine fails to find this "Error" view, and so throws a new exception
  5. ... which is logged by ELMAH, but not picked up by ElmahHandleErrorAttribute (because this exception occured outside the action)
  6. Instead, ASP.NET itself picks it up, and uses the errorPages in web.config
  7. ... calling /Errors/ApplicationError
  8. ... which displays the view you want

... but not actually for the exception that you threw, rather the exception that the ViewEngine threw.

You may want to implement your own exception handling, rather than basing it on HandleError, if you want the web.config settings to be honored. Take a look at HandleErrorAttribute in the MVC sources (here) to see what needs to be done (and what shouldn't be done in your case).

Upvotes: 3

Related Questions