Estou tentando executar uma versão modificada do exemplo HelloWeb para o ASP.NET vNext no DNX usando o Kestrel. Entendo que isso está muito no limite, mas espero que a equipe do ASP.NET mantenha pelo menos o aplicativo Web mais simples possível funcionando :)
Meio Ambiente:
- Linux (Ubuntu, basicamente)
- Mono 3.12.1
- DNX 1.0.0-beta4-11257 (também tenho 11249 disponíveis)
Código "aplicativo da Web", em Startup.cs
:
using Microsoft.AspNet.Builder;
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.UseWelcomePage();
}
}
Configuração do projeto, em 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
parece funcionar bem.
Quando tento executar, no entanto, recebo uma exceção sugerindo que Microsoft.Framework.Runtime.IApplicationEnvironment
não pode ser encontrada. Linha de comando e erro (um pouco reformatado)
.../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
Embora, obviamente, minha necessidade mais urgente seja corrigir isso, também gostaria de receber conselhos sobre como avançar para diagnosticar o que está acontecendo de errado, para que eu possa resolver problemas semelhantes no futuro. (Isso também provavelmente tornará essa pergunta mais útil para outras pessoas.)
Encontrei Microsoft.Framework.Runtime.IApplicationEnvironment
na Microsoft.Framework.Runtime.Interfaces
fonte do assembly e isso não parece ter mudado recentemente. Não está claro por que a exceção mostra o nome como se fosse um assembly inteiro, em vez de apenas uma interface dentro de outro assembly. Eu acho que isso pode ser devido a interfaces neutras de montagem , mas não está claro com o erro. ( [AssemblyNeutral]
está morto, então não é isso ... )
fonte
Respostas:
Boa pergunta. Para o seu problema específico, parece que você tem uma incompatibilidade nas dependências resolvidas. Quando coisas assim acontecem, é provável que você esteja executando seu aplicativo em um dnx incompatível. Ainda estamos fazendo grandes alterações, por isso, se você encontrar um método ausente do tipo ausente, é provável que tenha acabado executando
betaX
pacotes ebetaY
dnx ou vice-versa.Ainda mais especificamente, as interfaces neutras de montagem foram removidas na versão beta4, mas parece que o aplicativo que você está executando ainda as está usando.
Planejamos fazê-lo para que os pacotes possam marcar o dnx mínimo necessário para executar para tornar a mensagem de erro mais clara. Além disso, com o passar do tempo, as mudanças de ruptura desaparecerão.
Em geral, porém, sinto que é hora de escrever um guia sobre como diagnosticar problemas como esse ao usar o dnx (já que é bem diferente do .NET existente).
As dependências nas quais você coloca
project.json
são apenas de nível superior. As versões também são sempre mínimas (é como um pacote NuGet). Isso significa que, quando você especifica,Foo 1.0.0-beta4
está realmente especificandoFoo >= 1.0.0-beta4
. Isso significa que, se você solicitarMVC 0.0.1
e as versões mínimas no seu feed configuradoMVC 3.0.0
, você receberá esse. Também NUNCA lançamos sua versão a menos que você a especifique. Se você solicitar a 1.0.0 e ela existir, você receberá a 1.0.0, mesmo que existam versões mais recentes. A especificação de versões vazias SEMPRE é ruim e não será permitida em versões posteriores.Há um novo recurso que estamos apresentando ao nuget chamado versões flutuantes. Hoje funciona apenas na tag de pré-lançamento, mas na próxima versão funcionará em mais partes da versão. Isso é semelhante à sintaxe npm e gem para especificar intervalos de versão no arquivo de especificação do pacote.
1.0.0-*
- Significa fornecer a versão MAIS ALTA que corresponde ao prefixo (de acordo com as regras de controle de versão semântica ) OU, se não houver uma versão correspondente a esse prefixo, use o comportamento normal e obtenha a versão MAIS BAIXA> = a versão especificada.Ao executar a restauração nas versões mais recentes, ele gravará um arquivo chamado
project.lock.json
. Este arquivo terá o fechamento transitivo de dependências para todas as estruturas de destino definidas emproject.json
.Quando algo assim falha, você pode fazer o seguinte:
Dê uma olhada nas dependências resolvidas usando
kpm list
. Isso mostrará as versões resolvidas dos pacotes referenciadas pelo seu projeto e qual dependência o atraiu. Por exemplo, se A -> B, mostrará:Saída real da lista KPM:
Listando dependências para ClassLibrary39 (C: \ Usuários \ davifowl \ Documents \ Visual Studio 14 \ Projects \ ClassLibrary39 \ src \ ClassLibrary39 \ project.json)
* significa dependência direta.
Se você possui um visual studio em funcionamento (que rompe com o DNX agora), pode ver o nó de referências. Tem os mesmos dados representados visualmente:
Vejamos como é uma falha de dependência:
Aqui está o project.json
Newtonsoft.Json 8.0.0
não existe. Portanto, a execução do kpm restore mostra o seguinte:Ao diagnosticar quando a restauração pode ter falhado, observe as solicitações HTTP feitas, elas informam em qual fonte de pacote configurada o kpm foi acessado. Observe na imagem acima que há uma
CACHE
solicitação. Esse é o cache embutido com base no tipo de recurso (nupkg ou nuspec) e possui um TTL configurável (vejakpm restore --help
). Se você deseja forçarkpm
a acessar as fontes remotas do NuGet, use o--no-cache
sinalizador:Esses erros também aparecem no Visual Studio na janela de saída do log do gerenciador de pacotes:
Nota!
Fontes do pacote
Descreverei como o NuGet.config funciona agora (o que provavelmente mudará no futuro). Por padrão, você tem um NuGet.config com a fonte NuGet.org padrão configurada globalmente em
%appdata%\NuGet\NuGet.Config
. Você pode gerenciar essas fontes globais no visual studio ou com a ferramenta de linha de comando NuGet. Você deve sempre olhar para suas fontes eficazes (as listadas na saída em kpm) ao tentar diagnosticar falhas.Leia mais sobre o NuGet.config aqui
De volta à realidade:
Quando as dependências não são resolvidas, a execução do aplicativo fornece o seguinte:
O tempo de execução basicamente tenta validar que todo o gráfico de dependência foi resolvido antes de tentar executar. Se sugere executar
kpm restore
, é porque não consegue encontrar as dependências listadas.Outra razão pela qual você pode receber esse erro é se estiver executando o sabor dnx errado. Se o seu aplicativo especificar apenas dnx451 e você tentar executar o CoreCLR dnx, poderá encontrar um problema semelhante. Preste muita atenção à estrutura de destino na mensagem de erro:
Para correr:
Ao tentar executar, lembre-se do mapeamento mental do clr para o framework de destino definido no seu
project.json
.Isso também aparece no Visual Studio no nó de referências:
Os nós marcados como amarelos não foram resolvidos.
Eles também aparecem na lista de erros:
Construção
Esses erros também aparecem ao criar. Ao criar a partir da linha de comando, a saída é muito detalhada e pode ser extremamente útil ao diagnosticar problemas:
A saída mostra todos os assemblies passados para o compilador a partir de pacotes e referências de projeto. Quando você começa a obter falhas de construção, é útil procurar aqui para garantir que o pacote que você está usando realmente funcione nessa plataforma de destino.
Aqui está um exemplo de um pacote que não funciona no dnxcore50:
O Microsoft.Owin.Host.SystemWeb versão 3.0.0 não possui nenhum assembly que é executado no dnxcore50 (consulte a pasta lib do pacote descompactado). Quando corremos
kpm build
:Observe que ele diz "usando o Pacote Microsoft.Owin.Host.SystemWeb", mas não há "Arquivo:". Esse pode ser o motivo de uma falha na compilação.
Aqui termina meu despejo cerebral
fonte
Ainda não sei completamente o que estava errado, mas agora tenho uma série de etapas para pelo menos facilitar as tentativas:
~/.config/NuGet.config
se você está usando os feeds NuGet certosAcabei usando a seguinte linha de comando para testar várias opções de uma maneira razoavelmente limpa:
Parece que meu problema foi realmente devido às versões erradas das dependências que estão sendo instaladas.
"1.0.0-beta4"
Aparentemente, um número de versão de é bastante diferente"1.0.0-beta4-*"
. Por exemplo, aKestrel
dependência instalou a versão 1.0.0-beta4-11185 quando apenas especificada como1.0.0-beta4
, mas a versão 1.0.0-beta4-11262 com o-*
no final. Eu queria especificarbeta4
explicitamente para evitar usar acidentalmente uma versão beta3 com oA seguinte configuração do projeto funciona bem:
fonte
-*
sempre fornece a versão mais recente do pré-lançamento, enquanto sem ela você obtém a versão mais baixa que satisfaz todas as dependências (como é habitual no NuGet). Este teste tem alguns exemplos."frameworks": {"dnx451": {}}
tinha consertado para mim, não há necessidade dednxcore50
dnvm upgrade-self
, isso não seria atualizado para a versão mais recente. A execução do prompt de comando do VS como administrador mostrou a versão do dnvm comorc1...
, no entanto, quando não era como o administrador, erabeta5...
. Após o seu comando, os prompts de comando admin e non admin apareceram como arc2...
versão (mais recente).dnx451
oudnxcore50
esta resposta me ajudou a entender um pouco mais esse tópico: stackoverflow.com/a/30846048/89590 Resposta curta:dnx451
é apropriado para mono.Você pode definir uma var env chamado
DNX_TRACE
para1
ver um TON informações mais diagnóstico. Esteja avisado, é muito mais informação!fonte
Para fazê-lo funcionar, modifiquei o meu
project.json
.. agora se parece com:A chave parecia ser a seção de estruturas.
Também a renomeação mudou como
k web
funciona, de modo que agoradnx . web
oudnx . kestrel
Atualização - pouco mais informações
Estranhamente, depois de rodar sem estruturas definidas, ele ganhou um monte de coisas extras quando eu fiz
kpm restore
:.. então correu bem. Então eu mudei de volta na seção de estrutura
.. e ainda funcionou, enquanto antes isso geraria um erro!
Muito estranho!
(Estou correndo
1.0.0-beta4-11257
)Atualização adicional
Virei-se uma nova instância Ubuntu, e tenho o mesmo erro como você .. Meu pensamento foi que o problema pode ser causado por apenas tentando obter pacotes a partir
nuget.org
e nãomyget.org
(que tem as coisas mais recentes) para que eu caiu em umNuGet.Config
no raiz do projeto .... isso parece ter corrigido isso para mim, obtendo as versões corretas (depois da outra
kpm restore
).fonte
Hoje em dia, todas as minhas
package.json
versões terminam em"-rc2-*"
(Apenas as exceções que vi até agora são os
Microsoft.Framework.Configuration
pacotes, que precisam ser um"1.0.0-rc1-*"
ou"1.0.0-*"
)Com relação aos "trens de versão" mencionados por @davidfowl, parece que muita dor desapareceu entre beta8 e rc2.
Eu tive mais sorte
coreclr
com esses 2 feeds NuGet:Quando eu faço tem falta de problemas de pacotes, 90% do tempo é esses mesmos culpados:
Na maioria das vezes, eu posso contornar isso forçando o feed principal do NuGet.org:
Aqui está o meu config.json de trabalho:
fonte
Eu também estava tendo problemas com problemas de dependência ao tentar apaziguar as referências dnxcore50 e dnx451.
Se eu entendo essas "dependências" corretas: {} são compartilhadas entre as estruturas.
Em seguida, "dependências": {} dentro das "estruturas": são específicas para essa estrutura.
O dnxcore50 é um tempo de execução modular (independente), portanto contém basicamente todos os tempos de execução principais necessários para executar um programa diferente da estrutura clássica .net, na qual você tem dependências principais espalhadas por outros lugares.
Então, com isso dito, eu queria seguir a abordagem mínima, caso eu decidisse hospedar no mac ou linux em algum momento.
Atualizar Ocorreu um problema estranho de dependência com as exibições cshtml, apenas foi fornecido com o dnx451 por enquanto.
Este é o meu project.json
fonte