Como fazer uma rota de captura para lidar com consultas '404 não encontradas' para asp.net MVC?

StackOverflow https://stackoverflow.com/questions/310580

Pergunta

É possível criar uma rota final que pegue tudo .. e salta o usuário para uma visualização 404 no ASP.NET MVC?

Nota: Não quero configurar isso nas minhas configurações do IIS.

Foi útil?

Solução

Encontrei a resposta eu mesmo.

Richard Dingwall tem um excelente post passando por várias estratégias. Eu particularmente gosto da solução FilterAttribute. Eu não sou fã de dar exceções em torno de Willy Nilly, então vou ver se posso melhorar isso :)

Para o global.asax, basta adicionar este código como sua última rota para se registrar:

routes.MapRoute(
    "404-PageNotFound",
    "{*url}",
    new { controller = "StaticContent", action = "PageNotFound" }
    );

Outras dicas

Esta pergunta veio primeiro, mas a resposta mais fácil veio em uma pergunta posterior:

Roteamento para a página de erro ASP.NET MVC 404 personalizada

Recebi meu manuseio de erros para funcionar criando um controlador de erros que retorna as visualizações deste artigo. Eu também tive que adicionar o "Catch All" à rota no Global.asax.

Não consigo ver como chegará a nenhuma dessas páginas de erro, se não estiver na web.config ..? Meu web.config teve que especificar:

customErrors mode="On" defaultRedirect="~/Error/Unknown"

E então eu também adicionei:

error statusCode="404" redirect="~/Error/NotFound"

Espero que isto ajude.

Eu amo assim agora porque é tão simples:

 <customErrors mode="On" defaultRedirect="~/Error/" redirectMode="ResponseRedirect">
    <error statusCode="404" redirect="~/Error/PageNotFound/" />
 </customErrors>

Além disso, você pode lidar com o erro não encontrado no global.asax.cs como abaixo

protected void Application_Error(object sender, EventArgs e)
{
    Exception lastErrorInfo = Server.GetLastError();
    Exception errorInfo = null;

    bool isNotFound = false;
    if (lastErrorInfo != null)
    {
        errorInfo = lastErrorInfo.GetBaseException();
        var error = errorInfo as HttpException;
        if (error != null)
            isNotFound = error.GetHttpCode() == (int)HttpStatusCode.NotFound;
    }
    if (isNotFound)
    {
        Server.ClearError();
        Response.Redirect("~/Error/NotFound");// Do what you need to render in view
    }
}

Adicione estas linhas no seu arquivo ROOT Web.config do projeto.

 <system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
  <remove statusCode="404" />
  <error statusCode="404" responseMode="ExecuteURL" path="/Test/PageNotFound" />
  <remove statusCode="500" />
  <error statusCode="500" responseMode="ExecuteURL" path="/Test/PageNotFound" />
</httpErrors>
<modules>
  <remove name="FormsAuthentication" />
</modules>

Isso pode ser um problema quando você usa

throw new HttpException(404);

Quando você quiser pegar isso, não conheço outra maneira e editando sua configuração da web.

Uma alternativa para criar uma rota de captura é adicionar um Application_EndRequest método para o seu MvcApplication por MVC 404 da Marco MVC 404.

Lado de dentro RouterConfig.cs Adicione o pedaço de código de folga:

  routes.MapRoute(
           name: "Error",
           url: "{id}",
           defaults: new
           {
               controller = "Error",
               action = "PageNotFound"

           });

Se a rota não puder ser resolvida, o MVC Framework terá através de 404 erros. A melhor abordagem é usar os filtros de exceção ... Criar um Filter de exceção personalizado e fazer assim ..

public class RouteNotFoundAttribute : FilterAttribute, IExceptionFilter {
    public void OnException(ExceptionContext filterContext) {
        filterContext.Result  = new RedirectResult("~/Content/RouteNotFound.html");
   }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top