(Obligatory "I'm a novice and trying to learn" disclaimer here)
I am attempting to complete an exercise to create my first API in Visual Studio 2022 (the default weather one doesn't count). The app is supposed to be to store notes. I've been chasing errors all day. There are now two errors that I can't seem to get around. When I get rid of one, I get the other.
The current error is "Value cannot be null. (Parameter 'connectionString')" when I attempt to do a db migration with the command "dotnet ef migrations add InitialCreate -v". The output of that run is:
Using project 'C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\NotelyRestAPI.csproj'.
Using startup project 'C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\NotelyRestAPI.csproj'.
Writing 'C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\obj\NotelyRestAPI.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\aedwa\AppData\Local\Temp\tmp5530.tmp /verbosity:quiet /nologo C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\NotelyRestAPI.csproj
Writing 'C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\obj\NotelyRestAPI.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\aedwa\AppData\Local\Temp\tmp60CA.tmp /verbosity:quiet /nologo C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\NotelyRestAPI.csproj
Build started...
dotnet build C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\NotelyRestAPI.csproj /verbosity:quiet /nologo
C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\Models\Note.cs(11,23): warning CS8618: Non-nullable property 'Subject' must contain a non-null value when exiting constructor. Consider declaring the property as nullable. [C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\NotelyRestAPI.csproj]
C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\Models\Note.cs(12,23): warning CS8618: Non-nullable property 'Detail' must contain a non-null value when exiting constructor. Consider declaring the property as nullable. [C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\NotelyRestAPI.csproj]
C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\ConnectionService.cs(21,26): warning CS8601: Possible null reference assignment. [C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\NotelyRestAPI.csproj]
Build succeeded.
C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\Models\Note.cs(11,23): warning CS8618: Non-nullable property 'Subject' must contain a non-null value
when exiting constructor. Consider declaring the property as nullable. [C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\NotelyRestAPI.csproj]
C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\Models\Note.cs(12,23): warning CS8618: Non-nullable property 'Detail' must contain a non-null value when exiting constructor. Consider declaring the property as nullable. [C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\NotelyRestAPI.csproj]
C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\ConnectionService.cs(21,26): warning CS8601: Possible null reference assignment. [C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\NotelyRestAPI.csproj]
3 Warning(s)
0 Error(s)
Time Elapsed 00:00:27.11
Build succeeded.
dotnet exec --depsfile C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\bin\Debug\net6.0\NotelyRestAPI.deps.json --additionalprobingpath C:\Users\aedwa\.nuget\packages --additionalprobingpath "C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages" --additionalprobingpath C:\Microsoft\Xamarin\NuGet --additionalprobingpath "C:\Program Files\dotnet\sdk\NuGetFallbackFolder" --runtimeconfig C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\bin\Debug\net6.0\NotelyRestAPI.runtimeconfig.json C:\Users\aedwa\.dotnet\tools\.store\dotnet-ef\3.1.0\dotnet-ef\3.1.0\tools\netcoreapp3.1\any\tools\netcoreapp2.0\any\ef.dll migrations add InitialCreate --assembly C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\bin\Debug\net6.0\NotelyRestAPI.dll --startup-
assembly C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\bin\Debug\net6.0\NotelyRestAPI.dll --project-dir C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\ --language C# --working-dir C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI --verbose --root-namespace NotelyRestAPI
Using assembly 'NotelyRestAPI'.
Using startup assembly 'NotelyRestAPI'.
Using application base 'C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\bin\Debug\net6.0'.
Using working directory 'C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI'.
Using root namespace 'NotelyRestAPI'.
Using project directory 'C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\'.
The Entity Framework tools version '3.1.0' is older than that of the runtime '7.0.0-preview.7.22376.2'. Update the tools for the latest features and bug fixes. See https://aka.ms/AAc1fbw for more information.
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Finding application service provider in assembly 'NotelyRestAPI'...
Finding Microsoft.Extensions.Hosting service provider...
Using environment 'Development'.
Using application service provider from Microsoft.Extensions.Hosting.
Found DbContext 'NotelyDBContext'.
Finding DbContext classes in the project...
Using context 'NotelyDBContext'.
System.ArgumentNullException: Value cannot be null. (Parameter 'connectionString')
at Microsoft.EntityFrameworkCore.Utilities.Check.NotEmpty(String value, String parameterName)
at Microsoft.EntityFrameworkCore.SqliteDbContextOptionsBuilderExtensions.UseSqlite(DbContextOptionsBuilder optionsBuilder, String connectionString, Action`1 sqliteOptionsAction)
at NotelyRestAPI.Database.NotelyDBContext.OnConfiguring(DbContextOptionsBuilder optionsBuilder) in C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI\Database\NotelyDBContext.cs:line 18
at Microsoft.EntityFrameworkCore.DbContext.get_ContextServices()
at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<System.IServiceProvider>.get_Instance()
at Microsoft.EntityFrameworkCore.Infrastructure.Internal.InfrastructureExtensions.GetService[TService](IInfrastructure`1 accessor)
at Microsoft.EntityFrameworkCore.Infrastructure.AccessorExtensions.GetService[TService](IInfrastructure`1 accessor)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1 factory)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)
at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType, String namespace)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType, String namespace)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Value cannot be null. (Parameter 'connectionString')
PS C:\Users\aedwa\source\repos\NotelyRestAPI\NotelyRestAPI>
My Startup.cs looks like this:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using NotelyRestAPI.Database;
//using NotelyRestAPI.Repositories;
//using NotelyRestAPI.Repositories.Implementations;
namespace NotelyRestAPI
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
// Added from https://stackoverflow.com/questions/59861448/cannot-solve-this-error-no-database-provider-has-been-configured-for-this-dbco
ConnectionService.Set(configuration);
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
=> services.AddDbContext<NotelyDBContext>();
// Original code block deleted to make an empty function
// As was recommended by https://go.microsoft.com/fwlink/?linkid=851728
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Original code block deleted to make an empty function
// As was recommended by https://go.microsoft.com/fwlink/?linkid=851728
}
}
}
My Program.cs looks like this:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using NotelyRestAPI.Database;
//using NotelyRestAPI.Repositories;
//using NotelyRestAPI.Repositories.Implementations;
namespace NotelyRestAPI
{
public class Program
{
public static void Main(string[] args)
=> CreateHostBuilder(args).Build().Run();
// EF Core uses this method at design time to access the DbContext
public static IHostBuilder CreateHostBuilder(string[] args)
=> Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(
webBuilder => webBuilder.UseStartup<Startup>());
}
}
My NotelyDBContext.cs looks like this:
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using NotelyRestAPI.Database;
using NotelyRestAPI.Models;
namespace NotelyRestAPI.Database
{
public class NotelyDBContext : DbContext
{
public NotelyDBContext(DbContextOptions<NotelyDBContext> options) : base(options) { }
public DbSet<Note> Notes { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite(ConnectionService.connstring);
}
}
}
And my model Note.cs looks like:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace NotelyRestAPI.Models
{
public class Note
{
public long Id { get; set; }
public string Subject { get; set;}
public string Detail { get; set;}
public DateTime CreatedDate { get; set; }
public DateTime LastModified { get; set; }
public bool IsDeleted { get; set; }
}
}
The original code samples that I started the project with use SQLite so that is what my code above has. However it was throwing several errors that I was chasing down. I've gone through 7+ Stack Overflow pages and a few Microsoft pages chasing down the errors to finally get here, where the migration command doesn't immediately fail but then there's a single error at the end. Some of the code that I was following referenced SQLServer and not SQLite, so I modified it to suit. I don't know if that matters, but I thought it might be worth mentioning.
Hopefully someone out there can point out where I went wrong.