Assurez-vous que HttpConfiguration.EnsureInitialized ()

142

J'ai installé Visual Studio 2013 et lorsque j'exécute mon application, j'obtiens l'erreur ci-dessous.

Je n'ai aucune idée de l'endroit où je dois initialiser cet objet.

Que faire?

    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

C'est pour AlumCloud

Remplir la pile, c'est ce que je fais
la source

Réponses:

141

Voir la réponse de @ gentiane ci-dessous pour la bonne façon de gérer cela maintenant.

À la fin de la Application_Startméthode, Global.Asax.csessayez d'ajouter: -

GlobalConfiguration.Configuration.EnsureInitialized(); 
Ian Mercer
la source
3
J'obtenais cette réponse, alors j'ai comparé mon projet généré à partir d'une version préliminaire de VS 2013 à un projet généré avec la mise à jour 1 et la différence est qu'ils ont remplacé WebApiConfig.Register (...) par GlobalConfiguration.Configure (. ..) comme le décrit gentiane dans sa réponse. Cela résout le problème.
Bryan Bedard le
1
C'est exactement ce que l' GlobalConfiguration.Configure(Action<HttpConfiguration> configurationCallback)on appellera après la configurationCallback.
cmxl
4
Une erreur peut également se produire lorsque la configuration DI est effectuée avant le GlobalConfiguration.Configure (WebApiConfig.Register); appel
Silvos
Je vous remercie. Cela a été une épine dans mon côté.
Robert Bolton
241

Si vous le faites à la fin de Application_Start, il sera trop tard, car WebApiConfig.Register a été appelé.

La meilleure façon de résoudre ce problème est d'utiliser une nouvelle méthode d'initialisation en remplaçant dans Global.asax:

WebApiConfig.Register(GlobalConfiguration.Configuration);

par

GlobalConfiguration.Configure(WebApiConfig.Register);
gentiane
la source
12
D'après la documentation Microsoft, cela devrait être la bonne façon de procéder. asp.net/web-api/overview/web-api-routing-and-actions/…
Dalorzo
J'ai migré une application mvc, lorsque les routes de l'API ne fonctionnaient pas, l'ajout de cela et MapHttpAttributeRoutes a tout donné vie.
Phil Cooper
1
Cette réponse l'a corrigé pour moi.
GiddyUpHorsey
Mais que faire si vous avez une classe non statique WebApiConfig?
Georgy Grigoryev
@GeorgyGrigoryev: vous pouvez simplement l'instancier dans l'action comme ceci:GlobalConfiguration.Configure(config => new WebApiConfig().Register(config));
cmxl
69

En fait, j'ai eu cette erreur lorsque j'utilisais le routage d'attributs dans mon WebApi.

j'ai eu

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

au lieu de

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

pour mon itinéraire et j'ai obtenu cette erreur. J'avais simplement manqué la parenthèse bouclée de fermeture. Une fois que je l'ai rajouté, cette erreur ne s'est plus reproduite.

Jeff Yates
la source
23
J'ai aussi eu ce problème lorsque j'ai préfixé l'itinéraire avec une barre oblique [Route ("/ api /"]) au lieu de [Route ("api")]
cguedel
1
{int: id} au lieu de {id: int}
Marat Batalandabad
1
Celui-ci me donne tout le temps, mais il donnait une erreur différente. Après la mise à niveau vers Visual Studio 2015 et .Net 4.6, j'obtiens cette erreur.
nbering
7
Mon erreur était [Route ("api / {paramètre: string}")] au lieu de [Route ("api / {paramètre}")]. Apparemment, mettre: string comme type est faux car c'est la valeur par défaut.
Jamby
1
Semblable à Jamby, mon erreur était que j'avais besoin de: [Route ("api / ObjectOfInterest / {type} / {name}")] ... mais: [Route ("api / ObjectOfInterest / {type: string} / {nom : string} ")] // FAUX ... ne fonctionnait pas. Je sais que c'est bizarre que j'aie besoin d'un paramètre nommé «Type» qui soit une chaîne (et non un System.Type) ... mais j'ai supprimé la spécification de chaîne et cela fonctionne bien.
Aidanapword
31

C'est vieux, mais c'est le premier résultat sur google lors de la recherche de cette erreur. Après pas mal de recherches, j'ai pu comprendre ce qui se passait.

tldr:
Tout ce que fait GlobalConfiguration.Configure est d'appeler votre action et d'appeler EnsureInitialized () . config.MapAttributeRoutes () doit être appelée avant EnsureInitialized () car EnsureInitialized ne s'exécute qu'une seule fois.

Signification: si vous venez d'un projet Mvc existant, tout ce que vous avez à faire est:

  1. Ajouter GlobalConfiguration.Configuration.EnsureInitialized (); au bas de votre méthode Application_Start .

OU

  1. Déplacez toute votre configuration en un seul appel à GlobalConfiguration.Configure :
GlobalConfiguration.Configure(config => 
{
    WebApiConfig.Register(config);
    config.MapAttributeRoutes();
    ...
});

Creuser plus profond

HttpConfiguration.Configuration a une propriété "Initializer" définie comme ceci:

public Action<HttpConfiguration> Initializer;

HttpConfiguration.EnsureInitialized () exécute cette action et définit _initialized sur true

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

HttpConfiguration.MapAttributeRoutes appelle la méthode interne AttributeRoutingMapper.MapAttributeRoutes qui définit 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 exécute EnsureInitialized immédiatement après avoir appelé votre action:

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

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

N'oubliez pas que si vous vous heurtez à un mur, la source de asp.net est disponible à l' adresse http://aspnetwebstack.codeplex.com/SourceControl/latest

tField
la source
La solution avec un seul appel à GlobalConfiguration.Configure m'a sauvé la vie. J'ai eu des problèmes avec le routage basé sur les attributs et la configuration DI ainsi que l'ordre correct d'appeler les configurations. J'utilise également MS ApiVersioning, où j'avais besoin des injections DI avant que la première route n'atteigne les attributs de version. Merci beaucoup
Silvos
12

J'ai eu un problème connexe. Parfois, un appel à GlobalConfiguration.Configureplusieurs reprises déclenche cette erreur. Pour contourner le problème, j'ai mis toute la logique d'initialisation de la configuration au même endroit.

Gleno
la source
Oui, c'était définitivement le problème dans mon cas
Obi
Je vous remercie! C'était exactement mon problème.
Søren Boisen
Même problème ici! J'essaye de résoudre le problème depuis quelques heures, donc le x pour le commentaire.
Sc0tTy
7

Pour moi, le problème était que j'essayais d'utiliser des paramètres nommés pour les champs de chaîne de requête dans mes itinéraires:

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

Les champs de chaîne de requête sont automatiquement mappés aux paramètres et ne font pas réellement partie de la définition de l'itinéraire. Cela marche:

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

Bien que la réponse ci-dessus fonctionne si cela n'est pas défini, dans mon cas, ce truc était déjà défini. Ce qui était différent, c'est que, pour l'une des API que j'avais écrites, j'avais préfixé la route avec un /. Exemple

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

.Changer ceci en

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

réparé pour moi

Le 0bserver
la source
@Svend Indeed. Semblait être une chose stupide, mais semble être le problème dans de nombreux cas. : P
Le 0bserver
@ The0bserver cela a fonctionné pour moi aussi. Il était difficile à diagnostiquer , car en haut de ma classe de contrôleur j'avais un HttpPrefixdécorateur, puis pour mon point final individuel j'ai eu le décorateur: [Route("/")]. En passant simplement une chaîne vide dans l'itinéraire, le problème a été résolu.
David
1
Heureux que cela ait aidé. :)
The 0bserver
7

SI CETTE ERREUR SEMBLE ÊTRE VENUE "DE NULLE PART" , c'est-à-dire que votre application fonctionnait parfaitement bien pendant un certain temps, demandez-vous: ai-je ajouté une action à un contrôleur ou modifié des itinéraires avant de voir cette erreur?

Si la réponse est oui (et c'est probablement le cas), vous avez probablement fait une erreur dans le processus. Un formatage incorrect, copier / coller une action et oublier de s'assurer que les noms de point de terminaison sont uniques, etc., vous finirez tous ici. La suggestion de cette erreur sur la façon de la résoudre peut vous faire aboyer dans le mauvais arbre.

Byron Jones
la source
C'est exactement ce qui m'est arrivé. J'ai changé un itinéraire mais j'avais laissé une accolade erronée à la fin comme ceci: [Route ("GetStuff}")]
Stu Price
2

Appel

GlobalConfiguration.Configuration.MapHttpAttributeRoutes();

avant

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

termine son exécution.

abatishchev
la source
2

J'ai eu cette erreur lorsque la version de Newtonsoft.Json était différente dans mon projet principal par rapport au projet d'assistance

David Lilljegren
la source
Ajout rapide: assurez-vous de nettoyer votre solution après avoir corrigé le problème de référence et vérifiez que la DLL finale déployée est la bonne version :)
Marcel
1

On obtient généralement cette exception lorsque les modèles de route dans "Attribute Routing" ne sont pas appropriés.

Par exemple, j'ai obtenu ceci lorsque j'ai écrit le code suivant:

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

Dans la syntaxe des contraintes de route {paramètre: contrainte}, la contrainte par défaut est de type chaîne . Inutile de le mentionner explicitement.

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

J'ai commencé à avoir cette erreur un jour. Après avoir modifié notre application pour appeler, EnsureInitialized()j'ai pu voir la cause profonde.

J'avais un attribut personnalisé, un filtre, sur une action. Cette classe d'attributs avait subi un changement radical dans le package NuGet dans lequel elle vit.

Même si j'avais mis à jour le code et tout compilé, le travailleur IIS local chargeait une ancienne DLL et ne trouvait pas de membre de classe lors de l'initialisation, lisant les attributs sur les actions, etc.

Pour une raison quelconque (peut-être en raison de la commande / lorsque notre journalisation est initialisée), cette erreur n'était pas détectable, laissant peut-être le WebAPI dans un état étrange, jusqu'à ce que j'aie ajouté EnsureInitialized()qui a attrapé l'exception et l'a fait apparaître.

L'exécution d'un bon binet objpropre via un script pratique l'a résolu.

Luke Puplett
la source
0

Dans mon cas, j'ai créé le service Web dans le projet A et l'ai démarré à partir du projet B et j'ai eu exactement cette erreur. Le problème était que certains fichiers .dll requis par A manquaient dans le dossier build-output de B. Assurez-vous que ces fichiers .dll sont disponibles corrigés.

anion
la source
0

Dans mon cas, j'ai utilisé une entité comme paramètre de mon action que son «schéma» est manquant.

Mauvais attribut:

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

Correct :

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