Como obter a ação MVC para retornar 404

142

Eu tenho uma ação que leva em uma seqüência que é usada para recuperar alguns dados. Se essa sequência resultar em nenhum dado sendo retornado (talvez porque tenha sido excluído), desejo retornar um 404 e exibir uma página de erro.

Atualmente, apenas uso retornar uma exibição especial que exibe uma mensagem de erro amigável específica para esta ação dizendo que o item não foi encontrado. Isso funciona bem, mas o ideal é retornar um código de status 404 para que os mecanismos de pesquisa saibam que esse conteúdo não existe mais e possam removê-lo dos resultados da pesquisa.

Qual é a melhor maneira de fazer isso?

É tão simples quanto definir Response.StatusCode = 404?

Paul Hiles
fonte
você também precisa manter Response.TrySkipIisCustomErrors = true; A resposta por @ganders foi um salva-vidas ...
Trovão

Respostas:

111

Existem várias maneiras de fazer isso,

  1. Você está certo no código aspx comum que pode ser atribuído da maneira especificada
  2. throw new HttpException(404, "Some description");
Dewfy
fonte
1
Uma coisa a ser observada é que, se você tiver uma página customError configurada para manipular 404, essa página de erro retornará 200 (a página não encontrada foi encontrada ... :-(). Costumo lançar a exceção dizendo BlogController e ter a ação NotFound definir o código de resposta adequada.
Nigel Sampson
20
Acabei fazendo: Response.StatusCode = 404; Response.TrySkipIisCustomErrors = true; retornar View ("MyCustomView"); Isso funciona perfeitamente na minha situação.
Paul Hiles
@PaulHiles: Esta é a resposta para mim no MVC3. Gostaria de poder votá-lo como uma resposta e não como um comentário.
Valamas 23/12
Acho que isso não funciona se estiver usando o IIS. No meu site de teste, ele funciona bem, mas no site ativo a página de erro personalizada entra em ação.
Andy Brown
@AndyBrown funciona para o IIS, bem como para o IIS Express, você precisa revisar sua configuração do IIS (Admin Console)
Dewfy
150

No ASP.NET MVC 3 e acima, você pode retornar um HttpNotFoundResult do controlador.

return new HttpNotFoundResult("optional description");
Stefan Paul Noack
fonte
4
uso:return new HttpNotFoundResult("optional description");
Valamas
6
Se você estiver retornando de dentro do controlador, também haverá um método de conveniência chamado HttpNotFound(). Então você pode voltar return HttpNotFound("optional description").
22416 Luis Perez
1
Coisas wren't que volta conveniente em 2012 ;-)
Stefan Paul Noack
61

No MVC 4 e acima, você pode usar os HttpNotFoundmétodos auxiliares internos:

if (notWhatIExpected)
{
    return HttpNotFound();
}

ou

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

Código:

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

Web.config

<customErrors mode="On">
  <error statusCode="404" redirect="/Home/NotFound" />
</customErrors>
Sinan BARAN
fonte
Além disso, todos os códigos de status disponíveis existem nesta enumeração: HttpStatusCode.
User2173353
12

Eu usei isso:

Response.StatusCode = 404;
return null;
Wout
fonte
Obrigado. Isso parece muito melhor do que lançar uma exceção cara no servidor. Gostaria de saber se o 404 seria registrado nos logs do IIS ... idealmente seria.
Fozylet
1
Mas, no asp.net, esse método não é uma boa solução, certo? pois a página da web exibia todas as informações confidenciais relacionadas do servidor.
Lzlstyle
1
Uma exceção levará menos de um milissegundo para lidar. Comparado às poucas centenas de milésimos de segundo apenas para fazer uma conexão HTTP de volta e de volta, não faz sentido. jogue HttpException ou retorne HttpNotFoundResult, definir manualmente o código de status e retornar nulo é terrível.
George
10

Se você estiver trabalhando com o .NET Core, poderá return NotFound()

Robert Paulsen
fonte
5

No NerdDinner, por exemplo. Experimente -o

public ActionResult Details(int? id) {
    if (id == null) {
        return new FileNotFoundResult { Message = "No Dinner found due to invalid dinner id" };
    }
    ...
}
cem
fonte
Obrigado, mas nos bastidores, isso gera uma HttpException semelhante à sugestão número dois no post de Dewfy. Estou procurando um pouco mais de controle para poder exibir uma boa página de erro específica para a ação, não apenas redirecionando para a página 404 global / do controlador. Parece que definir o código de status e retornar a uma exibição personalizada é o caminho a seguir para minha situação.
Paul Hiles
4

Nenhum dos exemplos acima funcionou para mim até eu adicionar a linha do meio abaixo:

public ActionResult FourOhFour()
{
    Response.StatusCode = 404;
    Response.TrySkipIisCustomErrors = true; // this line made it work
    return View();
}
ganders
fonte
2
Você está me dizendo seriamente que o simples return HttpNotFound();não funcionou para você? que idade tem o seu sistema?
Gone Coding
1
Você tentou return HttpNotFound();? Funciona muito bem com o MVC 4 para cima. msdn.microsoft.com/en-us/library/… "A propriedade TrySkipIisCustomErrors é usada apenas quando o aplicativo está hospedado no IIS 7.0. Ao executar no modo Clássico no IIS 7.0, o valor padrão da propriedade TrySkipIisCustomErrors é verdadeiro. Ao executar no modo Integrado , o valor padrão da propriedade TrySkipIisCustomErrors é false. "
Gone Coding
2

Eu uso:

Response.Status = "404 NotFound";

Isso funciona para mim :-)

bruno
fonte
2

No .NET Core 1.1:

return new NotFoundObjectResult(null);
feedthedogs
fonte
1
Se você não estiver retornando um objeto, o retorno de NotFound () é mais apropriado, mas em ambos os casos, você não receberá uma página de erro amigável, a menos que a lide com algo como StatusCodePagesWithReExecute. Veja devtrends.co.uk/blog/handling-404-not-found-in-asp.net-core
Paul Hiles
0

Você também pode fazer:

        if (response.Data.IsPresent == false)
        {
            return StatusCode(HttpStatusCode.NoContent);
        }
Christof Mehlstäubler
fonte
-1

Por favor, tente o seguinte código de demonstração:

public ActionResult Test()

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