{"Message" da WebApi: "ocorreu um erro"} no IIS7, não no IIS Express

171

Estou trabalhando com o ASP.NET MVC 4 WebApi e estou me divertindo muito executando-o no meu computador local no IIS Express. Eu configurei o IIS Express para servir máquinas remotas também, e outras empresas da minha empresa estão usando meu computador como nosso servidor da web.

Depois de decidir que essa era uma solução abaixo do ideal, decidimos colocar o WebApi em um servidor remoto depois de instalar o .NET 4.5. Quando eu uso o violinista e enviei um POST para um controlador na minha máquina local, ele retornará a resposta correta; mesmo assim, quando altero o domínio para o servidor da Web que executa o IIS7, o mesmo POST retorna um encriptado

{"message": "ocorreu um erro"}

mensagem. Alguém tem alguma idéia do que poderia estar acontecendo?

nsg
fonte
2
Qual é o código de status HTTP na resposta ao erro? Se for 500, é muito provável que a configuração do site / aplicativo seja inválida para a máquina remota com o IIS 7. Crie um arquivo HTML simples na máquina remota, procure-o na máquina remota, se possível, para garantir que ele possa ser visualizado e tente para acertá-lo em sua máquina para ver se é bem-sucedido ou não.
Sixto Saez
É um erro de 500. Obrigado pela sugestão, mas a página index.html padrão fornecida pela WebApi funciona. Também deve-se acrescentar que alguns dos serviços da web da API funcionam e outros não, enquanto todos eles funcionam na minha máquina local.
Nsg 22/10/12
2
Você precisará ativar o rastreamento de solicitação do IIS para obter mais detalhes quando vir um erro 500. Geralmente, um erro 500 ocorre antes do roteamento da API da Web, mas acho que é possível acioná-lo por algo que seu código está fazendo. Veja o log de rastreamento do IIS e veja se isso oferece alguma pista.
Sixto Saez
1
Você pode conseguir que o servidor forneça informações de erro mais detalhadas em sua resposta iniciando a solicitação de um navegador na própria máquina do servidor (por exemplo, usando uma sessão da Área de Trabalho Remota).
Jon Schneider

Respostas:

268

O problema era uma dependência ausente que não estava no servidor, mas estava na minha máquina local. No nosso caso, era uma dll Devart.Data.Linq.

Para chegar a essa resposta, ativei o rastreamento do IIS para 500 erros. Isso forneceu um pouco de informação, mas a coisa realmente útil foi na configuração do web.config na opção <system.web><customErrors mode="Off"/></system.web>This, que apontava para uma dependência carregada dinamicamente. Depois de adicionar essa dependência e solicitar que ela seja copiada localmente, o servidor começou a funcionar.

nsg
fonte
33
Parece que o WebAPI substituirá {"message": "ocorreu um erro"} pela resposta real sempre que o código de resposta HTTP for 500 e os erros personalizados estiverem ativados. Obrigado pelo ponteiro.
Paul Suart 04/07
4
Ótima sugestão sobre a configuração do modo customErrors. Estou surpreso com a mudança que teve um impacto na saída desse tipo de erro.
Dewi Rees
1
Você também pode configurá-lo para mode="RemoteOnly"e se você executar a página em um browser no servidor, você também vai ver os erros sem comprometer a segurança, se o resto do site é acessível externamente
Simon_Weaver
Alguma sugestão sobre como obter esse tipo de detalhe de erro ao alterar essa configuração não é possível (por exemplo, os erros são desativados no nível da máquina porque a parte da API está hospedada em um servidor compatível com PCI)? Tentei configurar o Elmah, mas infelizmente não está registrando nada.
RubyHaus 17/08/2015
Essa é a melhor abordagem, fornece informações suficientes sobre esse método genérico.
DanielV
97

Basicamente:

Em IncludeErrorDetailPolicyvez disso, use se CustomErrorsnão resolver o problema para você (por exemplo, se você tiver uma pilha do ASP.NET> 2012):

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy 
= IncludeErrorDetailPolicy.Always;

Nota: Tenha cuidado ao retornar informações detalhadas de erro, que podem revelar informações confidenciais a 'hackers'. Veja o comentário de Simon sobre esta resposta abaixo.

Versão TL; DR

Para mim CustomErrors, realmente não ajudou. Já estava definido como Off, mas eu ainda só recebi uma an error has occurredmensagem fraca . Eu acho que a resposta aceita é de 3 anos atrás, que é um longo tempo na palavra web hoje em dia. Estou usando a API da Web 2 e o ASP.NET 5 (MVC 5) e a Microsoft se afastou de uma estratégia somente do IIS, enquanto o CustomErrorsvelho skool do IIS;).

Enfim, tive um problema de produção que não tinha localmente. E então descobri que não conseguia ver os erros na guia Rede do Chrome como na máquina de desenvolvimento. No final, consegui resolver o problema instalando o Chrome no meu servidor de produção e depois navegando até o aplicativo no próprio servidor (por exemplo, em 'localhost'). Em seguida, erros mais detalhados apareceram com rastreamentos de pilha e tudo.

Só depois encontrei este artigo de Jimmy Bogard (Nota: Jimmy é o Sr. AutoMapper! ). O engraçado é que o artigo dele também é de 2012, mas ele já explica que CustomErrorsnão ajuda mais nisso, mas que você PODE alterar o 'Detalhe do erro' definindo um diferente IncludeErrorDetailPolicyna configuração global da WebApi (por exemplo WebApiConfig.cs):

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy 
= IncludeErrorDetailPolicy.Always;

Felizmente, ele também explica como configurá-lo para que o webapi (2) escute suas CustomErrorsconfigurações. Essa é uma abordagem bastante sensata, e isso permite que você volte a 2012: p.

Nota: O valor padrão é 'LocalOnly', o que explica por que consegui resolver o problema da maneira que descrevi antes de encontrar esta postagem. Mas eu entendo que nem todo mundo pode apenas remotamente produzir e iniciar um navegador (eu sei que quase não consegui até que decidi me tornar freelancer e DevOps).

Bart
fonte
2
Agora, isso funciona. Obrigado! Eu tenho alguns testes de tipo de integração na memória que falham no servidor de compilação, mas não localmente. Com essa configuração na minha classe de inicialização, posso ter a chance de descobrir o porquê.
Thomas Eyde
Parece que a configuração customError funciona com o WebApi 2 quando hospedado no IIS por meio do Microsoft.AspNet.WebApi.WebHost. Os pacotes são da versão 5.2.3, então o ASP.NET se empilha desde 2012. Ao defini-lo como Desativado, a API da Web alterna de erros genéricos para mais detalhados, contendo a pilha de chamadas, etc ...
Tom
4
Tenha cuidado ao definir isso, pois pode revelar informações confidenciais para 'hackers'. Costumo fazer um hack rápido, algo como if (DateTime.Now < new DateTime(2017, 6, 22)) { .... }definir uma opção como esta. Então eu posso testá-lo em produção e amanhã ele voltará magicamente ao comportamento normal se eu esquecer de desativá-lo.
Simon_Weaver
36

Nenhuma das outras respostas funcionou para mim.

Isso aconteceu: (em Startup.cs)

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();

        WebApiConfig.Register(config);

        // Here: 
        config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
    }
}

(ou você pode colocá-lo em WebApiConfig.cs):

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        // Here: 
        config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
    }
}
samneric
fonte
Sim !, Essa foi a única solução funcional para mim no Mono / Linux.
Robert II
Isso funcionou para mim no prod de um aplicativo veiculado internamente no IIS e no Windows Server.
Paul Carlton
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always; me ajudou a descobrir que eu retorno uma instância de uma entidade que não pôde ser analisada porque o contexto foi descartado obrigado
Jood jindy 05/04
12

Eu sempre chego a essa pergunta quando encontro um erro no ambiente de teste e lembro: "Eu já fiz isso antes, mas posso fazê-lo diretamente no web.config sem precisar modificar o código e reimplantá-lo no ambiente de teste." , mas são necessárias duas alterações ... o que foi?

Para referência futura

<system.web>
   <customErrors mode="Off"></customErrors>
</system.web>

E

<system.webServer>
  <httpErrors errorMode="Detailed" existingResponse="PassThrough"></httpErrors>
</system.webServer>
Rick Glos
fonte
11

Eu tive um problema semelhante ao postar no terminal WebAPI. Ao desativar o CustomErrors = Off, consegui ver o erro real que está faltando uma das DLLs.

ctong
fonte
10

Caso isso ajude alguém:

Eu tive um problema semelhante e, seguindo as instruções do Nates, adicionei:

<system.web>
     <customErrors mode="Off"/>
 </system.web>

Isso me mostrou mais informações sobre o erro:

"ExceptionMessage": "Não foi possível carregar o recurso de metadados especificado.", "ExceptionType": "System.Data.Entity.Core.MetadataException", "StackTrace": "em System.Data.Entity.Core.Metadata.Edm.MetadataArtifactLoaderCompositeResource .LoadResources (...

Foi quando lembrei que havia movido o arquivo edmx para um local diferente e esqueci de alterar o nó connectionstrings na configuração (o nó connectionsstrings foi colocado em um arquivo separado usando "configSource", mas isso é outra história).

Hormberg
fonte
Isso aconteceu comigo ao adicionar o OData e o AutoMapper a uma API da Web no asp.net - espero que essas palavras-chave ajudem alguém a chegar a este post e o try / catch não funcionou no meu caso, então tive que ver o resultado bruto
Ekus
0

Meu arquivo XML swagger não foi implantado em \ bin:

GlobalConfiguration.Configuration
  .EnableSwagger(c =>
  {
    c.SingleApiVersion("v1", "SwaggerDemoApi");
    c.IncludeXmlComments(string.Format(@"{0}\bin\SwaggerDemoApi.XML", 
                         System.AppDomain.CurrentDomain.BaseDirectory));
    c.DescribeAllEnumsAsStrings();
  })

http://wmpratt.com/swagger-and-asp-net-web-api-part-1/

insira a descrição da imagem aqui

Ele precisava ser definido na configuração da versão e na configuração da depuração.

RaSor
fonte
0

Se você possui <deployment retail="true"/>o machine.config do .NET Framework, não verá mensagens de erro detalhadas. Verifique se a configuração é falsa ou não está presente.

Eric H
fonte
0

Então, eu tentei todas as soluções sugeridas sem sucesso. Tudo o que fiz foi definir a execução do aplicativo a partir do servidor e ele exibiu o erro por completo, isso deveria ter funcionado quando eu defini o modo customErrors como false, mas não funcionou. No momento em que naveguei na API do servidor, pude ver o problema.

Prince Tegaton
fonte