Se for dada a rota:
{FeedName} / {ItemPermalink}
ex: / Blog / Hello-World
Se o item não existir, desejo retornar um 404. Qual é a maneira certa de fazer isso na ASP.NET MVC?
asp.net
asp.net-mvc
http-status-code-404
Daniel Schaffer
fonte
fonte
Respostas:
Tirando fotos do quadril (codificação de cowboy ;-)), sugiro algo assim:
Controlador:
HttpNotFoundResult:
Usando essa abordagem, você cumpre os padrões da estrutura. Já existe um HttpUnauthorizedResult lá, então isso simplesmente estenderia a estrutura aos olhos de outro desenvolvedor que manterá seu código posteriormente (você sabe, o psicopata que sabe onde você mora).
Você poderia usar o refletor para dar uma olhada na montagem para ver como o HttpUnauthorizedResult é alcançado, porque eu não sei se essa abordagem deixa escapar alguma coisa (parece quase muito simples).
Eu usei o refletor para dar uma olhada no HttpUnauthorizedResult agora mesmo. Parece que eles estão definindo o StatusCode na resposta para 0x191 (401). Embora isso funcione para 401, usando 404 como o novo valor, parece que estou recebendo apenas uma página em branco no Firefox. O Internet Explorer mostra um 404 padrão (não a versão ASP.NET). Usando a barra de ferramentas do webdeveloper, inspecionei os cabeçalhos no FF, que mostram uma resposta 404 Not Found. Pode ser simplesmente algo que configurei incorretamente no FF.
Dito isso, acho que a abordagem de Jeff é um bom exemplo de KISS. Se você realmente não precisa da verbosidade neste exemplo, seu método também funciona bem.
fonte
Nós fazemos assim; este código é encontrado em
BaseController
chamado assim
fonte
fonte
web.config
.O HttpNotFoundResult é uma ótima primeira etapa para o que estou usando. Retornar um HttpNotFoundResult é bom. Então a questão é: o que vem a seguir?
Eu criei um filtro de ação chamado HandleNotFoundAttribute que mostra uma página de erro 404. Uma vez que retorna uma visão, você pode criar uma visão 404 especial por controlador, ou vamos usar uma visão 404 compartilhada padrão. Ele ainda será chamado quando um controlador não tiver a ação especificada presente, porque a estrutura lança uma HttpException com um código de status 404.
fonte
Observe que a partir de MVC3, você pode apenas usar
HttpStatusCodeResult
.fonte
HttpNotFoundResult
Usar ActionFilter é difícil de manter porque sempre que lançamos um erro, o filtro precisa ser definido no atributo. E se esquecermos de configurá-lo? Uma maneira é derivar
OnException
no controlador de base. Você precisa definir umBaseController
derivado deController
e todos os seus controladores devem derivarBaseController
. É uma prática recomendada ter um controlador de base.Observe que se
Exception
o código de status de resposta for 500, precisamos alterá-lo para 404 para Não encontrado e 401 para Não autorizado. Assim como mencionei acima, useOnException
substituiçõesBaseController
para evitar o uso do atributo de filtro.O novo MVC 3 também torna mais problemático, retornando uma visão vazia ao navegador. A melhor solução depois de alguma pesquisa é baseada na minha resposta aqui. Como retornar uma visualização para HttpNotFound () no ASP.Net MVC 3?
Para tornar mais conveniente, colo aqui:
Depois de algum estudo. A solução alternativa para MVC 3 aqui é para derivar todas
HttpNotFoundResult
,HttpUnauthorizedResult
,HttpStatusCodeResult
aulas e implementar novo (substituindo-lo)HttpNotFound
método () inBaseController
.É uma prática recomendada usar o controlador básico para que você tenha 'controle' sobre todos os controladores derivados.
Eu crio uma nova
HttpStatusCodeResult
classe, não para derivar,ActionResult
masViewResult
para renderizar a vista ou qualquer outra queView
você queira especificando aViewName
propriedade. Sigo o originalHttpStatusCodeResult
para definir oHttpContext.Response.StatusCode
e,HttpContext.Response.StatusDescription
mas, em seguidabase.ExecuteResult(context)
, renderizarei a visualização adequada porque, novamente, derivei deViewResult
. Simples o suficiente, não é? Espero que isso seja implementado no núcleo MVC.Veja meu
BaseController
abaixo:Para usar em sua ação como esta:
E em _Layout.cshtml (como a página mestra)
Além disso, você pode usar uma visão personalizada
Error.shtml
ou criar uma novaNotFound.cshtml
como comentei no código e pode definir um modelo de visão para a descrição do status e outras explicações.fonte