150

I have an action that takes in a string that is used to retrieve some data. If this string results in no data being returned (maybe because it has been deleted), I want to return a 404 and display an error page.

I currently just use return a special view that display a friendly error message specific to this action saying that the item was not found. This works fine, but would ideally like to return a 404 status code so search engines know that this content no longer exists and can remove it from the search results.

What is the best way to go about this?

Is it as simple as setting Response.StatusCode = 404?

Paul Hiles
  • 9,558
  • 7
  • 51
  • 76
  • you also have to keep Response.TrySkipIisCustomErrors = true; The answer by @ganders was a life saver... – Thunder Jan 10 '15 at 11:28

12 Answers12

156

In ASP.NET MVC 3 and above you can return a HttpNotFoundResult from the controller.

return new HttpNotFoundResult("optional description");
Christian Gollhardt
  • 16,510
  • 17
  • 74
  • 111
Stefan Paul Noack
  • 3,654
  • 1
  • 27
  • 38
121

There are multiple ways to do it,

  1. You are right in common aspx code it can be assigned in your specified way
  2. throw new HttpException(404, "Some description");
Christian Gollhardt
  • 16,510
  • 17
  • 74
  • 111
Dewfy
  • 23,277
  • 13
  • 73
  • 121
  • 1
    One thing to watch out for is that if you have a customError page set up to handle 404 then this error page will return 200 (the not found page was found... :-( ). I tend to throw the exception from say BlogController and have the NotFound action set the proper response code. – Nigel Sampson Jun 01 '10 at 22:26
  • 23
    I ended up doing: Response.StatusCode = 404; Response.TrySkipIisCustomErrors = true; return View("MyCustomView"); This works perfectly in my situation. – Paul Hiles Jun 02 '10 at 13:42
  • @PaulHiles: This is the answer for me in MVC3. Wish I could upvote it as an answer rather than a comment. – Valamas Dec 23 '14 at 20:40
  • This doesn't work, I think, if using IIS. On my test site it works fine, but on the live site the custom error page kicks in. – Andy Brown Aug 16 '17 at 11:04
  • @AndyBrown it works for IIS as well as for IIS Express, you need review your configuration of IIS (Admin console) – Dewfy Aug 16 '17 at 14:20
66

In MVC 4 and above you can use the built-in HttpNotFound helper methods:

if (notWhatIExpected)
{
    return HttpNotFound();
}

or

if (notWhatIExpected)
{
    return HttpNotFound("I did not find message goes here");
}
iCollect.it Ltd
  • 92,391
  • 25
  • 181
  • 202
27

Code :

if (id == null)
{
  throw new HttpException(404, "Your error message");//RedirectTo NoFoundPage
}

Web.config

<customErrors mode="On">
  <error statusCode="404" redirect="/Home/NotFound" />
</customErrors>
T.Rob
  • 31,522
  • 9
  • 59
  • 103
Sinan BARAN
  • 279
  • 3
  • 2
16

If you are working with .NET Core, you can return NotFound()

Robert Paulsen
  • 4,935
  • 3
  • 21
  • 27
11

I've used this:

Response.StatusCode = 404;
return null;
Wout
  • 624
  • 5
  • 14
  • Thank you. This looks way better than throwing a costly exception on server. Wonder if the 404 would be logged in IIS logs... ideally it would be. – fozylet Jan 29 '12 at 03:00
  • 3
    But, in asp.net ,this method is not a good solution, right? since the web page would display all related sensitive information of the server. – lzlstyle Nov 30 '13 at 08:33
  • 2
    One exception will take less than a millisecond to handle. Compared to the few hundred millseconds just to do a HTTP connection up and back it's meaningless. throw HttpException or return HttpNotFoundResult, manually setting the status code and returning null is terrible. – George Dec 15 '16 at 00:49
6

None of the above examples worked for me until I added the middle line below:

public ActionResult FourOhFour()
{
    Response.StatusCode = 404;
    Response.TrySkipIisCustomErrors = true; // this line made it work
    return View();
}
ganders
  • 7,285
  • 17
  • 66
  • 114
  • 2
    Are you seriously telling me the simple `return HttpNotFound();` did not work for you? How old is your system? – iCollect.it Ltd Oct 08 '14 at 12:40
  • 1
    Did you try `return HttpNotFound();`? It works just fine with MVC 4 upwards. http://msdn.microsoft.com/en-us/library/system.web.httpresponse.tryskipiiscustomerrors(v=vs.110).aspx "The TrySkipIisCustomErrors property is used only when your application is hosted in IIS 7.0. When running in Classic mode in IIS 7.0 the TrySkipIisCustomErrors property default value is true. When running in Integrated mode, the TrySkipIisCustomErrors property default value is false." – iCollect.it Ltd Oct 08 '14 at 12:57
5

In NerdDinner eg. Try it

public ActionResult Details(int? id) {
    if (id == null) {
        return new FileNotFoundResult { Message = "No Dinner found due to invalid dinner id" };
    }
    ...
}
cem
  • 1,911
  • 12
  • 16
  • Thanks, but behind the scenes, that throws an HttpException similar to suggestion number two in Dewfy's post. I am looking for a bit more control so I can display a nice error page specific to the action, not just redirecting to the controller / global 404 page. Looks as though setting the status code and returning to a custom view is the way to go for my situation. – Paul Hiles Jun 01 '10 at 15:29
4

In .NET Core 1.1:

return new NotFoundObjectResult(null);
feedthedogs
  • 413
  • 1
  • 3
  • 10
  • 2
    If you are not returning an object then return NotFound() is more appropriate but in either case, you will not get a friendly error page unless you handle it with something like StatusCodePagesWithReExecute. See https://www.devtrends.co.uk/blog/handling-404-not-found-in-asp.net-core – Paul Hiles May 19 '17 at 15:28
3

I use:

Response.Status = "404 NotFound";

This works for me :-)

bruno
  • 1,830
  • 2
  • 22
  • 36
0

You can also do:

        if (response.Data.IsPresent == false)
        {
            return StatusCode(HttpStatusCode.NoContent);
        }
-1

Please try the following demo code:

public ActionResult Test()

{
  return new HttpStatusCodeResult (404,"Not found");
}