Verifique se HttpConfiguration.EnsureInitialized ()

142

Instalei o Visual Studio 2013 e, quando executo meu aplicativo, recebo o erro abaixo.

Não tenho idéia de onde devo inicializar esse objeto.

O que fazer?

    Server Error in '/' Application.

The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized() is called in the application's startup code after all other initialization code.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.InvalidOperationException: The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized() is called in the application's startup code after all other initialization code.

Source Error: 

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace: 


[InvalidOperationException: The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized() is called in the application's startup code after all other initialization code.]
   System.Web.Http.Routing.RouteCollectionRoute.get_SubRoutes() +101
   System.Web.Http.Routing.RouteCollectionRoute.GetRouteData(String virtualPathRoot, HttpRequestMessage request) +63
   System.Web.Http.WebHost.Routing.HttpWebRoute.GetRouteData(HttpContextBase httpContext) +107
   System.Web.Routing.RouteCollection.GetRouteData(HttpContextBase httpContext) +233
   System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context) +60
   System.Web.Routing.UrlRoutingModule.OnApplicationPostResolveRequestCache(Object sender, EventArgs e) +82
   System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +136
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +69

Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.18408

Isto é para AlumCloud

Preenchendo a pilha é o que eu faço
fonte

Respostas:

141

Veja a resposta da @ gentiane abaixo para a maneira correta de lidar com isso agora.

No final do Application_Startmétodo, Global.Asax.cstente adicionar: -

GlobalConfiguration.Configuration.EnsureInitialized(); 
Ian Mercer
fonte
3
Eu estava recebendo esta resposta, então comparei meu projeto que foi gerado a partir de uma versão de visualização do VS 2013 para um que foi gerado com a Atualização 1 e a diferença é que eles substituíram WebApiConfig.Register (...) por GlobalConfiguration.Configure (. ..) como gentiane descreve em sua resposta. Isso resolve o problema.
Bryan Bedard
1
Isso é exatamente o GlobalConfiguration.Configure(Action<HttpConfiguration> configurationCallback)que chamará após o configurationCallback.
Cmdl #
4
O erro também pode ocorrer quando a configuração da DI é feita antes do GlobalConfiguration.Configure (WebApiConfig.Register); chamada
Silvos
Obrigado. Isso tem sido um espinho do meu lado.
Robert Bolton
241

Se você fizer isso no final do Application_Start, será tarde demais, como WebApiConfig.Register foi chamado.

A melhor maneira de resolver isso é usar o novo método de inicialização substituindo no Global.asax:

WebApiConfig.Register(GlobalConfiguration.Configuration);

de

GlobalConfiguration.Configure(WebApiConfig.Register);
gentiane
fonte
12
Com base na documentação da Microsoft, este deve ser o caminho certo para fazê-lo. asp.net/web-api/overview/web-api-routing-and-actions/…
Dalorzo
Estou migrando um aplicativo mvc, quando as rotas da API não estavam funcionando, adicionando isso e o MapHttpAttributeRoutes trouxe tudo à vida.
Phil Cooper
1
Esta resposta corrigiu para mim.
GiddyUpHorsey
Mas e se você tiver classe não estática WebApiConfig?
Georgy Grigoryev 30/01
@GeorgyGrigoryev: você pode instancia-lo dentro da ação da seguinte maneira:GlobalConfiguration.Configure(config => new WebApiConfig().Register(config));
cmxl
69

Na verdade, eu recebi esse erro quando estava usando o roteamento de atributos na minha WebApi.

eu tinha

[Route ("webapi / siteTypes / {siteTypeId"]

ao invés de

[Route ("webapi / siteTypes / {siteTypeId}"]

para minha rota e recebi esse erro. Eu simplesmente tinha perdido a chave de fechamento. Depois que o adicionei novamente, esse erro não ocorreu novamente.

Jeff Yates
fonte
23
Eu também tive esse problema quando eu prefixado a rota com uma barra [Route ( "/ api /"]) em vez de [Route ( "API")]
cguedel
1
{int: id} em vez de {id: int}
Marat Batalandabad
1
Este me pega o tempo todo, mas costumava dar um erro diferente. Após a atualização para o visual studio 2015 e o .Net 4.6, recebo esse erro.
N / a
7
Meu erro foi [Route ("api / {parameter: string}")] em vez de [Route ("api / {parameter}")]. Aparentemente, colocar: string como tipo está errado, pois é o padrão.
Jamby
1
Semelhante ao Jamby, meu erro foi que eu precisava: [Route ("api / ObjectOfInterest / {type} / {name}")] ... mas: [Route ("api / ObjectOfInterest / {type: string} / {name : string} ")] // ERRADO ... não estava funcionando. Eu sei que é estranho eu precisar de um parâmetro chamado 'Type' que seja uma string (e não um System.Type) ... mas removi a especificação da string e funciona bem.
Aidanapword
31

Isso é antigo, mas é o primeiro resultado no google ao procurar esse erro. Depois de cavar bastante, consegui descobrir o que estava acontecendo.

tldr:
Tudo que o GlobalConfiguration.Configure faz é invocar sua ação e chamar GuaranteInitialized () . config.MapAttributeRoutes () deve ser chamado antes de GuaranteInitialized (), pois GuaranteInitialized é executado apenas uma vez.

Significado: se você é proveniente de um projeto Mvc existente, tudo o que você precisa fazer é:

  1. Adicione GlobalConfiguration.Configuration.EnsureInitialized (); na parte inferior do seu método Application_Start .

OU

  1. Mova toda a sua configuração em uma única chamada para GlobalConfiguration.Configure :
GlobalConfiguration.Configure(config => 
{
    WebApiConfig.Register(config);
    config.MapAttributeRoutes();
    ...
});

Indo Mais Fundo

HttpConfiguration.Configuration possui uma propriedade "Initializer" definida assim:

public Action<HttpConfiguration> Initializer;

HttpConfiguration.EnsureInitialized () executa esta ação e define _initialized como true

public void EnsureInitialized()
{ 
    if (_initialized)
    {
        return;
    }
    _initialized = true;
    Initializer(this);            
}

HttpConfiguration.MapAttributeRoutes chama o método interno AttributeRoutingMapper.MapAttributeRoutes que define HttpConfiguration.Initializer

public static void MapAttributeRoutes(...)
{
    RouteCollectionRoute aggregateRoute = new RouteCollectionRoute();
    configuration.Routes.Add(AttributeRouteName, aggregateRoute);

    ...

    Action<HttpConfiguration> previousInitializer = configuration.Initializer;
    configuration.Initializer = config =>
    {
        previousInitializer(config);
        ...
    };
}

GlobalConfiguration.Configure executa o GuaranteInitialized imediatamente após invocar sua ação:

public static void Configure(Action<HttpConfiguration> configurationCallback)
{
    if (configurationCallback == null)
    {
        throw new ArgumentNullException("configurationCallback");
    }

    configurationCallback.Invoke(Configuration);
    Configuration.EnsureInitialized();
}

Não se esqueça, se você se deparar com uma parede, a fonte do asp.net estará disponível em http://aspnetwebstack.codeplex.com/SourceControl/latest

tField
fonte
A solução com uma única chamada para GlobalConfiguration.Configure salvou minha vida. Eu tive problemas com o roteamento baseado em atributos e a configuração de DI, juntamente com a ordem correta de chamar as configurações. Também uso o MS ApiVersioning, onde eu precisava das injeções de DI feitas antes da primeira rota atingir os atributos de versão. Thx muito
Silvos
12

Eu tive um problema relacionado. Às vezes, chamar GlobalConfiguration.Configurevárias vezes aciona esse erro. Como solução alternativa, coloquei toda a lógica de inicialização da configuração em um só lugar.

Gleno
fonte
Sim, esse foi definitivamente o problema no meu caso
Obi
Obrigado! Este foi exatamente o meu problema.
Søren Boisen 9/04/2015
O mesmo problema aqui! Estou tentando corrigir o problema há algumas horas, então x para o comentário.
Sc0tTy
7

Para mim, o problema era que eu estava tentando usar parâmetros nomeados para campos de string de consulta em minhas rotas:

[Route("my-route?field={field}")]
public void MyRoute([FromUri] string field)
{
}

Os campos de sequência de consulta são mapeados automaticamente para parâmetros e, na verdade, não fazem parte da definição de rota. Isso funciona:

[Route("my-route")]
public void MyRoute([FromUri] string field)
{
}
NathanAldenSr
fonte
7

Embora a resposta acima funcione se o caso não estiver definido, no meu caso essas coisas já foram definidas. O que foi diferente foi que, para uma das APIs que eu havia escrito, prefixo a rota com um /. Exemplo

[Route("/api/abc/{client}")] 

.Alterar isso para

[Route("api/abc/{client}")]

consertou para mim

O 0bserver
fonte
@Svend Indeed. Parecia uma coisa estúpida, mas parece que é esse o problema em alguns casos. : P
O 0bserver
@ The0bserver isso funcionou para mim também. Era difícil de diagnosticar porque no topo da minha classe de controlador I teve um HttpPrefixdecorador e, em seguida, para o meu ponto final indivíduo que tinha o decorador: [Route("/")]. Simplesmente passando uma String vazia na rota, resolvia o problema.
David David
1
Ainda bem que ajudou. :)
The 0bserver
7

Se esse erro parecer "fora do nada" , ou seja, seu aplicativo estiver funcionando perfeitamente por algum tempo, pergunte-se: eu adicionei uma ação a um controlador ou alterei alguma rota antes de ver esse erro?

Se a resposta for sim (e provavelmente é), você provavelmente cometeu um erro no processo. Formatação incorreta, copie / cole uma ação e esqueça-se de garantir que os nomes dos terminais sejam únicos, etc. A sugestão que esse erro faz sobre como resolvê-lo pode enviar você latindo na árvore errada.

Byron Jones
fonte
Foi exatamente o que aconteceu comigo. Eu mudei uma rota, mas havia deixado uma chave de fenda incorreta no final, assim: [Route ("GetStuff}"))]
Stu Price
2

Ligar

GlobalConfiguration.Configuration.MapHttpAttributeRoutes();

antes

GlobalConfiguration.Configure(c => ...);

completa sua execução.

abatishchev
fonte
2

Eu recebi esse erro quando a versão do Newtonsoft.Json era diferente no meu projeto principal em comparação ao projeto auxiliar

David Lilljegren
fonte
Breve disso: Certifique-se de limpar a sua solução depois de corrigir o problema de referência e verifique que a final DLL implantado é a versão correta :)
Marcel
1

Geralmente, obtém-se essa exceção quando os modelos de rota em "Roteamento de Atributos" não são adequados.

Por exemplo, obtive isso quando escrevi o seguinte código:

[Route("{dirName:string}/contents")] //incorrect
public HttpResponseMessage GetDirContents(string dirName) { ... }

Na sintaxe das restrições de rota {parameter: constraint}, a restrição por padrão é do tipo string . Não há necessidade de mencionar explicitamente.

[Route("{dirName}/contents")] //correct
public HttpResponseMessage GetDirContents(string dirName) { ... }
Tarun Kumar
fonte
0

Comecei a receber esse erro um dia. Depois que alterei nosso aplicativo para ligar, EnsureInitialized()pude ver a causa raiz.

Eu tinha um atributo personalizado, um filtro, em uma ação. Essa classe de atributo teve uma alteração de última hora feita no pacote NuGet em que vive.

Embora eu tenha atualizado o código e tudo compilado, o trabalhador local do IIS estava carregando uma DLL antiga e não encontrava um membro da classe durante a inicialização, lendo atributos em ações etc.

Por algum motivo (possivelmente devido ao pedido / quando nosso log é inicializado), esse erro não foi detectável, possivelmente deixando a WebAPI em um estado estranho, até que eu adicionasse EnsureInitialized() que capturou a exceção e a emergiu.

Executar um bom bine objlimpo através de um script útil resolveu isso.

Luke Puplett
fonte
0

No meu caso, criei o serviço da web no projeto A e o iniciei no Projeto B e recebi exatamente esse erro. O problema era que alguns arquivos .dll exigidos por A estavam ausentes na pasta de saída de compilação de B. Verifique se esses arquivos .dll estão disponíveis.

ânion
fonte
0

No meu caso, usei uma Entidade como parâmetro da minha ação que está faltando 'Esquema'.

Atributo errado:

[Table("Table name", Schema = "")]

Correto:

[Table("Table name", Schema = "schema name")]
Reza Nafisi
fonte