I want to be able to generate IIS's standard 404 response, not a custom 404 page, in response to an error condition in a code-behind class. My Page_Load method looks like this:
protected void Page_Load(object sender, System.EventArgs e)
{
this.a = ...
...
if (this.a == null) ... // *** generate a 404
}
So if a is not null the .aspx file renders, etc, but if a is null I want the standard "The resource cannot be found" page to be shown with a 404 response code.
If I use:
if (a == null) Response.StatusCode = 404;
(which is what seems to be the correct method according to what I can find) the page continues to render (and gives a NullReferenceException with a response code of 500 when it tries to use a).
If I use:
if (a == null) throw new HttpException(404, "Not found");
The response code is 404 but the page content is ASP.NET's unhandled exception page showing the HttpException (which is then shown as the generic "Runtime Error" when customErrors is On).
I want to show IIS's 404 page because the users will understand that, but they probably won't check the response code of the page if it shows a server error.
EDIT: It looks like I can't do this exactly. Given @Smudge202's answer I let my code-behind throw the HttpException and added code to Global.Application_Error() to handle those exceptions:
void Application_Error(object sender, EventArgs e)
{
var exception = Server.GetLastError();
if (exception is HttpException)
{
var httpException = (HttpException)exception;
if (httpException.GetHttpCode() == 404)
{
var context = HttpContext.Current;
context.Response.Clear();
context.Response.StatusCode = 404;
context.Response.StatusDescription = "Not Found";
context.Response.Write("<h1>404 Not Found</h1>");
context.Server.ClearError();
}
}
// ...
}
This lets me set my own response to the exception. This approach has two drawbacks:
- What I really wanted to do was revert control back to IIS and let it display its default 404 response, I can't find a way to do that
- The new response (written by
context.Response.Write()) is shown for every 404, not just ones generated in code
So it looks like I will need to either:
- From the code-behind, redirect to a bespoke page explaining that the 'thing' can't be found (which also sets the 404 response code), or
- Set up a custom global 404 page