3

I have implemented 404 handling for the general case in ASP.NET MVC 3, for when a controller/view is not found. But how should it be handled inside the controller if the user is trying to access something that can't be found? For example www.foo.bar/Games/Details/randomjunk will call this inside GamesController:

public ActionResult Details(string id) // id is 'randomjunk'
{
  if(DoesGameExist(id) == false)
    // Now what?

I could just do a return Redirect('/Errors/Http404'); but that doesn't seem like the correct way to do it. Should you throw an exception, or something else?

We could have a special view in this case, but to start with we need a good way we can apply to several cases.

Edit: I want to show my friendly 404 page I already have for the general case.

John-Philip
  • 617
  • 9
  • 20

3 Answers3

9

You should throw HttpException 404 :

throw new HttpException(404, "Page not Found");
Antonio Bakula
  • 20,445
  • 6
  • 75
  • 102
  • This does exactly what I want! The user ends up at '/Errors/Http404?aspxerrorpath=/Games/Details/randomjunk', sees a nice page, and the error is logged on the server. – John-Philip Apr 15 '12 at 15:31
5

EDIT: Apparently per Darin Dimitrov, what I had before doesn't work even with customErrors. As Antonio Bakula says in the other answer, you have to do:

throw new HttpException(404, "Not found")

Then the customErrors will work.

There's a built-in helper method called HttpNotFound so you can just do:

return HttpNotFound();

You could also explicitly return a 404 with HttpStatusCodeResult:

return new HttpStatusCodeResult(404);

HttpStatusCodeResult is helpful when there's not a specific helper method or class for the code you want.

You should also have this in your Web.config:

<customErrors>
    <error statusCode="404" redirect="~/Custom404Page.html"/>
</customErrors>

You can also have additional lines for other statuses, and a defaultRedirect.

Community
  • 1
  • 1
Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
  • Yes I tried that, but that gives the user a 404 instead of a proper webpage with an error message. I.e. when trying in Chrome then Chrome says "Oops! This link appears to be broken." instead of seeing my friendly "Can not find that page, sorry" message. – John-Philip Apr 15 '12 at 15:17
  • @John-Philip, you also need to configure it in your Web.config. I'll find the exact XML. – Matthew Flaschen Apr 15 '12 at 15:17
  • 2
  • Alternatively you could throw an HttpException with code 404, but this method does seem a lot cleaner – David Esteves Apr 15 '12 at 15:20
  • @MatthewFlaschen That's what I have, but I'm still not getting the friendly page - just the browsers own one. – John-Philip Apr 15 '12 at 15:21
  • 1
    @John-Philip, are you using IIS 7? If so, try [this question](http://stackoverflow.com/questions/434272/iis7-overrides-customerrors-when-setting-response-statuscode). – Matthew Flaschen Apr 15 '12 at 15:24
  • @MatthewFlaschen I am, but it's not displaying a general IIS error message - it's actually giving the user a status code of 404. I want my "page not found" page to show, i.e. the user gets a 200 from that page. Throwing an exception, like the other answer suggests, works exactly as I want. Is it supposed to do the same thing as your answer? – John-Philip Apr 15 '12 at 15:29
1

You could return a HttpStatusCodeResult.

return new httpStatusCodeResult(404);
Arjan Einbu
  • 13,543
  • 2
  • 56
  • 59
  • This sends a 404 Http result to the visitor, which makes the browser show it's own "page not found" instead of the website taking care of it and showing a proper branded "Sorry we couldn't find what you're looking for" page. – John-Philip Apr 15 '12 at 16:42