简体   繁体   中英

Custom error pages in IIS

I have the following set-up in my web.config

<customErrors mode="RemoteOnly" defaultRedirect="/ServerError" redirectMode="ResponseRewrite"/>

<httpErrors errorMode="Custom" existingResponse="Replace">
      <remove statusCode="400" subStatusCode="-1" />
      <remove statusCode="404" subStatusCode="-1" />
      <remove statusCode="500" subStatusCode="-1" />
      <error statusCode="400" path="/error/Error400" responseMode="ExecuteURL" />
      <error statusCode="404" path="/error/Error404" responseMode="ExecuteURL" />
      <error statusCode="500" path="/error/Error500" responseMode="ExecuteURL" />
</httpErrors>

With the above configuration, our website is able to catch 404s, and display the nice 404 page served from /error/error404 with the 404 Header.

Now i have the following scenario:
1. User navigates to /action/id
2. Id is not found, i would like to return a 404, but serve a custom 404, different from the generic one served from /error/error404. ie serve a different custom page;

In my controller i have the following:

Response.StatusCode=(int)HttpStatusCode.NotFound;                          
Response.TrySkipIisCustomErrors = true;
return View("SomeView", model);

Is this something that can be achieved ?

PS: using IIS 8

LE In case anyone is interested in the solution i implemented, i have done the following:
1. In my action , i set a session variable Session["InvalidId"]=something
2. In my ErrorController i have the following:

var invalidId = Session["InvalidId"];
if(invalidId != null)
{
    return View("SomeView", model);
}

This helped me serve a different 404 page to my generic one.

Thanks for the help !

Yes, this can be easily achieved and you do not really need other pages. You need to have some session variables for custom messages and use them to determine whether you need to display some messages. If so, then display them in your view.

Algorithm:

  1. Your custom page detects an error
  2. Some error messages are generated
  3. Your custom page redirects to the error page
  4. The error page checks for error messages to be displayed
  5. If there are such error messages, then they are displayed and the error message queue is cleared

Depending on how you handle your exceptions, you could create your own exception class that inherits from HttpException .

[Serializable]
public class MyHttpException : HttpException
{
    // Constructors ...
    // You could either allow for an http status code to be passed in a 
    // constructor (to make your class more reusable) or you could call the
    // base constructor with 404 

    // Additional properties if needed ...
}

Then, in you action, when your condition is met (ie id not found) you can throw a new MyHttpException .

Your exception handling mechanism can test to see if the current exception is a MyHttpException and react to that with a custom view. It should also set the correct response status code, like you were doing.

The status code can come from MyHttpException since it is a HttpException :

(HttpStatusCode)myHttpException.GetHttpCode()

I'm not sure what controllers you have or how you capture application-wide exceptions but what I have is an ErrorController with an Index action that takes an Exception as a parameter:

public ActionResult Index(Exception exception) { ... }

It is this action that decides what gets returned based on the exception object, similar to what I described above.

Hope this helps.

PS I have a similar <httpErrors>...</httpErrors> setup in my web.config and my custom exception works with a 404 status code as described above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM