Como um aplicativo de API da Web .Net Core 3.0 de arquivo único deve ser configurado para procurar o appsettings.json
arquivo que está no mesmo diretório em que o aplicativo de arquivo único é criado?
Depois de correr
dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true
O diretório fica assim:
XX/XX/XXXX XX:XX PM <DIR> .
XX/XX/XXXX XX:XX PM <DIR> ..
XX/XX/XXXX XX:XX PM 134 appsettings.json
XX/XX/XXXX XX:XX PM 92,899,983 APPNAME.exe
XX/XX/XXXX XX:XX PM 541 web.config
3 File(s) 92,900,658 bytes
No entanto, tentar executar APPNAME.exe
resultados no seguinte erro
An exception occurred, System.IO.FileNotFoundException: The configuration file 'appsettings.json' was not found and is not optional. The physical path is 'C:\Users\USERNAME\AppData\Local\Temp\.net\APPNAME\kyl3yc02.5zs\appsettings.json'.
at Microsoft.Extensions.Configuration.FileConfigurationProvider.HandleException(ExceptionDispatchInfo info)
at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load(Boolean reload)
at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load()
at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
at Microsoft.AspNetCore.Hosting.WebHostBuilder.BuildCommonServices(AggregateException& hostingStartupErrors)
at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
...
Tentei soluções a partir de uma pergunta semelhante, mas distinta , bem como de outras questões do Stack Overflow.
Tentei passar o seguinte para SetBasePath()
Directory.GetCurrentDirectory()
environment.ContentRootPath
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)
Cada um deles levou ao mesmo erro.
A raiz do problema é que o PublishSingleFile
binário é descompactado e executado a partir de um temp
diretório.
No caso deste aplicativo de arquivo único, o local que ele estava procurando appsettings.json
era o seguinte diretório:
C:\Users\USERNAME\AppData\Local\Temp\.net\APPNAME\kyl3yc02.5zs
Todos os métodos acima apontam para o local em que o arquivo está descompactado, diferente do local em que foi executado.
fonte
Se você concorda em ter arquivos usados em tempo de execução fora do executável, basta sinalizar os arquivos que deseja fora, no csproj. Este método permite alterações em tempo real e em um local conhecido.
Se isso não é aceitável e deve ter APENAS um único arquivo, passo o caminho extraído por um único arquivo como o caminho raiz na configuração do meu host. Isso permite que a configuração e o razor (que adiciono depois) encontrem seus arquivos normalmente.
Observe que, para criar realmente um único arquivo e sem PDB, você também precisará:
fonte
Meu aplicativo está no .NET Core 3.1, é publicado como um único arquivo e é executado como um Serviço do Windows (que pode ou não ter impacto no problema).
A solução proposta com
Process.GetCurrentProcess().MainModule.FileName
a raiz do conteúdo funciona para mim, mas somente se eu definir a raiz do conteúdo no lugar certo:Isso funciona:
Isso não funciona:
fonte