Я пытаюсь запустить измененную версию примера HelloWeb для ASP.NET vNext на DNX, используя Kestrel. Я понимаю, что это очень важно, но я надеюсь, что команда ASP.NET по крайней мере поддержит работу самого простого веб-приложения :)
Окружающая среда:
- Linux (Ubuntu, в значительной степени)
- Mono 3.12.1
- DNX 1.0.0-beta4-11257 (у меня тоже есть 11249)
Код "Веб-приложение", в Startup.cs
:
using Microsoft.AspNet.Builder;
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.UseWelcomePage();
}
}
Конфигурация проекта, в project.json
:
{
"dependencies": {
"Kestrel": "1.0.0-beta4",
"Microsoft.AspNet.Diagnostics": "1.0.0-beta4",
"Microsoft.AspNet.Hosting": "1.0.0-beta4",
"Microsoft.AspNet.Server.WebListener": "1.0.0-beta4",
"Microsoft.AspNet.StaticFiles": "1.0.0-beta4",
"Microsoft.Framework.Runtime": "1.0.0-beta4",
"Microsoft.Framework.Runtime.Common": "1.0.0-beta4",
"Microsoft.Framework.Runtime.Loader": "1.0.0-beta4",
"Microsoft.Framework.Runtime.Interfaces": "1.0.0-beta4",
},
"commands": {
"kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004"
},
"frameworks": {
"dnx451": {}
}
}
kpm restore
Кажется, работает нормально.
Однако, когда я пытаюсь запустить, я получаю исключение, предполагающее, что Microsoft.Framework.Runtime.IApplicationEnvironment
его нельзя найти. Командная строка и ошибка (несколько переформатированы)
.../HelloWeb$ dnx . kestrel
System.IO.FileNotFoundException: Could not load file or assembly
'Microsoft.Framework.Runtime.IApplicationEnvironment,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
or one of its dependencies.
File name: 'Microsoft.Framework.Runtime.IApplicationEnvironment,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke
(System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke
(System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder,
System.Object[] parameters, System.Globalization.CultureInfo culture)
[0x00000] in <filename unknown>:0
Хотя, очевидно, что моя самая насущная потребность - исправить это, я также был бы признателен за совет о том, как перейти к диагностике, что идет не так, чтобы я мог сам исправить подобные проблемы в будущем. (Это также, вероятно, сделает этот вопрос более полезным и для других.)
Я нашел Microsoft.Framework.Runtime.IApplicationEnvironment
в Microsoft.Framework.Runtime.Interfaces
источнике сборки , и, похоже, в последнее время это не изменилось. Непонятно, почему исключение отображает имя так, как будто оно представляет собой целую сборку, а не просто интерфейс внутри другой сборки. Я предполагаю, что это может быть связано с нейтральными интерфейсами сборки , но это не ясно из ошибки. ( [AssemblyNeutral]
мертв, значит, не то ... )
источник
Ответы:
Хороший вопрос. Для вашей конкретной проблемы похоже, что у вас есть несоответствие в ваших разрешенных зависимостях. Когда такие вещи случаются, скорее всего, потому что вы запускаете свое приложение на несовместимом dnx. Мы по-прежнему вносим очень серьезные изменения, поэтому, если вы когда-нибудь увидите, что отсутствует метод пропущенного типа, скорее всего, вы в конечном итоге запустили
betaX
пакеты иbetaY
dnx или наоборот.Более конкретно, в бета4 версии были удалены сборочные нейтральные интерфейсы, но похоже, что приложение, которое вы используете, все еще использует их.
Мы планируем сделать так, чтобы пакеты могли отмечать минимальный dnx, необходимый для запуска, чтобы сделать сообщение об ошибке более понятным. Кроме того, со временем разрушительные изменения стихнут.
В общем, я чувствую, что пришло время написать руководство о том, как диагностировать подобные проблемы при использовании dnx (так как он сильно отличается от существующего .NET).
Зависимости, которые вы вводите,
project.json
относятся только к верхнему уровню. Версии также всегда минимальны (это как пакет NuGet). Это означает, что когда вы указываете,Foo 1.0.0-beta4
вы действительно указываетеFoo >= 1.0.0-beta4
. Это означает, что если вы попросите указатьMVC 0.0.1
минимальную версию в настроенном фидеMVC 3.0.0
, вы ее получите. Мы также НИКОГДА не публикуем вашу версию, если вы не укажете ее. Если вы запрашиваете 1.0.0, и она существует, вы получите 1.0.0, даже если существуют более новые версии. Указание пустых версий ВСЕГДА плохо и будет запрещено в более поздних сборках.Мы представляем nuget новую функцию, называемую плавающими версиями. Сегодня он работает только с тегом предварительной версии, но в следующей версии он будет работать и с другими частями версии. Это похоже на синтаксис npm и gem для указания диапазонов версий в файле спецификации пакета.
1.0.0-*
- Средства дают мне HIGHEST-версию, соответствующую префиксу (в соответствии с правилами семантического управления версиями ) ИЛИ, если не существует версии, соответствующей этому префиксу, используйте нормальное поведение и получите мне LOWEST-версию> = указанной версии.Когда вы запускаете восстановление в последних сборках, он записывает файл с именем
project.lock.json
. Этот файл будет иметь транзитивное закрытие зависимостей для всех целевых платформ, определенных вproject.json
.Когда что-то подобное не получается, вы можете сделать следующее:
Взгляните на разрешенные зависимости с помощью
kpm list
. Это покажет вам разрешенные версии пакетов, на которые ссылается ваш проект, и какая зависимость вытащила его. Например, если A -> B, он покажет:Фактический вывод списка KPM:
Список зависимостей для ClassLibrary39 (C: \ Users \ davifowl \ Documents \ Visual Studio 14 \ Projects \ ClassLibrary39 \ src \ ClassLibrary39 \ project.json)
* означает прямую зависимость.
Если у вас есть работающая визуальная студия (которая сейчас не работает с DNX), вы можете посмотреть узел ссылок. Он имеет те же данные, представленные визуально:
Давайте посмотрим, как выглядит сбой зависимости:
Вот проект. Json
Newtonsoft.Json 8.0.0
не существует Таким образом, запуск восстановления kpm показывает следующее:При диагностировании, когда восстановление может быть неудачным, посмотрите на сделанные HTTP-запросы, они сообщают вам, в каких настроенных исходных пакетах просматриваются kpm. Обратите внимание, что на изображении выше есть
CACHE
запрос. Это встроенное кэширование на основе типа ресурса (nupkg или nuspec) и имеет настраиваемый TTL (см.kpm restore --help
). Если вы хотите принудительноkpm
поразить удаленные источники NuGet, используйте--no-cache
флаг:Эти ошибки также отображаются в Visual Studio в окне вывода журнала диспетчера пакетов:
Примечание!
Источники пакетов
Я опишу, как NuGet.config работает прямо сейчас (что, вероятно, изменится в будущем). По умолчанию у вас есть NuGet.config с исходным кодом NuGet.org по умолчанию, настроенным глобально
%appdata%\NuGet\NuGet.Config
. Вы можете управлять этими глобальными источниками в Visual Studio или с помощью инструмента командной строки NuGet. Вы должны всегда смотреть на свои эффективные источники (те, которые перечислены в выводе kpm), пытаясь диагностировать сбои.Узнайте больше о NuGet.config здесь
Обратно в реальность:
Когда зависимости не разрешены, запуск приложения даст вам следующее:
Среда выполнения в основном пытается проверить, что весь граф зависимостей разрешен перед попыткой запуска. Если он предлагает выполнить
kpm restore
это, потому что он не может найти перечисленные зависимости.Другая причина, по которой вы можете получить эту ошибку, заключается в том, что вы используете неправильный вариант dnx. Если ваше приложение указывает только dnx451 и вы пытаетесь запустить CoreCLR dnx, вы можете столкнуться с подобной проблемой. Обратите особое внимание на целевой фреймворк в сообщении об ошибке:
Для бега:
Когда вы пытаетесь запустить, вы должны помнить, что ментальное отображение от clr к целевой структуре определено в вашем
project.json
.Это также отображается в Visual Studio под узлом ссылки:
Узлы, отмеченные желтым, не разрешены.
Они также отображаются в списке ошибок:
Здание
Эти ошибки также отображаются при сборке. При сборке из командной строки вывод очень подробный и может быть чрезвычайно полезен при диагностике проблем:
В выходных данных показаны все сборки, переданные в компилятор из пакетов и ссылок на проекты. Когда вы начинаете получать ошибки сборки, полезно посмотреть здесь, чтобы убедиться, что используемый вами пакет действительно работает на этой целевой платформе.
Вот пример пакета, который не работает на dnxcore50:
Microsoft.Owin.Host.SystemWeb версии 3.0.0 не имеет сборок, работающих на dnxcore50 (взгляните на папку lib распакованного пакета). Когда мы бежим
kpm build
:Заметьте, что там написано «используя пакет Microsoft.Owin.Host.SystemWeb», но там нет «File:». Это могло быть причиной сбоя сборки.
Здесь заканчивается мой мозговой дамп
источник
Я до сих пор не знаю полностью, что случилось, но теперь у меня есть ряд шагов, чтобы хотя бы упростить попытки:
~/.config/NuGet.config
что вы используете правильные каналы NuGetЯ закончил тем, что использовал следующую командную строку, чтобы протестировать различные опции достаточно чистым способом:
Похоже, что моя проблема была действительно из-за неправильных версий устанавливаемых зависимостей. Номер версии
"1.0.0-beta4"
явно отличается от"1.0.0-beta4-*"
. Например, вKestrel
зависимости установлена версия 1.0.0-beta4-11185, если просто указано как1.0.0-beta4
, но версия 1.0.0-beta4-11262 с расширением-*
в конце. Я хотел указатьbeta4
явно, чтобы избежать случайного использования сборки beta3 сСледующий конфиг проекта работает нормально:
источник
-*
вы всегда получаете последнюю предварительную версию, а без нее вы получаете самую низкую версию, которая удовлетворяет всем зависимостям (как обычно в NuGet). Этот тест имеет несколько примеров."frameworks": {"dnx451": {}}
исправили для меня, в этом нет необходимостиdnxcore50
dnvm upgrade-self
, это не будет обновлять до последней версии. Запуск командной строки VS от имени администратора показал версию dnvm какrc1...
, но не как администраторbeta5...
. После вашей команды в командной строке отображаются как администратор, так и не администраторrc2...
(последняя версия).dnx451
илиdnxcore50
этот ответ помог мне понять эту тему немного больше: stackoverflow.com/a/30846048/89590 Краткий ответ:dnx451
подходит для моно.Вы можете установить env var с именем
DNX_TRACE
to,1
чтобы увидеть TON больше диагностической информации. Имейте в виду, это намного больше информации!источник
Чтобы заставить его работать, я изменил мой
project.json
.. теперь он выглядит так:Ключ, казалось, был разделом рамок.
Также переименование изменило, как
k web
работает так, чтобы его сейчасdnx . web
илиdnx . kestrel
Обновление - немного больше информации
Как ни странно, после запуска без определенных каркасов он пошел и получил кучу дополнительных вещей, когда я сделал
kpm restore
:.. потом все прошло нормально. Потом я переключился обратно в раздел фреймворка
.. и это все еще работало, тогда как прежде это выкинуло бы ошибку!
Очень странно!
(Я бегу
1.0.0-beta4-11257
)Дальнейшее обновление
Я раскручивается новый экземпляр Ubuntu, и получил ту же ошибку , как вы .. Моя мысль о том , что проблема может быть вызвана она только пытается получить пакеты от
nuget.org
и неmyget.org
(который имеет новые вещи) , так что я упал вNuGet.Config
в корень проекта .... это, кажется, исправило это для меня, получая правильные версии (после другого
kpm restore
).источник
В наши дни все мои
package.json
версии заканчиваются"-rc2-*"
(Единственные исключения, которые я видел до сих пор, это
Microsoft.Framework.Configuration
пакеты, которые должны быть либо"1.0.0-rc1-*"
или"1.0.0-*"
)Что касается «обучающих версий», о которых упоминает @davidfowl, кажется, что МНОГО боли исчезло между бета8 и rc2.
Мне больше всего повезло
coreclr
с этими двумя каналами NuGet:Когда у меня возникают проблемы с пакетами, 90% времени это те же самые виновники:
В большинстве случаев я могу обойти это, заставив основной канал NuGet.org:
Вот мой рабочий config.json:
источник
У меня также были проблемы с отсутствием зависимости при попытке утешить ссылки на dnxcore50 и dnx451.
Насколько я понимаю, "зависимости": {} разделяются между фреймворками.
Затем «зависимости»: {} внутри «фреймворков»: относятся к этому фреймворку.
dnxcore50 - это модульная среда выполнения (самодостаточная), поэтому она в основном содержит все основные среды выполнения, необходимые для запуска программы, в отличие от классической среды .net, где у вас есть основные зависимости, разбросанные в других местах.
Итак, с учетом сказанного, я хотел придерживаться минимального подхода, если в какой-то момент я решил разместить на Mac или Linux.
Обновление Возникли странные проблемы с зависимостями с представлениями cshtml, на данный момент просто использовал dnx451.
Это мой проект. Json
источник