Jak uzyskać akcję MVC, aby zwrócić 404


142

Mam akcję, która przyjmuje ciąg, który jest używany do pobierania niektórych danych. Jeśli ten ciąg nie powoduje zwrócenia żadnych danych (być może dlatego, że zostały usunięte), chcę zwrócić 404 i wyświetlić stronę błędu.

Obecnie używam po prostu powrotu specjalnego widoku, który wyświetla przyjazny komunikat o błędzie specyficzny dla tej akcji, informujący, że element nie został znaleziony. Działa to dobrze, ale najlepiej byłoby zwrócić kod stanu 404, aby wyszukiwarki wiedziały, że ta treść już nie istnieje i mogą ją usunąć z wyników wyszukiwania.

Jaki jest najlepszy sposób rozwiązania tego problemu?

Czy jest to tak proste, jak ustawienie Response.StatusCode = 404?


musisz także zachować Response.TrySkipIisCustomErrors = true; Odpowiedź @ganders uratowała życie ...
Grzmot

Odpowiedzi:


111

Można to zrobić na wiele sposobów,

  1. Masz rację we wspólnym kodzie aspx, który można przypisać w określony sposób
  2. throw new HttpException(404, "Some description");

1
Jedną rzeczą, na którą należy zwrócić uwagę, jest to, że jeśli masz stronę CustomError skonfigurowaną do obsługi 404, ta strona błędu zwróci 200 (nie znaleziono strony ... :-(). Zwykle zgłaszam wyjątek od powiedz BlogController i niech akcja NotFound ustawi właściwy kod odpowiedzi
Nigel Sampson

20
Skończyło się na zrobieniu: Response.StatusCode = 404; Response.TrySkipIisCustomErrors = true; return View ("MyCustomView"); Działa to doskonale w mojej sytuacji.
Paul Hiles

@PaulHiles: To jest odpowiedź dla mnie w MVC3. Chciałbym móc zagłosować jako odpowiedź, a nie komentarz.
Valamas,

Myślę, że to nie działa, jeśli używasz IIS. Na mojej stronie testowej działa dobrze, ale w witrynie aktywnej uruchamia się niestandardowa strona błędu.
Andy Brown

@AndyBrown działa zarówno dla IIS, jak i IIS Express, musisz przejrzeć swoją konfigurację IIS (konsola administracyjna)
Dewfy

150

W ASP.NET MVC 3 i nowszych można zwrócić HttpNotFoundResult z kontrolera.

return new HttpNotFoundResult("optional description");

4
użycie:return new HttpNotFoundResult("optional description");
Valamas

6
Jeśli wracasz z poziomu kontrolera, istnieje również wygodna metoda o nazwie HttpNotFound(). Więc możesz return HttpNotFound("optional description")zamiast tego wrócić .
Luis Perez

1
W 2012 roku nie było już tak wygodnie ;-)
Stefan Paul Noack

61

W MVC 4 i nowszych możesz użyć wbudowanych HttpNotFoundmetod pomocniczych:

if (notWhatIExpected)
{
    return HttpNotFound();
}

lub

if (notWhatIExpected)
{
    return HttpNotFound("I did not find message goes here");
}

26

Kod :

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

Web.config

<customErrors mode="On">
  <error statusCode="404" redirect="/Home/NotFound" />
</customErrors>

Ponadto wszystkie dostępne kody stanu istnieją w tym wyliczeniu: HttpStatusCode.
user2173353

12

Użyłem tego:

Response.StatusCode = 404;
return null;

Dziękuję Ci. Wygląda to o wiele lepiej niż rzucenie kosztownego wyjątku na serwer. Zastanawiam się, czy 404 byłby zalogowany w dziennikach IIS ... Idealnie byłoby.
fozylet

1
Ale w asp.net ta metoda nie jest dobrym rozwiązaniem, prawda? ponieważ strona internetowa wyświetlałaby wszystkie powiązane poufne informacje serwera.
lzlstyle

1
Obsługa jednego wyjątku zajmie mniej niż milisekundę. W porównaniu z kilkuset milisekundami, które wystarczyło na wykonanie połączenia HTTP w górę iz powrotem, jest to bez znaczenia. throw HttpException lub return HttpNotFoundResult, ręczne ustawienie kodu stanu i zwrócenie wartości null jest straszne.
George,


5

W NerdDinner np. Spróbuj go

public ActionResult Details(int? id) {
    if (id == null) {
        return new FileNotFoundResult { Message = "No Dinner found due to invalid dinner id" };
    }
    ...
}

Dzięki, ale za kulisami generuje HttpException podobny do sugestii numer dwa w poście Dewfy. Szukam nieco większej kontroli, aby móc wyświetlić ładną stronę błędu specyficzną dla akcji, a nie tylko przekierowującą do kontrolera / globalnej strony 404. Wygląda na to, że ustawienie kodu stanu i powrót do widoku niestandardowego jest sposobem na rozwiązanie mojej sytuacji.
Paul Hiles

4

Żaden z powyższych przykładów nie działał dla mnie, dopóki nie dodałem środkowej linii poniżej:

public ActionResult FourOhFour()
{
    Response.StatusCode = 404;
    Response.TrySkipIisCustomErrors = true; // this line made it work
    return View();
}

2
Naprawdę mówisz mi, że prostota return HttpNotFound();nie działa dla ciebie? Ile lat ma Twój system?
Gone Coding

1
Próbowałeś return HttpNotFound();? Działa dobrze z MVC 4 w górę. msdn.microsoft.com/en-us/library/… "Właściwość TrySkipIisCustomErrors jest używana tylko wtedy, gdy aplikacja jest hostowana w usługach IIS 7.0. W przypadku uruchamiania w trybie klasycznym w usługach IIS 7.0 wartością domyślną właściwości TrySkipIisCustomErrors jest true. Podczas pracy w trybie zintegrowanym , domyślną wartością właściwości TrySkipIisCustomErrors jest false. "
Gone Coding

2

Używam:

Response.Status = "404 NotFound";

To działa dla mnie :-)




-1

Wypróbuj następujący kod demonstracyjny:

public ActionResult Test()

{
  return new HttpStatusCodeResult (404,"Not found");
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.