no parameterless constructor defined for type dbcontext

Viewed 1687

I search many posts in stack and another sites about this error but it wasn't my answer this is my DbCintext

[Table("AspNetUsers")]
public class ApplicationUser : IdentityUser { }

public class EMSContext : IdentityDbContext<ApplicationUser> {
   

    public EMSContext (DbContextOptions<EMSContext> options) : base (options) { }

    public DbSet<Ambulance> Ambulances { get; set; }
 }

and this is mu StartUp.cs

 services.AddControllers();
        
        services.AddDbContext<EMSContext>(options =>
          options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

but when I want to generate api controller I got this error

no parameterless constructor defined for type dbcontext

3 Answers

The error is clear, you don't have a parameterless constructor.

But that said, the tooling shouldn't need it since you are calling AddDbContext and passing in your connection string. The tooling scaffolds controllers/etc. by actually running your program and then requesting the DbContext from the host's service provider. It does this by looking for methods with very specific names.

My guess is that your main Program.cs is not following the prescribed upon pattern and thus cannot construct your Host nor locate its ServiceProvider.

Your options are as follows (my personal choice is #2):

  • Add a paremeterless constructor like the message says
  • Make sure your main entry point uses the correct conventions for the host builder methods
  • Create a Design-Time context factory

Parameterless Constructor

This is the obvious answer, though it's not always possible. Furthermore it should not be necessary since the scaffolding has other means by which to read from your DbContext. Adding a constructor just for this purpose is not something I would do nor recommend.

Correct Naming / Method Signature

The scaffolding looks for a very specific method signature when it attempts to run your program. Basically, it is looking for something like this:

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>());
}

Now it doesn't need to look exactly like this. The important part is the name and signature of the CreateHostBuilder method.*

If there are any errors raised while attempting to construct the service, for example because there are dependencies that cannot be resolved or configuration is missing then this method will fail. I'm pretty sure you will get either the same error or a DI-related one.**

Design Time Factory

Supposing that still doesn't work or you'd like better control you can create a Design-Time Factory for your context. The tooling will scan your project for types implementing IDesignTimeDbContextFactory<EMSContext> and then use that during scaffolding:

public class EMSContextFactory : IDesignTimeDbContextFactory<EMSContext>
{
    public EMSContext CreateDbContext(string[] args)
    {
        var optionsBuilder = new DbContextOptionsBuilder<EMSContext>();
        optionsBuilder.UseSqlServer("Your Connection String");

        return new EMSContext(optionsBuilder.Options);
    }
}

See this link for more information.

* Note: You've not specified what version of aspnet core you are running. If you aren't using the generic host (Host.CreateDefaultBuilder) but are instead using WebHost, then the expected method signature will look a bit different. That said it will match that of creating a new project with the same settings.

If you've ever written integration tests for your controllers, the WebApplicationFactory looks for similar methods/signatures. Those same signatures should satisfy the controller scaffolding. I can't seem to find documentation on either other than the link above.

** When the scaffolding runs, it executes as the 'Production' environment. DI errors can occur if service resolution/configuration fails due to being in the "wrong" environment. This is one of the reasons the context factory solution exists.

The error is exactly located in this line:

public EMSContext (DbContextOptions<EMSContext> options) : base (options) { }

No parameterless constructors for DbContext... of course, because your constructor takes one parameter DbContextOptions options,

so you have two options to fix it, fix the call to the constructor or make the constructor take 0 parameters

Here's the error I was getting, sounds very similar to yours.enter image description here

I had encountered this problem when trying to create a View (the one circled in red). My issue was the Startup.cs file. I had recently done a re-name from LeaveHistory... to LeaveRequest..., and when editing my Startup.cs file I made an incorrect change.

incorreect change

Line 39 should read:

services.AddScoped<ILeaveRequestRepository, LeaveRequestRepository>();  // no "I"

The error I was getting mentioned that the dbContext class didn't have a parameterless constructor - so it was totally deceptive, or at least not that helpful.

So to anyone else looking at this error, don't take it on it's face! I am fairly deep into this project, and none of my other controllers have parameterless constructors, at least not written out.

Think about other clerical changes you've made - class name changes, things like that. Perhaps the error message is not actually what it seems, and you've made a small error somewhere else that is simply generating a confusing error message.

Related