Як отримати дії MVC для повернення 404


142

У мене є дія, яка виконує рядок, який використовується для отримання деяких даних. Якщо цей рядок призводить до того, що дані не будуть повернені (можливо, тому, що вони були видалені), я хочу повернути 404 та відобразити сторінку помилки.

Зараз я просто використовую return спеціальний вигляд, який відображає дружнє повідомлення про помилку, характерне для цієї дії, вказуючи, що елемент не знайдено. Це добре працює, але в ідеалі хочеться повернути код статусу 404, щоб пошукові системи знали, що цього вмісту більше немає і можуть видалити його з результатів пошуку.

Який найкращий шлях для цього?

Це так просто, як встановити Response.StatusCode = 404?


ви також повинні зберегти Response.TrySkipIisCustomErrors = true; Відповідь @ganders була рятівницею життя ...
Грім

Відповіді:


111

Існує кілька способів зробити це,

  1. Ви маєте рацію в загальному коді aspx, який можна призначити у вказаний спосіб
  2. throw new HttpException(404, "Some description");

1
Одне, на що слід звернути увагу, це те, що якщо у вас налаштована сторінка customError для обробки 404, ця сторінка з помилками поверне 200 (не знайдена не знайдена сторінка ... :-(). Я схиляюсь викидати виняток з, наприклад, BlogController і запропонуйте дію NotFound встановити відповідний код відповіді
Найджел Сампсон

20
Я закінчив робити: Response.StatusCode = 404; Response.TrySkipIisCustomErrors = true; вигляд повернення ("MyCustomView"); Це прекрасно працює в моїй ситуації.
Пол Хілз

@PaulHiles: Це відповідь для мене в MVC3. Бажаю, щоб я міг сприйняти це як відповідь, а не коментар.
Валамас

Я думаю, це не працює, якщо використовувати IIS. На моєму тестовому сайті він працює чудово, але на веб-сайті в реальному часі починається користувацька сторінка помилок.
Енді Браун

@AndyBrown він працює як для IIS, так і для IIS Express, вам потрібно переглянути конфігурацію IIS (консолі адміністратора)
Dewfy

150

В ASP.NET MVC 3 і вище ви можете повернути HttpNotFoundResult з контролера.

return new HttpNotFoundResult("optional description");

4
використання:return new HttpNotFoundResult("optional description");
Валамас

6
Якщо ви повертаєтесь зсередини контролера, існує також зручний метод, який називається HttpNotFound(). Тож ви могли return HttpNotFound("optional description")замість цього повернутися .
Луїс Перес

1
У 2012 році речі були не такі зручні ;-)
Стефан Пол Ноак

61

У MVC 4 і вище ви можете використовувати вбудовані HttpNotFoundдопоміжні методи:

if (notWhatIExpected)
{
    return HttpNotFound();
}

або

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

26

Код:

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

Web.config

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

Крім того, всі доступні коди статусу існують у цьому переліку: HttpStatusCode.
user2173353

12

Я використовував це:

Response.StatusCode = 404;
return null;

Дякую. Це виглядає набагато краще, ніж кидати дорогий виняток на сервер. Цікаво, якби 404 увійшов до журналів IIS ... в ідеалі це було б.
фозилет

1
Але, на asp.net, цей метод не є хорошим рішенням, правда? оскільки веб-сторінка відображатиме всю пов'язану конфіденційну інформацію сервера.
lzlstyle

1
Один виняток займе менше мілісекунди для обробки. У порівнянні з кількома сотнями секунд, просто робити підключення HTTP і назад це безглуздо. кинути HttpException або повернути HttpNotFoundResult, вручну встановити код статусу і повернути null - це жахливо.
Джордж


5

У NerdDinner, наприклад. Спробуйте це

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

Дякую, але за кадром, що кидає HttpException, подібний до пропозиції номер два, у посту Dewfy. Я шукаю трохи більше контролю, щоб я міг відобразити приємну сторінку помилок, специфічну для дії, а не просто перенаправлення на контролер / глобальну сторінку 404. Схоже, встановлення коду статусу та повернення до спеціального перегляду - це спосіб вирішити мою ситуацію.
Пол Хілз

4

Жоден із наведених вище прикладів не працював для мене, поки я не додав середню лінію нижче:

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

2
Ти серйозно кажеш мені, що простий return HttpNotFound();не працював для тебе? Скільки років вашій системі?
Пройшло кодування

1
Ви пробували return HttpNotFound();? Він працює чудово з MVC 4 вгору. msdn.microsoft.com/en-us/library/… "Властивість TrySkipIisCustomErrors використовується лише тоді, коли ваша програма розміщена в IIS 7.0. При запуску в класичному режимі в IIS 7.0 значення за замовчуванням властивості TrySkipIisCustomErrors є істинним. При запуску в інтегрованому режимі , значення за замовчуванням властивості TrySkipIisCustomErrors є помилковим. "
Пройшов кодування

2

Я використовую:

Response.Status = "404 NotFound";

Це працює для мене :-)


2

У .NET Core 1.1:

return new NotFoundObjectResult(null);

1
Якщо ви не повертаєте об'єкт, то повернення NotFound () є більш підходящим, але в будь-якому випадку ви не отримаєте дружню сторінку помилки, якщо не обробляєте її з чимось на зразок StatusCodePagesWithReExecute. Дивіться devtrends.co.uk/blog/handling-404-not-found-in-asp.net-core
Пол Хілз


-1

Спробуйте скористатися наступним демо-кодом:

public ActionResult Test()

{
  return new HttpStatusCodeResult (404,"Not found");
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.