Upewnij się, że HttpConfiguration.EnsureInitialized ()

142

Mam zainstalowany program Visual Studio 2013 i po uruchomieniu aplikacji pojawia się poniższy błąd.

Nie mam pojęcia, gdzie mam zainicjować ten obiekt.

Co robić?

    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

To jest dla AlumCloud

Wypełnianie stosu jest tym, co robię
źródło

Odpowiedzi:

141

Zobacz odpowiedź @ gentiane poniżej, aby dowiedzieć się, jak sobie z tym teraz poradzić.

Na koniec Application_Startmetody Global.Asax.csspróbuj dodać: -

GlobalConfiguration.Configuration.EnsureInitialized(); 
Ian Mercer
źródło
3
Otrzymałem tę odpowiedź, więc porównałem projekt, który został wygenerowany z wersji zapoznawczej VS 2013 z projektem wygenerowanym z Update 1, a różnica polega na tym, że zastąpiły one WebApiConfig.Register (...) z GlobalConfiguration.Configure (. ..), jak opisuje gentiane w swojej odpowiedzi. To rozwiązuje problem.
Bryan Bedard,
1
To jest dokładnie to, co GlobalConfiguration.Configure(Action<HttpConfiguration> configurationCallback)zostanie wywołane po wywołaniu konfiguracjiCallback.
cmxl
4
Błąd może również wystąpić, gdy konfiguracja DI jest wykonywana przed GlobalConfiguration.Configure (WebApiConfig.Register); zadzwoń
Silvos
Dziękuję Ci. To był cierń w moim boku.
Robert Bolton,
241

Jeśli zrobisz to pod koniec Application_Start, będzie za późno, bo wywołano WebApiConfig.Register.

Najlepszym sposobem rozwiązania tego problemu jest użycie nowej metody inicjalizacji poprzez zastąpienie w Global.asax:

WebApiConfig.Register(GlobalConfiguration.Configuration);

przez

GlobalConfiguration.Configure(WebApiConfig.Register);
gentiane
źródło
12
W oparciu o dokumentację firmy Microsoft powinien to być właściwy sposób. asp.net/web-api/overview/web-api-routing-and-actions/…
Dalorzo
Migrowałem aplikację mvc, gdy trasy API nie działały, dodając to i MapHttpAttributeRoutes ożywiło to wszystko.
Phil Cooper,
1
Ta odpowiedź rozwiązała problem.
GiddyUpHorsey
Ale co w przypadku, gdy masz niestatyczną klasę WebApiConfig?
Georgy Grigoryev
@GeorgyGrigoryev: możesz po prostu utworzyć instancję w akcji w następujący sposób:GlobalConfiguration.Configure(config => new WebApiConfig().Register(config));
cmxl
69

W rzeczywistości pojawił się ten błąd, gdy korzystałem z routingu atrybutów w moim WebApi.

miałem

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

zamiast

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

dla mojej trasy i otrzymałem ten błąd. Po prostu przegapiłem zamykający nawias klamrowy. Po ponownym dodaniu ten błąd nie wystąpił ponownie.

Jeff Yates
źródło
23
Miałem również ten problem, gdy poprzedzałem trasę ukośnikiem [Route ("/ api /"]) zamiast [Route ("api")]
cguedel
1
{int: id} zamiast {id: int}
Marat Batalandabad
1
Ten dostaje mnie cały czas, ale dawał inny błąd. Po uaktualnieniu do Visual Studio 2015 i .Net 4.6 pojawia się ten błąd.
nbering
7
Mój błąd to [Route ("api / {parametr: string}")] zamiast [Route ("api / {parametr}")]. Najwyraźniej umieszczenie: string jako type jest błędne, ponieważ jest domyślne.
Jamby
1
Podobnie jak w przypadku Jamby, mój błąd polegał na tym, że potrzebowałem: [Route ("api / ObjectOfInterest / {type} / {name}")] ... ale: [Route ("api / ObjectOfInterest / {type: string} / {name) : string} ")] // ŹLE ... nie działa. Wiem, że to dziwne, że potrzebuję parametru o nazwie „Typ”, który jest łańcuchem (a nie typem System.Type) ... ale usunąłem specyfikację ciągu i działa dobrze.
Aidanapword
31

To jest stare, ale jest to pierwszy wynik w Google podczas wyszukiwania tego błędu. Po długich poszukiwaniach byłem w stanie dowiedzieć się, co się dzieje.

tldr:
Wszystko, co robi GlobalConfiguration.Configure , to wywołanie akcji i wywołanie ApplyInitialized () . config.MapAttributeRoutes () musi zostać wywołana przed ZapewnienieInitialized (), ponieważ ZapewnijInitialized działa tylko raz.

Znaczenie: jeśli pochodzisz z istniejącego projektu Mvc, wszystko, co musisz zrobić, to:

  1. Dodaj GlobalConfiguration.Configuration.EnsureInitialized (); u dołu metody Application_Start .

LUB

  1. Przenieś całą konfigurację do jednego wywołania GlobalConfiguration .
GlobalConfiguration.Configure(config => 
{
    WebApiConfig.Register(config);
    config.MapAttributeRoutes();
    ...
});

Kopać głębiej

HttpConfiguration.Configuration ma właściwość „Initializer” zdefiniowaną w następujący sposób:

public Action<HttpConfiguration> Initializer;

HttpConfiguration.EnsureInitialized () uruchamia tę akcję i ustawia _initialized na true

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

HttpConfiguration.MapAttributeRoutes wywołuje metodę wewnętrzną AttributeRoutingMapper.MapAttributeRoutes, która ustawia 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 uruchamia usługę GuaranteeInitialized natychmiast po wywołaniu akcji:

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

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

Nie zapomnij, jeśli wpadniesz na ścianę, źródło asp.net jest dostępne pod adresem http://aspnetwebstack.codeplex.com/SourceControl/latest

tField
źródło
Rozwiązanie z jednym wywołaniem GlobalConfiguration.Configure uratowało mi życie. Miałem problemy z routingiem opartym na atrybutach i konfiguracją DI wraz z prawidłową kolejnością wywoływania konfiguracji. Używam również MS ApiVersioning, gdzie potrzebowałem wstrzyknięć DI wykonanych zanim pierwsza trasa dotrze do atrybutów wersjonowania. Thx dużo
Silvos
12

Miałem powiązany problem. Czasami GlobalConfiguration.Configurewielokrotne wywołanie powoduje ten błąd. Aby obejść ten problem, umieściłem całą logikę inicjowania konfiguracji w jednym miejscu.

Gleno
źródło
Tak, to był zdecydowanie problem w moim przypadku
Obi
Dziękuję Ci! To był dokładnie mój problem.
Søren Boisen
Ten sam problem tutaj! Próbowałem rozwiązać ten problem przez kilka godzin, więc x dla komentarza.
Sc0tTy
7

Dla mnie problem polegał na tym, że próbowałem użyć nazwanych parametrów dla pól ciągu zapytania w moich trasach:

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

Pola ciągu zapytania są automatycznie mapowane na parametry i nie są w rzeczywistości częścią definicji trasy. To działa:

[Route("my-route")]
public void MyRoute([FromUri] string field)
{
}
NathanAldenSr
źródło
7

Chociaż powyższa odpowiedź działa, jeśli okaże się, że nie jest ustawiona, w moim przypadku te rzeczy były już ustawione. Różnica polegała na tym, że w przypadku jednego z napisanych przeze mnie interfejsów API trasę poprzedziłam znakiem /. Przykład

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

.Zmiana tego na

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

naprawił to dla mnie

Plik 0bserver
źródło
@Svend Rzeczywiście. Wydawało się to głupią rzeczą, ale wydaje się, że w kilku przypadkach jest to problem. : P
The 0bserver,
@ The0bserver to też zadziałało dla mnie. To była trudna do zdiagnozowania, ponieważ na szczycie mojej klasy kontrolera miałem HttpPrefixdekorator a następnie do mojego indywidualnego punktu końcowego miałem dekorator: [Route("/")]. Przekazanie pustego ciągu w trasie rozwiązało problem.
David
1
Cieszę się, że pomogło. :)
The 0bserver
7

JEŚLI WYDAJE SIĘ, ŻE BŁĄD WYSTĄPIŁ „Z NIGDZIE” , tzn. Twoja aplikacja przez jakiś czas działała doskonale, zadaj sobie pytanie: Czy dodałem akcję do kontrolera lub zmieniłem trasy przed wyświetleniem tego błędu?

Jeśli odpowiedź brzmi tak (i ​​prawdopodobnie tak jest), prawdopodobnie popełniłeś błąd w procesie. Nieprawidłowe formatowanie, kopiowanie / wklejanie akcji i zapomnienie o upewnieniu się, że nazwy punktów końcowych są unikalne, itp. Skończą cię tutaj. Sugestia, że ​​ten błąd dotyczy sposobu rozwiązania tego problemu, może spowodować, że szczekasz na niewłaściwe drzewo.

Byron Jones
źródło
To właśnie mi się przydarzyło. Zmieniłem trasę, ale na końcu zostawiłem błędny nawias klamrowy w ten sposób: [Route ("GetStuff}")]
Stu Price
2

Połączenie

GlobalConfiguration.Configuration.MapHttpAttributeRoutes();

przed

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

kończy jego wykonanie.

abatishchev
źródło
2

Otrzymałem ten błąd, gdy wersja Newtonsoft.Json była inna w moim głównym projekcie niż w projekcie pomocniczym

David Lilljegren
źródło
Szybki dodatek: pamiętaj, aby wyczyścić swoje rozwiązanie po naprawieniu problemu z odniesieniem i dokładnie sprawdź, czy ostateczna wdrożona biblioteka DLL jest poprawna :)
Marcel
1

Ten wyjątek występuje zwykle, gdy szablony tras w „Routingu atrybutów” nie są właściwe.

Na przykład dostałem to, kiedy napisałem następujący kod:

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

W składni ograniczeń trasy {parametr: ograniczenie} domyślnie ograniczenie jest typu ciąg . Nie trzeba o tym wyraźnie wspominać.

[Route("{dirName}/contents")] //correct
public HttpResponseMessage GetDirContents(string dirName) { ... }
Tarun Kumar
źródło
0

Pewnego dnia zacząłem otrzymywać ten błąd. Po tym, jak zmieniłem naszą aplikację, aby dzwoniła EnsureInitialized(), mogłem zobaczyć główną przyczynę.

Miałem niestandardowy atrybut, filtr, dla akcji. Ta klasa atrybutów miała istotną zmianę wprowadzoną w pakiecie NuGet, w którym znajduje się.

Mimo że zaktualizowałem kod i wszystko zostało skompilowane, lokalny pracownik IIS ładował starą bibliotekę DLL i nie znajdował elementu członkowskiego klasy podczas inicjalizacji, odczytując atrybuty akcji itp.

Z jakiegoś powodu (prawdopodobnie z powodu zamówienia / kiedy nasze logowanie jest inicjowane) ten błąd nie był wykrywalny, prawdopodobnie pozostawiając WebAPI w dziwnym stanie, dopóki nie dodałem EnsureInitialized() który przechwycił wyjątek i nie pokazałem go.

Wykonanie prawidłowego bini objwyczyszczenia za pomocą podręcznego skryptu rozwiązało problem.

Luke Puplett
źródło
0

W moim przypadku utworzyłem usługę sieciową w projekcie A i uruchomiłem ją z projektu B i otrzymałem dokładnie ten błąd. Problem polegał na tym, że brakowało niektórych plików .dll wymaganych przez A w folderze build-output w B. Upewnij się, że te pliki .dll są dostępne, naprawił problem.

anion
źródło
0

W moim przypadku użyłem Entity jako parametru mojego działania, w którym brakuje jej „Schematu”.

Błędny atrybut:

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

Poprawnie:

[Table("Table name", Schema = "schema name")]
Reza Nafisi
źródło