Próbuję uruchomić zmodyfikowaną wersję przykładu HelloWeb dla ASP.NET vNext na DNX przy użyciu Kestrel. Rozumiem, że jest to bardzo na plusie, ale mam nadzieję, że zespół ASP.NET przynajmniej utrzyma działanie najprostszej możliwej aplikacji internetowej :)
Środowisko:
- Linux (Ubuntu, prawie)
- Mono 3.12.1
- DNX 1.0.0-beta4-11257 (mam też dostępne 11249)
Kod „aplikacji internetowej”, w Startup.cs
:
using Microsoft.AspNet.Builder;
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.UseWelcomePage();
}
}
Konfiguracja projektu, w 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
wydaje się działać dobrze.
Kiedy jednak próbuję uruchomić, pojawia się wyjątek sugerujący, że Microsoft.Framework.Runtime.IApplicationEnvironment
nie można go znaleźć. Wiersz poleceń i błąd (nieco przeformatowany)
.../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
Chociaż oczywiście moją najpilniejszą potrzebą jest naprawienie tego, byłbym również wdzięczny za porady, jak przejść, aby zdiagnozować, co się dzieje, aby móc samodzielnie naprawić podobne problemy w przyszłości. (Prawdopodobnie sprawi to również, że to pytanie będzie bardziej przydatne również dla innych).
Znalazłem Microsoft.Framework.Runtime.IApplicationEnvironment
w Microsoft.Framework.Runtime.Interfaces
źródle zestawu i wygląda na to, że ostatnio się nie zmieniło. Nie jest jasne, dlaczego wyjątek pokazuje nazwę tak, jakby była całym zestawem samym w sobie, a nie tylko interfejsem w innym zestawie. Zgaduję, że może to być spowodowane neutralnymi interfejsami montażu , ale nie jest to jasne z błędu. ( [AssemblyNeutral]
nie żyje, więc to nie to ... )
źródło
Odpowiedzi:
Dobre pytanie. W przypadku Twojego konkretnego problemu wygląda na to, że masz niezgodność w rozwiązanych zależnościach. Kiedy zdarzają się takie rzeczy, jest to prawdopodobnie spowodowane tym, że uruchamiasz aplikację na niezgodnym pliku dnx. Wciąż wprowadzamy bardzo duże zmiany, więc jeśli kiedykolwiek zauważysz, że brakuje metody lub typu, prawdopodobnie skończyłeś uruchomieniem
betaX
pakietów ibetaY
dnx lub odwrotnie.Mówiąc dokładniej, interfejsy Assembly Neutral zostały usunięte w wersji beta4, ale wygląda na to, że aplikacja, którą uruchomiłeś, nadal ich używa.
Planujemy zrobić to tak, aby pakiety mogły oznaczać minimalne dnx, których wymagają do uruchomienia, aby komunikat o błędzie był bardziej przejrzysty. Z biegiem czasu przełomowe zmiany zanikną.
Ogólnie jednak wydaje mi się, że nadszedł czas, aby napisać poradnik dotyczący diagnozowania takich problemów podczas korzystania z dnx (ponieważ różni się on od istniejącego .NET).
Zależności, w które wkładasz,
project.json
są tylko na najwyższym poziomie. Wersje są również zawsze wartościami minimalnymi (podobnie jak pakiet NuGet). Oznacza to, że kiedy określaszFoo 1.0.0-beta4
, naprawdę określaszFoo >= 1.0.0-beta4
. Oznacza to, że jeśli poprosisz,MVC 0.0.1
a minimalna wersja w skonfigurowanym kanale wynosiMVC 3.0.0
, otrzymasz tę. NIGDY nie udostępniamy również Twojej wersji, chyba że ją określisz. Jeśli poprosisz o 1.0.0 i istnieje, otrzymasz 1.0.0, nawet jeśli istnieją nowsze wersje. Określanie pustych wersji jest ZAWSZE złe i będzie niedozwolone w późniejszych kompilacjach.Wprowadzamy nową funkcję nuget o nazwie wersje pływające. Dziś działa tylko na tagu przedpremierowym, ale w następnej wersji będzie działać na większej liczbie części wersji. Jest to podobne do składni npm i gem do określania zakresów wersji w pliku specyfikacji pakietu.
1.0.0-*
- Oznacza, że daj mi NAJWYŻSZĄ wersję pasującą do prefiksu (zgodnie z regułami wersjonowania semantycznego ) LUB jeśli nie ma wersji pasującej do tego prefiksu, użyj normalnego zachowania i uzyskaj NAJNIŻSZĄ wersję> = określona wersja.Kiedy uruchomisz przywracanie w najnowszych kompilacjach, zapisze plik o nazwie
project.lock.json
. Ten plik będzie miał przechodnie zamknięcie zależności dla wszystkich platform docelowych zdefiniowanych wproject.json
.Gdy coś takiego zawiedzie, możesz wykonać następujące czynności:
Przyjrzyj się rozwiązanym zależnościom za pomocą
kpm list
. To pokaże rozwiązane wersje pakietów, do których odwołuje się twój projekt i jaka zależność go wciągnęła. Np. Jeśli A -> B, pokaże:Rzeczywiste dane wyjściowe listy KPM:
Lista zależności dla ClassLibrary39 (C: \ Users \ davifowl \ Documents \ Visual Studio 14 \ Projects \ ClassLibrary39 \ src \ ClassLibrary39 \ project.json)
* oznacza bezpośrednią zależność.
Jeśli masz działające studio wizualne (które obecnie zrywa z DNX), możesz spojrzeć na węzeł odwołań. Zawiera te same dane przedstawione wizualnie:
Spójrzmy, jak wygląda awaria zależności:
Oto plik project.json
Newtonsoft.Json 8.0.0
nie istnieje. Tak więc uruchomienie przywracania kpm pokazuje następujące informacje:Podczas diagnozowania, kiedy przywracanie mogło się nie powieść, spójrz na wykonane żądania HTTP, które informują, jakie skonfigurowane źródła pakietów szukały kpm. Zauważ, że na powyższym obrazku jest
CACHE
żądanie. Jest to wbudowane buforowanie oparte na typie zasobu (nupkg lub nuspec) i ma konfigurowalne TTL (patrzkpm restore --help
). Jeśli chcesz wymusićkpm
uderzenie w zdalne źródła NuGet, użyj--no-cache
flagi:Te błędy są również wyświetlane w programie Visual Studio w oknie danych wyjściowych dziennika menedżera pakietów:
Dygresja!
Źródła pakietów
Opiszę sposób, w jaki NuGet.config działa teraz (co prawdopodobnie zmieni się w przyszłości). Domyślnie masz NuGet.config z domyślnym źródłem NuGet.org skonfigurowanym globalnie w
%appdata%\NuGet\NuGet.Config
. Możesz zarządzać tymi globalnymi źródłami w programie Visual Studio lub za pomocą narzędzia wiersza polecenia NuGet. Podczas próby zdiagnozowania awarii należy zawsze spojrzeć na efektywne źródła (te wymienione w danych wyjściowych kpm).Przeczytaj więcej o NuGet.config tutaj
Powrót do rzeczywistości:
Gdy zależności są nierozwiązane, uruchomienie aplikacji da ci to:
Środowisko wykonawcze zasadniczo próbuje sprawdzić, czy cały wykres zależności jest rozwiązany przed próbą uruchomienia. Jeśli sugeruje uruchomienie, oznacza
kpm restore
to, że nie może znaleźć wymienionych zależności.Innym powodem, dla którego możesz otrzymać ten błąd, jest to, że używasz niewłaściwego smaku dnx. Jeśli twoja aplikacja określa tylko dnx451 i spróbujesz uruchomić CoreCLR dnx, możesz zobaczyć podobny problem. Zwróć szczególną uwagę na platformę docelową w komunikacie o błędzie:
Do biegania:
Kiedy próbujesz uruchomić, pamiętaj, że mapowanie mentalne z CLR na platformę docelową zdefiniowane w Twoim
project.json
.To również pojawia się w programie Visual Studio w węźle odwołań:
Węzły oznaczone na żółto są nierozwiązane.
Te również pojawiają się na liście błędów:
Budynek
Te błędy pojawiają się również podczas budowania. Podczas budowania z wiersza poleceń dane wyjściowe są bardzo szczegółowe i mogą być niezwykle przydatne podczas diagnozowania problemów:
Dane wyjściowe pokazują wszystkie zestawy przesłane do kompilatora z pakietów i odwołań do projektów. Gdy zaczniesz otrzymywać błędy kompilacji, warto zajrzeć tutaj, aby upewnić się, że pakiet, którego używasz, faktycznie działa na tej platformie docelowej.
Oto przykład pakietu, który nie działa na dnxcore50:
Microsoft.Owin.Host.SystemWeb w wersji 3.0.0 nie ma żadnych zestawów działających na dnxcore50 (spójrz na folder lib rozpakowanego pakietu). Kiedy biegamy
kpm build
:Zauważ, że jest napisane „using Package Microsoft.Owin.Host.SystemWeb”, ale nie ma „File:”. Może to być przyczyną niepowodzenia kompilacji.
Tutaj kończy się mój zrzut mózgu
źródło
Nadal nie wiem do końca, co było nie tak, ale mam teraz serię kroków, aby przynajmniej ułatwić wypróbowywanie różnych rzeczy:
~/.config/NuGet.config
czy używasz odpowiednich źródeł danych NuGetSkończyło się na tym, że użyłem następującego wiersza poleceń, aby przetestować różne opcje w dość czysty sposób:
Wygląda na to, że mój problem był naprawdę spowodowany instalacją niewłaściwych wersji zależności. Numer wersji programu
"1.0.0-beta4"
jest najwyraźniej zupełnie inny niż"1.0.0-beta4-*"
. Na przykładKestrel
zależność zainstalowała wersję 1.0.0-beta4-11185, gdy została określona jako1.0.0-beta4
, ale wersja 1.0.0-beta4-11262 z rozszerzeniem-*
na końcu. Chciałembeta4
wyraźnie określić, aby uniknąć przypadkowego użycia wersji beta3 z rozszerzeniemNastępująca konfiguracja projektu działa poprawnie:
źródło
-*
zawsze zapewnia najnowszą wersję wstępną, a bez niej uzyskujesz najniższą wersję, która spełnia wszystkie zależności (jak zwykle w przypadku NuGet). Ten test ma kilka przykładów."frameworks": {"dnx451": {}}
Naprawiono to dla mnie, nie ma potrzebydnxcore50
dnvm upgrade-self
, to nie zaktualizowałoby do najnowszej wersji. Uruchomienie wiersza poleceń VS jako admin pokazało wersję dnvm jakorc1...
, ale kiedy nie była jako adminbeta5...
. Porc2...
wydaniu polecenia monity poleceń administratora i innych użytkowników były wyświetlane jako (najnowsza) wersja.dnx451
czydnxcore50
ta odpowiedź pomogła mi nieco lepiej zrozumieć ten temat: stackoverflow.com/a/30846048/89590 Krótka odpowiedź:dnx451
jest odpowiednia dla mono.Można ustawić var env nazwie
DNX_TRACE
aby1
zobaczyć mnóstwo info Więcej diagnostycznego. Ostrzegam, to dużo więcej informacji!źródło
Aby to działało, zmodyfikowałem mój
project.json
… teraz wygląda tak:Wydawało się, że kluczem była sekcja dotycząca ram.
Zmiana nazwy również zmieniła sposób
k web
działania, tak że terazdnx . web
lubdnx . kestrel
Aktualizacja - trochę więcej informacji
Co dziwne, po uruchomieniu bez zdefiniowanych frameworków poszło i dostałem kilka dodatkowych rzeczy, gdy to zrobiłem
kpm restore
:.. wtedy wszystko poszło dobrze. Następnie wróciłem do sekcji frameworka
.. i nadal działało, a wcześniej wyrzucał błąd!
Bardzo dziwne!
(Biegnę
1.0.0-beta4-11257
)Dalsza aktualizacja
Uruchomiłem nową instancję Ubuntu i otrzymałem ten sam błąd co ty. Pomyślałem, że problem może być spowodowany tylko próbą pobrania pakietów z,
nuget.org
a niemyget.org
(która ma nowsze rzeczy), więc upuściłem aNuGet.Config
do katalog główny projektu .... wydaje się, że naprawiło to dla mnie poprzez pobranie poprawnych wersji (po kolejnej
kpm restore
).źródło
Obecnie wszystkie moje
package.json
wersje kończą się na"-rc2-*"
(Jedynymi wyjątkami, które widziałem do tej pory, są
Microsoft.Framework.Configuration
pakiety, które muszą być albo"1.0.0-rc1-*"
albo"1.0.0-*"
)Jeśli chodzi o „pociągi wersji”, o których wspomina @davidfowl, wydaje się, że DUŻO bólu zniknęło między wersjami beta8 i rc2.
Miałem najwięcej szczęścia
coreclr
z tymi 2 kanałami NuGet:Kiedy zrobić nie brakuje problemów pakiet 90% czasu, że to ci sami sprawcy:
W większości przypadków mogę to obejść, wymuszając główny kanał NuGet.org:
Oto mój działający config.json:
źródło
Miałem również problemy z brakującymi zależnościami, próbując uspokoić odniesienia dnxcore50 i dnx451.
Jeśli rozumiem to prawo „zależności”: {} są współdzielone między frameworkami.
Następnie „zależności”: {} w ramach „struktur”: są specyficzne dla tej struktury.
dnxcore50 to modułowe środowisko uruchomieniowe (samodzielne), więc zawiera w zasadzie wszystkie podstawowe środowiska wykonawcze potrzebne do uruchomienia programu, w przeciwieństwie do klasycznego środowiska .net, w którym podstawowe zależności są rozproszone w innych miejscach.
Powiedziawszy to, że chcę trzymać się minimalnego podejścia, w pewnym momencie zdecydowałem się hostować na Macu lub Linuksie.
Aktualizacja Napotkała dziwne problemy z zależnościami w widokach cshtml, na razie po prostu poszła z dnx451.
To jest mój project.json
źródło