Файл конфигурации appsettings.json не найден и не является обязательным
Ошибка Azure:
.Net Core: исключение при запуске приложения: System.IO.FileNotFoundException: файл конфигурации 'appsettings.json' не найден и не является обязательным.
Так что это немного расплывчато. Я не могу пригвоздить это. Я пытаюсь развернуть проект.Net Core Web API в Azure и получаю следующую ошибку:
:(Упс. 500 Internal Server Error Произошла ошибка при запуске приложения.
Я развернул старые добрые.Net WebAPI, и они сработали. Я следовал онлайн-урокам, и они сработали. Но так или иначе мой проект не работает. Включение stdoutLogEnabled в Web.config и просмотр потоковых журналов Azure дает мне следующее:
2016-08-26T02:55:12 Welcome, you are now connected to log-streaming service.
Application startup exception: System.IO.FileNotFoundException: The configuration file 'appsettings.json' was not found and is not optional.
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 Quanta.API.Startup..ctor(IHostingEnvironment env) in D:\Source\Workspaces\Quanta\src\Quanta.API\Startup.cs:line 50
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
at Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
at Microsoft.Extensions.Internal.ActivatorUtilities.GetServiceOrCreateInstance(IServiceProvider provider, Type type)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetServiceOrCreateInstance(IServiceProvider provider, Type type)
at Microsoft.AspNetCore.Hosting.Internal.StartupLoader.LoadMethods(IServiceProvider services, Type startupType, String environmentName)
at Microsoft.AspNetCore.Hosting.WebHostBuilderExtensions.<>c__DisplayClass1_0.<UseStartup>b__1(IServiceProvider sp)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.FactoryService.Invoke(ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.ScopedCallSite.Invoke(ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.SingletonCallSite.Invoke(ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass12_0.<RealizeService>b__0(ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureStartup()
at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices()
at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
Hosting environment: Production
Content root path: D:\home\site\wwwroot
Now listening on: http://localhost:30261
Application started. Press Ctrl+C to shut down.
Хорошо, это кажется простым. Он не может найти appsettings.json. Глядя на мой конфиг ( startup.cs), он выглядит очень хорошо определенным. Мой стартап выглядит так:
public class Startup
{
private static string _applicationPath = string.Empty;
private static string _contentRootPath = string.Empty;
public IConfigurationRoot Configuration { get; set; }
public Startup(IHostingEnvironment env)
{
_applicationPath = env.WebRootPath;
_contentRootPath = env.ContentRootPath;
// Setup configuration sources.
var builder = new ConfigurationBuilder()
.SetBasePath(_contentRootPath)
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
if (env.IsDevelopment())
{
// This reads the configuration keys from the secret store.
// For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
builder.AddUserSecrets();
}
builder.AddEnvironmentVariables();
Configuration = builder.Build();
}
private string GetXmlCommentsPath()
{
var app = PlatformServices.Default.Application;
return System.IO.Path.Combine(app.ApplicationBasePath, "Quanta.API.xml");
}
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
var pathToDoc = GetXmlCommentsPath();
services.AddDbContext<QuantaContext>(options =>
options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"],
b => b.MigrationsAssembly("Quanta.API")));
//Swagger
services.AddSwaggerGen();
services.ConfigureSwaggerGen(options =>
{
options.SingleApiVersion(new Info
{
Version = "v1",
Title = "Project Quanta API",
Description = "Quant.API",
TermsOfService = "None"
});
options.IncludeXmlComments(pathToDoc);
options.DescribeAllEnumsAsStrings();
});
// Repositories
services.AddScoped<ICheckListRepository, CheckListRepository>();
services.AddScoped<ICheckListItemRepository, CheckListItemRepository>();
services.AddScoped<IClientRepository, ClientRepository>();
services.AddScoped<IDocumentRepository, DocumentRepository>();
services.AddScoped<IDocumentTypeRepository, DocumentTypeRepository>();
services.AddScoped<IProjectRepository, ProjectRepository>();
services.AddScoped<IProtocolRepository, ProtocolRepository>();
services.AddScoped<IReviewRecordRepository, ReviewRecordRepository>();
services.AddScoped<IReviewSetRepository, ReviewSetRepository>();
services.AddScoped<ISiteRepository, SiteRepository>();
// Automapper Configuration
AutoMapperConfiguration.Configure();
// Enable Cors
services.AddCors();
// Add MVC services to the services container.
services.AddMvc()
.AddJsonOptions(opts =>
{
// Force Camel Case to JSON
opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles();
// Add MVC to the request pipeline.
app.UseCors(builder =>
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod());
app.UseExceptionHandler(
builder =>
{
builder.Run(
async context =>
{
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
var error = context.Features.Get<IExceptionHandlerFeature>();
if (error != null)
{
context.Response.AddApplicationError(error.Error.Message);
await context.Response.WriteAsync(error.Error.Message).ConfigureAwait(false);
}
});
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
// Uncomment the following line to add a route for porting Web API 2 controllers.
//routes.MapWebApiRoute("DefaultApi", "api/{controller}/{id?}");
});
//Ensure DB is created, and latest migration applied. Then seed.
using (var serviceScope = app.ApplicationServices
.GetRequiredService<IServiceScopeFactory>()
.CreateScope())
{
QuantaContext dbContext = serviceScope.ServiceProvider.GetService<QuantaContext>();
dbContext.Database.Migrate();
QuantaDbInitializer.Initialize(dbContext);
}
app.UseSwagger();
app.UseSwaggerUi();
}
}
Это прекрасно работает на местном уровне. Но как только мы публикуем в Azure, это терпит неудачу. Я в недоумении. Я создал новый основной проект.Net, который развертывается в Azure. Но этот один проект, в который я вкладываю все свое время, кажется провальным. Я готов скопировать и вставить код из проекта, который не запускается, и в новый проект, но мне действительно любопытно, что его нарушает.
Есть идеи?
РЕДАКТИРОВАТЬ: Таким образом, мой Program.cs был:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
namespace Quanta.API
{
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
}
}
Edit2: Per Frans, я проверил опцию publishOptions. Это было:
"publishOptions": {
"include": [
"wwwroot",
"web.config"
]
},
Я взял publishOptions из рабочего проекта и изменил его на::
"publishOptions": {
"include": [
"wwwroot",
"Views",
"Areas/**/Views",
"appsettings.json",
"web.config"
]
},
Он по-прежнему выдавал ошибку 500, но не давал трассировки стека, говоря, что он может загрузить appsettings.json. Теперь он жаловался на подключение к SQL. Я заметил, что мой код строки соединения SQL упоминается во многих сообщениях блога RC1. RC2.Net Core изменил его. Поэтому я обновил его до:
"Data": {
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=QuantaDb;Trusted_Connection=True;MultipleActiveResultSets=true"
}
},
И изменил мой стартап на:
services.AddDbContext<QuantaContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
b => b.MigrationsAssembly("Quanta.API")));
Наконец-то это сработало.
Я, должно быть, следовал более старому примеру RC1 и не понял этого.
15 ответов
Проверьте publishOptions в project.json и убедитесь, что в разделе "include" есть "appsettings.json". Они изменили модель публикации в RTM, чтобы потребовать от вас указать все, что вы хотите скопировать из каталога компиляции в веб-папку.
В моем случае файл appsettings.json
в папке проекта, но он не был отмечен Do not copy
Я изменил настройку на Copy always
(см. изображения ниже). И это сработало для меня.
Он автоматически добавит следующий XML в ваш project.csproj
файл:
<ItemGroup>
<Content Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
Я посмотрел на другой ответ, project.json
мертв, как говорит этот ответ.
В более поздних версиях ядра.net вместо файла project.json используется файл *.csproj.
Вы можете изменить файл, чтобы получить желаемый результат, добавив:
<ItemGroup>
<Content Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
Для меня ошибка использовала Directory.GetCurrentDirectory()
, Это работало нормально, работая локально, но на рабочем сервере не получалось при запуске программы из Powershell
, Заменено на Assembly.GetEntryAssembly().Location
и все заработало.
Полный код:
var builder = new ConfigurationBuilder()
.SetBasePath(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location))
.AddJsonFile("appsettings.json");
var configuration = builder.Build();
В вашем project.json
убедитесь, что вы включили appsettings.json
как copyToOutput
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true,
"copyToOutput": {
"include": [ "appsettings.json" ]
}
},
Для меня решено было включить appsettings.json
через интерфейс в выходном каталоге (Build directory), вот так:
Вам не нужно добавлять свой файл.json для публикации параметров. просто он ищет файл по неверному пути.
установить базовый путь, а затем добавить файл JSON, и он будет работать.
public Startup(IHostingEnvironment environment)
{
var builder = new ConfigurationBuilder()
.SetBasePath(environment.ContentRootPath)
.AddJsonFile("TestJson.json");
Configuration = builder.Build();
}
здесь конструктор запуска создается с помощью HostingEnviornment, а базовый путь задается текущим корневым путем. и это будет работать!
Для меня сработало изменение свойства Копировать в выходной каталог наappsettings.json
для копирования, если новее.
У меня была такая же ошибка, когда приложение запускается из сетевого ресурса. Он даже пытался найти
appsettings.json
файл на рабочем столе пользователя.
В итоге я объединил путь с исполняемым файлом, как показано ниже:
configuration
.AddJsonFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "appsettings.json"), optional: false, reloadOnChange: false)
.AddJsonFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"appsettings.{env.EnvironmentName}.json"), optional: true, reloadOnChange: false);
Я оказался здесь при публикации своей функции Azure из Visual Studio 2019. Я получил эту ошибку при попытке опубликовать свою функцию на портале с помощью файла appSettings.json. Он копировал appSettings.json в выходной каталог, но не в каталог публикации. Мне пришлось добавить строку ниже в.csproj проекта функции Azure.
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
Итак, мой.csproj будет выглядеть так:
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Для меня проблема заключалась в том, что файл appsettings.json был скрыт. Как он оказался скрытым, я понятия не имею, но .netcore ConfiguraitonFileProvider имеет проверку на наличие скрытых файлов и не загружает их, если они скрыты.
Этот ответ предназначен для... Кто-то пытается выполнить отладку в VS Code, но appsettings.json не обрабатывается. Я попробовал отладить то же решение в Visual Studio, и это сработало. Кроме того, я смог получить доступ к переменным среды. Версия приложения: Core 2.2.
Я удалил папку.vscode и снова отладил, и это сработало.
Была такая же проблема при использовании.net core 3, и это сработало.
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
надеюсь, что это хорошо
Для меня это было использованиеconfig.GetConnectionString();
чтобы получить значение вместоconfig.GetValue()
. Это после того, как я включил CopyAlways при нажатии на свойства appsettings.json (щелчок правой кнопкой мыши).
Для меня эта ошибка возникла из-за синтаксической ошибки в файле Json (опечатка: удаленная запятая). По умолчанию свойство "Копировать в выходной каталог" файла appsettings.json установлено на "Не копировать", что я считаю правильным.