Убедитесь, что HttpConfiguration.EnsureInitialized ()

142

Я установил Visual Studio 2013, и когда я запускаю свое приложение, я получаю сообщение об ошибке ниже.

Я понятия не имею, где я должен инициализировать этот объект.

Что делать?

    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

Это для AlumCloud

Заполнение стека - это то, что я делаю
источник

Ответы:

141

Посмотрите ответ @ gentiane ниже для правильного способа справиться с этим сейчас.

В конце Application_Startметода Global.Asax.csпопробуйте добавить:

GlobalConfiguration.Configuration.EnsureInitialized(); 
Ян Мерсер
источник
3
Я получил этот ответ, поэтому я сравнил свой проект, созданный на основе предварительной версии VS 2013, с проектом, созданным с обновлением 1, и разница в том, что они заменили WebApiConfig.Register (...) на GlobalConfiguration.Configure (. ..) как горечавка описывает в своем ответе. Это действительно решает проблему.
Брайан Бедард
1
Именно так и GlobalConfiguration.Configure(Action<HttpConfiguration> configurationCallback)будет звонить после настройки обратного вызова.
cmxl
4
Ошибка может также произойти, когда конфигурация DI выполнена перед GlobalConfiguration.Configure (WebApiConfig.Register); звонок
Сильвос
Спасибо. Это было занозой на моей стороне.
Роберт Болтон
241

Если вы сделаете это в конце Application_Start, будет слишком поздно, так как был вызван WebApiConfig.Register.

Лучший способ решить эту проблему - использовать новый метод инициализации, заменив в Global.asax:

WebApiConfig.Register(GlobalConfiguration.Configuration);

по

GlobalConfiguration.Configure(WebApiConfig.Register);
Gentiane
источник
12
Основываясь на документации Microsoft, это должен быть правильный способ сделать это. asp.net/web-api/overview/web-api-routing-and-actions/…
Dalorzo
Я переносил приложение mvc, когда не работали API-маршруты, добавив это, и MapHttpAttributeRoutes привел его в чувство.
Фил Купер
1
Этот ответ исправил это для меня.
GiddyUpHorsey
Но что, если у вас есть нестатический класс WebApiConfig?
Георгий Григорьев
@GeorgyGrigoryev: вы можете просто создать его экземпляр внутри действия следующим образом:GlobalConfiguration.Configure(config => new WebApiConfig().Register(config));
cmxl
69

Я действительно получил эту ошибку, когда я использовал маршрутизацию атрибутов в моем WebApi.

я имел

[Маршрут ( "WebAPI / siteTypes / {siteTypeId"]

вместо того

[Маршрут ( "WebAPI / siteTypes / {siteTypeId}"]

для моего маршрута и получил эту ошибку. Я просто пропустил закрывающую фигурную скобку. Как только я добавил его обратно, эта ошибка больше не возникала.

Джефф Йейтс
источник
23
У меня также была эта проблема, когда я ставил перед маршрутом косую черту [Route ("/ api /"]) вместо [Route ("api")]
cguedel
1
{int: id} вместо {id: int}
Марат Баталандабад
1
Этот получает меня все время, но раньше он давал другую ошибку. После обновления до Visual Studio 2015 и .Net 4.6 я получаю эту ошибку.
nbering
7
Моя ошибка была [Маршрут ("api / {параметр: строка}")] вместо [Маршрут ("api / {параметр}")]. Видимо, строка: строка как тип неверна, так как это значение по умолчанию.
Джемби
1
Как и в случае с Jamby, моя ошибка заключалась в том, что мне нужно было: [Route ("api / ObjectOfInterest / {type} / {name}")] ... но: [Route ("api / ObjectOfInterest / {type: string} / {name : string} ")] // НЕПРАВИЛЬНО ... не работал. Я знаю, что это странно, что мне нужен параметр с именем «Тип», который является строкой (а не System.Type) ... но удалил спецификацию строки, и она работает нормально.
Aidanapword
31

Это старый, но это первый результат в Google при поиске этой ошибки. После нескольких копаний я смог понять, что происходит.

tldr:
Все GlobalConfiguration.Configure делает это вызвать ваши действия и вызов EnsureInitialized () . config.MapAttributeRoutes () должен быть вызван перед EnsureInitialized (), так как EnsureInitialized запускается только один раз.

Значение: если вы пришли из существующего проекта Mvc, все, что вам нужно сделать, это:

  1. Добавить GlobalConfiguration.Configuration.EnsureInitialized (); в нижней части вашего метода Application_Start .

ИЛИ

  1. Переместите всю конфигурацию в один вызов GlobalConfiguration.Configure :
GlobalConfiguration.Configure(config => 
{
    WebApiConfig.Register(config);
    config.MapAttributeRoutes();
    ...
});

Копать глубже

HttpConfiguration.Configuration имеет свойство «Initializer», определенное следующим образом:

public Action<HttpConfiguration> Initializer;

HttpConfiguration.EnsureInitialized () запускает это действие и устанавливает для _initialized значение true

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

HttpConfiguration.MapAttributeRoutes вызывает внутренний метод AttributeRoutingMapper.MapAttributeRoutes, который устанавливает 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 работает EnsureInitialized сразу после вызова ваших действий:

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

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

Не забывайте, что если вы столкнетесь со стеной, источник asp.net доступен по адресу http://aspnetwebstack.codeplex.com/SourceControl/latest.

TField
источник
Решение с одним вызовом GlobalConfiguration.Configure спасло мне жизнь. У меня были проблемы с маршрутизацией на основе атрибутов и конфигурацией DI вместе с правильным порядком вызова конфигураций. Я также использую MS ApiVersioning, где мне нужно было сделать инъекции DI до того, как первый маршрут достигнет атрибутов управления версиями. Thx много
Silvos
12

У меня была связанная проблема. Иногда вызов GlobalConfiguration.Configureнесколько раз вызывает эту ошибку. В качестве обходного пути я поместил всю логику инициализации конфигурации в одном месте.

Глено
источник
Да, это была определенно проблема в моем случае
Оби
Спасибо! Это была именно моя проблема.
Сорен Бойзен
Та же проблема здесь! Пытаюсь решить проблему за пару часов, поэтому х за комментарий.
Sc0tTy
7

Для меня проблема заключалась в том, что я пытался использовать именованные параметры для полей строки запроса в моих маршрутах:

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

Поля строки запроса автоматически сопоставляются с параметрами и фактически не являются частью определения маршрута. Это работает:

[Route("my-route")]
public void MyRoute([FromUri] string field)
{
}
NathanAldenSr
источник
7

Хотя приведенный выше ответ работает, если incase не установлен, в моем случае этот материал уже был установлен. Отличие состояло в том, что для одного из написанных мною API я поставил перед маршрутом префикс /. пример

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

. Изменение этого к

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

исправил это для меня

Сервер 0
источник
@Svend Действительно. Казалось бы, глупость, но, похоже, проблема во многих случаях. : P
The 0bserver
@ The0bserver это сработало и для меня. Это было трудно диагностировать , так как в верхней части моего класса контроллера у меня был HttpPrefixдекоратор , а затем для моей индивидуальной конечной точки я имел декоратор: [Route("/")]. Простая передача пустой строки в маршруте исправила проблему.
Дэвид
1
Рад, что это помогло. :)
The 0bserver
7

ЕСЛИ ЭТА ОШИБКА СЧИТАЕТ, ЧТОБЫ ИДЕТ «НИЧЕГО» , то есть ваше приложение какое-то время прекрасно работало, спросите себя: я добавил действие в контроллер или изменил какие-либо маршруты до появления этой ошибки?

Если ответ «да» (и, вероятно, так и есть), вы, вероятно, допустили ошибку в процессе. Неправильное форматирование, копирование / вставка действия и забвение о том, что имена конечных точек уникальны и т. Д., Приведут вас сюда. Предположение, что эта ошибка связана с тем, как ее устранить, может привести к тому, что вы ошибетесь деревом.

Байрон Джонс
источник
Это именно то, что случилось со мной. Я изменил маршрут, но на конце оставил ошибочную фигурную скобку, например: [Route ("GetStuff}")]
Stu Цена
2

Вызов

GlobalConfiguration.Configuration.MapHttpAttributeRoutes();

перед

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

завершает его выполнение.

abatishchev
источник
2

Я получил эту ошибку, когда версия Newtonsoft.Json в моем основном проекте отличалась от вспомогательного проекта

Дэвид Лилльгегрен
источник
Быстрое добавление: не забудьте очистить свое решение после исправления проблемы с эталоном и дважды проверить, что последняя развернутая DLL является правильной версией :)
Марсель
1

Как правило, это исключение возникает, когда шаблоны маршрутов в «Маршрутизации атрибутов» неверны.

Например, я получил это, когда написал следующий код:

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

В синтаксисе ограничений маршрута {параметр: ограничение} ограничение по умолчанию имеет тип string . Не нужно упоминать это явно.

[Route("{dirName}/contents")] //correct
public HttpResponseMessage GetDirContents(string dirName) { ... }
Тарун Кумар
источник
0

Я начал получать эту ошибку однажды. После того, как я изменил наше приложение, чтобы позвонитьEnsureInitialized() я смог увидеть причину.

У меня был собственный атрибут, фильтр, для действия. В этом классе атрибутов были сделаны серьезные изменения в пакете NuGet, в котором он живет.

Несмотря на то, что я обновил код и все это скомпилировано, локальный работник IIS загружал старую DLL и не находил члена класса во время инициализации, считывал атрибуты действий и т. Д.

По какой-то причине (возможно, из-за порядка / при инициализации нашего ведения журнала) эта ошибка не была обнаружена, возможно, оставив WebAPI в странном состоянии, пока я не добавил EnsureInitialized() который перехватил исключение и обнаружил его.

Выполнение правильного binи objчистого с помощью удобного сценария решило это.

Люк Пуплетт
источник
0

В моем случае я создал веб-сервис в проекте A и запустил его из проекта B, и я получил именно эту ошибку. Проблема заключалась в том, что некоторые .dll-файлы, которые требуются A, отсутствуют в папке build-output-of B. Убедитесь, что эти .dll-файлы доступны и исправили это.

анион
источник
0

В моем случае я использовал Entity в качестве параметра моего действия, отсутствующего в его «Схеме».

Неправильный атрибут:

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

Верный :

[Table("Table name", Schema = "schema name")]
Реза Нафиси
источник