i'm trying to create a web api with SQL Database server in and when i'm trying to post comes this error
System.InvalidOperationException: Unable to resolve service for type 'BooksApi.Data.BooksdbContext' while attempting to activate 'BooksApi.Controllers.BooksController'. at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired) at lambda_method9(Closure , IServiceProvider , Object[] ) at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass7_0.b__0(ControllerContext controllerContext) at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass6_0.g__CreateController|0(ControllerContext controllerContext) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Code:Program.cs
using BooksApi.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen();
var optionsBuilder = new DbContextOptionsBuilder();
var app = builder.Build();
if (app.Environment.IsDevelopment()){
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Books API V1"));}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseRouting();
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
app.MapControllers();
app.Run();
public class Startup{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public string ConnectionString => Configuration.GetConnectionString("BooksDb");
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<BooksdbContext>(opt => { opt.UseSqlServer(ConnectionString); });
services.AddHttpContextAccessor();
}
}
public class Program_2
{
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>());}
public class BooksDbContextFactory : IDesignTimeDbContextFactory<BooksdbContext>{
public IConfiguration Configuration { get; }
public BooksdbContext CreateDbContext(string[] args){
var optionsBuilder = new DbContextOptionsBuilder<BooksdbContext>();
optionsBuilder.UseSqlServer(("BooksDb"));
return new BooksdbContext(optionsBuilder.Options);
}
}
Model:
using System;
using System.Collections.Generic;
namespace BooksApi.Models{
public partial class Book
{
public int Id { get; set; }
public string Name { get; set; }
public string Genre { get; set; }
}
}
Context:
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using BooksApi.Models;
namespace BooksApi.Data{
public partial class BooksdbContext : DbContext
{
public BooksdbContext(DbContextOptions options)
{
}
public BooksdbContext(DbContextOptions<BooksdbContext> options)
: base(options)
{
}
public virtual DbSet<Book> Books { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Book>(entity =>
{
entity.Property(e => e.Id)
.ValueGeneratedNever()
.HasColumnName("id");
entity.Property(e => e.Genre)
.HasMaxLength(255)
.IsUnicode(false)
.HasColumnName("genre");
entity.Property(e => e.Name)
.IsRequired()
.HasMaxLength(255)
.IsUnicode(false)
.HasColumnName("name");
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}
Controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using BooksApi.Data;
using BooksApi.Models;
namespace BooksApi.Controllers{
[Route("api/[controller]")]
[ApiController]
public class BooksController : ControllerBase
{
private readonly BooksdbContext _context;
public BooksController(BooksdbContext context)
{
_context = context;
}
// GET: api/Books
[HttpGet]
public async Task<ActionResult<IEnumerable<Book>>> GetBooks()
{
return await _context.Books.ToListAsync();
}
// GET: api/Books/5
[HttpGet("{id}")]
public async Task<ActionResult<Book>> GetBook(int id)
{
var book = await _context.Books.FindAsync(id);
if (book == null)
{
return NotFound();
}
return book;
}
// PUT: api/Books/5
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
[HttpPut("{id}")]
public async Task<IActionResult> PutBook(int id, Book book)
{
if (id != book.Id)
{
return BadRequest();
}
_context.Entry(book).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!BookExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
// POST: api/Books
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
[HttpPost]
public async Task<ActionResult<Book>> PostBook(Book book)
{
_context.Books.Add(book);
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
if (BookExists(book.Id))
{
return Conflict();
}
else
{
throw;
}
}
return CreatedAtAction("GetBook", new { id = book.Id }, book);
}
// DELETE: api/Books/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteBook(int id)
{
var book = await _context.Books.FindAsync(id);
if (book == null)
{
return NotFound();
}
_context.Books.Remove(book);
await _context.SaveChangesAsync();
return NoContent();
}
private bool BookExists(int id)
{
return _context.Books.Any(e => e.Id == id);
}
}
}
CodePudding user response:
It's because you pass BooksdbContext context in the BooksController, but context hasn't been registered properly
I will recommend to do this:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddDbContext<BooksdbContext>(opt =>
{
opt.UseSqlServer(ConnectionString);
});
services.AddHttpContextAccessor();
return services.BuildServiceProvider();
}