Unable to resolve service DbContext while attempting to activate controller - c#

I have my own DbContext:
public class DreamsContext : DbContext
{
public DbSet<UserAccount> UserAccounts { get; set; }
public DbSet<DreamPublication> DreamPublications { get; set; }
public DreamsContext(DbContextOptions<DreamsContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<UserAccount>().ToTable("dreams_user");
modelBuilder.Entity<DreamPublication>().ToTable("dream_publications");
base.OnModelCreating(modelBuilder);
}
}
where UserAccount and DreamPublication contain just a few fields with get and set.
In my startup I add this for the DbContext:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<Models.DreamsContext>(options =>
options.UseSqlServer("server = SCAT\\SQLEXPRESS; database = dreams_web; Trusted_Connection=True ; MultipleActiveResultSets = true"));
}
And then I'm trying to inject my DbContext into a controller using DI:
private readonly Models.DreamsContext _context;
public SignUpController (Models.DreamsContext dbContext)
{
_context = dbContext;
}
But when I am trying to do something with this context I get an exception:
Unable to resolve service for type '(My DbContext)' while attempting to activate '(My controller)'
And I don't know what to do, on MSDN they do just this and everything works
Update. This is what written in console
System.InvalidOperationException: Unable to resolve service for type 'DreamWeb.Models.DreamsContext' while attempting to activate 'DreamWeb.Controllers.SignUpController'.
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method25(Closure , IServiceProvider , Object[] )
at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass7_0.<CreateActivator>b__0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass6_0.<CreateControllerFactory>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.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

The main problem was I was trying to configure services in Startup class, while I am using asp.net CORE so the main magic is going in program.cs
I moved everything to program.cs and everything is working fine. It cost me a few days, even it's such a little mistake
https://learn.microsoft.com/en-us/dotnet/architecture/porting-existing-aspnet-apps/app-startup-differences
According to this, startup should continue to work in asp.net core, but i had problems with it

I had the same problem I solved by adding the connection to the db in the main file of the Project Program.cs , add it after the line var builder :
// db connection
builder.Services.AddDbContext<Dbcontexclass>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnectionString"));
Add in appsettings.json :
"ConnectionStrings": {
"DefaultConnectionString": "SERVER=server;DATABASE=database;User ID=user;PASSWORD=password;"
}
fill the Connection String , Dbcontexclass , and it should work, I leave you the docs link ( https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/working-with-sql?view=aspnetcore-7.0&tabs=visual-studio )

Related

.NET 6 API System.InvalidOperationException

I have Autofac module like this on one class;
public class AutofacBusinessModule:Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<ProductManager>().As<IProductService>();
builder.RegisterType<EfProductDal>().As<IProductDal>();
builder.RegisterType<CategoryManager>().As<ICategoryService>();
builder.RegisterType<EfCategoryDal>().As<ICategoryDal>();
builder.RegisterType<CustomerManager>().As<ICustomerService>();
builder.RegisterType<EfCustomerDal>().As<ICustomerDal>();
builder.RegisterType<RegionManager>().As<IRegionService>();
builder.RegisterType<EfRegionDal>().As<IRegionDal>();
builder.RegisterType<TerritoryManager>().As<ITerritoryService>();
builder.RegisterType<EfTerritoryDal>().As<ITerritoryDal>();
builder.RegisterType<ShipperManager>().As<IShipperService>();
builder.RegisterType<EfShipperDal>().As<IShipperDal>();
builder.RegisterType<EmployeeManager>().As<IEmployeeDal>();
builder.RegisterType<EfEmployeeDal>().As<IEmployeeDal>();
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces()
.EnableInterfaceInterceptors(new ProxyGenerationOptions()
{
Selector = new AspectInterceptorSelector()
}).SingleInstance();
}
my api code its there;
[Route("api/[controller]")]
[ApiController]
public class ProductsController : Controller
{
private readonly IProductService _productService;
public ProductsController(IProductService productService)
{
_productService = productService;
}
[HttpGet("getall")]
public IActionResult GetAllProducts()
{
var result = _productService.GetAll();
if (result.Success)
{
return Ok(result);
}
return BadRequest(result);
}
}
}
I add this on program.cs but didn't work, if lower I use .net 6 i fix it like that but i dont know how to fix .net 6 because startup doesnt exists anymore.
IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(builder =>
{
builder.RegisterModule(new AutofacBusinessModule());
});
How can I fix this?
it gives me that error
System.InvalidOperationException: Unable to resolve service for type 'TAO.Business.Abstract.IProductService' while attempting to activate 'TAO.WebApi.Controllers.ProductsController'.
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method3(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.Authorization.AuthorizationMiddleware.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)
HEADERS
=======
Accept: */*
Connection: keep-alive
Host: localhost:7019
User-Agent: PostmanRuntime/7.30.0
Accept-Encoding: gzip, deflate, br
Postman-Token: fbff062e-ca49-4f37-afc5-e8785afbd43c
Try the following code from migration doc:
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
// Register services directly with Autofac here. Don't
// call builder.Populate(), that happens in AutofacServiceProviderFactory.
builder.Host.ConfigureContainer<ContainerBuilder>(builder => builder.RegisterModule(new AutofacBusinessModule()));
Note that the "old" generic hosting model still works in .NET 6, there is no requirement to use the new minimal hosting model (but you need to copy not only CreateHostBuilder method but also contents of old Program.Main into the new Program top-level statement file).

throw user defined exception message when an unregistered dependency is resolved

I have 1 service like below
public interface IGopalSharma
{
}
Now, if I forgot the implementation of this interface IGopalSharma and use this service in constructor as below
private readonly IGopalSharma _gopalSharma;
public ClientsController(IGopalSharma gopalSharma)
{
_gopalSharma = gopalSharma ?? throw new ArgumentNullException(
"An implementation of IGopalSharma must be provided");
}
So I want to return this "An implementation of IGopalSharma must be provided" msg.
but something different is coming.
System.InvalidOperationException: Unable to resolve service for type 'SAPI.Services.Interface.IGopalSharma' while attempting to activate 'SAPI.API.Controllers.ClientsController'.
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.<CreateActivator>b__0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass6_0.<CreateControllerFactory>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.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.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)
I want custom msg here. How can I do it?

I can't get records from .net core mvc web api database

I couldn't solve it in any way, can you please help?
I added web api to my .net core mvc project. I can return values as string or json, quite normally. But when it comes to the database, I have a problem. I am getting a null error. No matter how hard I searched, I couldn't figure it out. The smallest answer helps a lot.
[ApiController] When I add it, my app doesn't open at all. When I make a comment line, it opens. But I can't call database methods. The same operations can be called seamlessly in the webui layer.
Startup.cs
Appsettings
Can you please help?
Fail:
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.NullReferenceException: Object reference not set to an instance of an object.
at zfc.webapi.Controllers.zfc.GetReferrer() in C:\Users\mderv\Desktop\zfc\zfc.webapi\Controllers\zfc.cs:line 26
at lambda_method(Closure , Object , Object[] )
at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
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 where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Csproj
Repository
From your screenshots and error so far I am assuming you haven't register the service in startup.cs file correctly.
Here I am adding a complete example for you how you can access data from database using your architecture.
Abstract:
public interface IChatRepository
{
object GetDataFromDatabase();
}
Concrete:
public class ChatRepository : IChatRepository
{
private readonly AppDbContext _dbContext;
public ChatRepository(AppDbContext dbContext)
{
this._dbContext = dbContext;
}
public object GetDataFromDatabase()
{
var dataFromDatabase = _dbContext.PrinterJobs.ToList();
return dataFromDatabase;
}
}
Note: I have injected a dbContext class instance here to access database object. This dbContext, IChatRepository and ChatRepository need to be registered in startup.cs file.
Startup:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options => options.AddPolicy("AllowAll", p => p.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()));
services.AddScoped<IChatRepository, ChatRepository>();
services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddMvc().AddRazorPagesOptions(options =>
{
options.Conventions.ConfigureFilter(new IgnoreAntiforgeryTokenAttribute());
});
}
AppDbContext:
public class AppDbContext: DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
}
public DbSet<PrinterJob> PrinterJobs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<PrinterJob>().ToTable("PrintJob");
}
internal object Query<T>(string v, string name, int employeeId)
{
throw new NotImplementedException();
}
}
PrinterJob sample model class:
public class PrinterJob
{
[Key]
public int PrinterId { get; set; }
public string PrinterName { get; set; }
public int PrintedBy { get; set; }
public int TotalPrint { get; set; }
}
Database script:
CREATE TABLE PrintJob
(
[PrinterId] [int] PRIMARY KEY IDENTITY(1,1) NOT NULL,
[PrinterName] [nvarchar](100) NULL,
[PrintedBy] [int] NULL,
[TotalPrint] [int] NULL,
)
Note: add some sample data into the table once you create the table from about script.
appsettings.json:
"ConnectionStrings": {
"DefaultConnection": "Server=YourServerName;Database=YourDatabaseName;Trusted_Connection=True;MultipleActiveResultSets=true"
}
Note: make sure you are referring a correct database to access your data accordingly.
Controller:
[Route("api/ZfcData")]
public class ZfcDataController : Controller
{
private readonly IChatRepository _chatRepository;
public ZfcDataController(IChatRepository chatRepository)
{
this._chatRepository = chatRepository;
}
[HttpGet("[action]")]
[Route("GetDataFromDatabase")]
[ActionName("GetDataFromDatabase")]
public object GetDataFromDatabase()
{
var callRepository = _chatRepository.GetDataFromDatabase();
return Ok(callRepository);
}
}
Output:
Hope it would guide you through, and help you to get resolve your problem and implementations.
You are using dependecy injection to use your chatRepository and the injection it's not well configured ,
services.AddScoped<InterfaceOfMyReposiory,ImplementationOfMyRepository>();
So let's suppose that your ChatRepository is :
public class ChatRepository :IChatRepository {
//some special impelementation
}
and you have an interface like this :
public interface IChatRepository {
// some great methods definitions
}
so in your startup.cs class you should configure it like this :
services.AddScoped<IChatRepository ,ChatRepository>();
you can check more in details here.
in your case this should solve the null exception :
ChatRepository : interface
EfChatRepository and EfGenericRepository : implementation
services.AddScoped<ChatRepository ,EfChatRepository>();
EfChatRepository inherit the implemntation of EfGenericRepository

'No such table' after Deploying ASP.Net Core API with SQLite DB on Linux

UPDATE: I was able to locate the measurements.db file in the root path. It does not have a Measurements-Table like the error-message says, which propably causes it.
Replacing it with my local file - fixes it and the program works as intended.
So my question changes: Why does it not create the Measurements-Table inside the db-file?
Hey there,
First of all the project runs fine locally! I am having the issue that after publishing (with the command dotnet publish -c Release -r debian-x64), moving the files of the publish-folder to the Linux VM and launching with dotnet MessdatenController.ddl that it is unable to create the measurements.db file by itself which propably results in the following error. (Nor does it find it, when adding/uploading it manualy).
info: Microsoft.Hosting.Lifetime[0]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
Content root path: /
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 GET http://IP.OF.LINUX.VM/api/Measurements/GetMeasurements
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint 'MessdatenController.Controllers.MeasurementsController.GetMeasurements (MessdatenController)'
info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[3]
Route matched with {action = "GetMeasurements", controller = "Measurements"}. Executing controller action with signature Microsoft.AspNetCore.Mvc.ActionResult`1[System.Collections.Generic.IEnumerable`1[MessdatenController.Models.Measurement]] GetMeasurements() on controller MessdatenController.Controllers.MeasurementsController (MessdatenController).
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 3.1.9 initialized 'MeasurementsContext' using provider 'Microsoft.EntityFrameworkCore.Sqlite' with options: None
fail: Microsoft.EntityFrameworkCore.Database.Command[20102]
Failed executing DbCommand (21ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT "m"."MeasurementId", "m"."PM10", "m"."PM25", "m"."Posted", "m"."Timestamp"
FROM "Measurements" AS "m"
ORDER BY "m"."Timestamp"
fail: Microsoft.EntityFrameworkCore.Query[10100]
An exception occurred while iterating over the results of a query for context type 'MessdatenController.Business.MeasurementsContext'.
Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 1: 'no such table: Measurements'.
at Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
at Microsoft.Data.Sqlite.SqliteCommand.PrepareAndEnumerateStatements(Stopwatch timer)+MoveNext()
at Microsoft.Data.Sqlite.SqliteCommand.GetStatements(Stopwatch timer)+MoveNext()
at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader()
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.InitializeReader(DbContext _, Boolean result)
at Microsoft.EntityFrameworkCore.Storage.Internal.NoopExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext()
Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 1: 'no such table: Measurements'.
at Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
at Microsoft.Data.Sqlite.SqliteCommand.PrepareAndEnumerateStatements(Stopwatch timer)+MoveNext()
at Microsoft.Data.Sqlite.SqliteCommand.GetStatements(Stopwatch timer)+MoveNext()
at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader()
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.InitializeReader(DbContext _, Boolean result)
at Microsoft.EntityFrameworkCore.Storage.Internal.NoopExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext()
info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[2]
Executed action MessdatenController.Controllers.MeasurementsController.GetMeasurements (MessdatenController) in 1061.5466ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint 'MessdatenController.Controllers.MeasurementsController.GetMeasurements (MessdatenController)'
fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HM4PTAT76L67", Request id "0HM4PTAT76L67:00000001": An unhandled exception was thrown by the application.
Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 1: 'no such table: Measurements'.
at Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
at Microsoft.Data.Sqlite.SqliteCommand.PrepareAndEnumerateStatements(Stopwatch timer)+MoveNext()
at Microsoft.Data.Sqlite.SqliteCommand.GetStatements(Stopwatch timer)+MoveNext()
at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader()
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.InitializeReader(DbContext _, Boolean result)
at Microsoft.EntityFrameworkCore.Storage.Internal.NoopExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at MessdatenController.Controllers.MeasurementsController.GetMeasurements() in C:\Users\michu\Desktop\Wissenschaftspreis-2021\MessdatenController\MessdatenController\Controllers\MeasurementsController.cs:line 23
at lambda_method(Closure , Object , Object[] )
at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
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 where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 1312.107ms 500
Routing via Apache should work correctly, because if reaches the controller-methods.
Now regarding my files:
Program.cs remains default.
Startup.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = 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<MeasurementsContext>(options => options.UseSqlite("Data Source=measurements.db"));
services.AddTransient<IMeasurementsService, MeasurementsService>();
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
Measurement.cs
public class Measurement
{
public Measurement(PostMeasurement pm, DateTime posted)
{
this.Timestamp = pm.Timestamp;
this.PM10 = pm.PM10;
this.PM25 = pm.PM25;
this.Posted = posted;
}
public Measurement(Guid measurementId, DateTime timestamp, double pM10, double pM25, DateTime posted)
{
MeasurementId = measurementId;
Timestamp = timestamp;
PM10 = pM10;
PM25 = pM25;
Posted = posted;
}
public Guid MeasurementId { get; set; }
public DateTime Timestamp { get; set; }
public Double PM10 { get; set; }
public Double PM25 { get; set; }
public DateTime Posted { get; set; }
}
MeasurementsContext.cs:
public class MeasurementsContext : DbContext
{
public MeasurementsContext(DbContextOptions<MeasurementsContext> options) : base(options)
{ }
public DbSet<Measurement> Measurements { get; set; }
}
}
SERVICES
public interface IMeasurementsService
{
public Measurement AddMeasurement(PostMeasurement measurement, DateTime posted);
public ICollection<Measurement> AddMeasurements(IEnumerable<PostMeasurement> measurements, DateTime posted);
public IQueryable<Measurement> GetAllMeasurements();
public IQueryable<Measurement> GetMeasurementsBetweenTimestamps(DateTime start, DateTime end);
}
its Implementation
public class MeasurementsService : IMeasurementsService
{
private readonly MeasurementsContext _context;
public MeasurementsService(MeasurementsContext context)
{
_context = context;
}
public Measurement AddMeasurement(PostMeasurement measurement, DateTime posted)
{
Measurement m = new Measurement(measurement, posted);
_context.Add(m);
_context.SaveChanges();
return m;
}
public ICollection<Measurement> AddMeasurements(IEnumerable<PostMeasurement> measurements, DateTime posted)
{
List<Measurement> result = new List<Measurement>();
foreach (PostMeasurement postM in measurements)
{
Measurement tempM = new Measurement(postM, posted);
_context.Add(tempM);
result.Add(tempM);
}
_context.SaveChanges();
return result;
}
public IQueryable<Measurement> GetAllMeasurements()
{
return _context.Measurements.OrderBy(m => m.Timestamp);
}
public IQueryable<Measurement> GetMeasurementsBetweenTimestamps(DateTime start, DateTime end)
{
return _context.Measurements.Where(r => r.Timestamp > start && r.Timestamp < end).OrderBy(m => m.Timestamp);
}
}
I left out the controller as it should not be important, when taking a look at my problem.
Any advice is appreciated and feel free to ask me anything - I'll reply as fast as possible
The SQLite provider for EntityFramework will not create the database or add missing tables automatically for you. You can call dbContext.Database.EnsureCreatedAsync() to make EF create the database file if it does not exist. It will then also create all the required tables. However, if the file already exists, it will not modify it.
If you want to add additional tables to your database at a later time, you should consider using migrations which allow you to evolve your database schema over time while providing means to migrate from older versions of a database to the current schema.
If you have migrations set up, you can call dbContext.Database.EnsureMigratedAsync() to apply pending migrations to the database and make sure that the database matches the model you expect.
You can also create the database or apply migrations using the dotnet ef command line utility.

SassKit.Multitenancy not compatible with AspNetCore 2.2?

I've created a .NET Core API Controller, and in the POST method, I'm trying to use the CreatedAtActionResult method to include the route as a Location Header in my response.
[ApiController, Route("v1/[controller]")]
public class WidgetController: ControllerBase
{
public WidgetController(IWidgetService service)
{
_service = service;
}
private readonly IWidgetService _service;
[HttpGet("{id}", Name = "GetSingle")]
public IActionResult GetSingle(Guid id)
{
var result = _service.Get(id);
return Ok(result);
}
[HttpPost]
public IActionResult Post(WidgetModel model)
{
var result = _service.Post(model);
return result == Guid.Empty
? (IActionResult) BadRequest("No changes saved.")
: CreatedAtAction(nameof(GetSingle),
new {id = result},
model);
}
}
When I start the application, the first call to POST from POSTman runs without problem. Both the object and the Location Header URL get generated as expected. However, if I try to hit that endpoint a second time while the code is still running, I get the following error:
System.InvalidOperationException: No service for type 'Microsoft.AspNetCore.Routing.IEndpointAddressScheme1[Microsoft.AspNetCore.Routing.RouteValuesAddress]' has been registered.
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at Microsoft.AspNetCore.Routing.DefaultLinkGenerator.GetEndpoints[TAddress](TAddress address)
at Microsoft.AspNetCore.Routing.DefaultLinkGenerator.GetPathByAddress[TAddress](HttpContext httpContext, TAddress address, RouteValueDictionary values, RouteValueDictionary ambientValues, Nullable1 pathBase, FragmentString fragment, LinkOptions options)
at Microsoft.AspNetCore.Routing.LinkGeneratorRouteValuesAddressExtensions.GetPathByRouteValues(LinkGenerator generator, HttpContext httpContext, String routeName, Object values, Nullable1 pathBase, FragmentString fragment, LinkOptions options)
at Microsoft.AspNetCore.Mvc.Routing.EndpointRoutingUrlHelper.Action(UrlActionContext urlActionContext)
at Microsoft.AspNetCore.Mvc.UrlHelperExtensions.Action(IUrlHelper helper, String action, String controller, Object values, String protocol, String host, String fragment)
at Microsoft.AspNetCore.Mvc.UrlHelperExtensions.Action(IUrlHelper helper, String action, String controller, Object values, String protocol, String host)
at Microsoft.AspNetCore.Mvc.CreatedAtActionResult.OnFormatting(ActionContext context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsync(ActionContext context, ObjectResult result)
at Microsoft.AspNetCore.Mvc.ObjectResult.ExecuteResultAsync(ActionContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultAsync(IActionResult result)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResultFilterAsync[TFilter,TFilterAsync]()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResultExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultFilters()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
at SaasKit.Multitenancy.Internal.TenantResolutionMiddleware1.Invoke(HttpContext context, ITenantResolver`1 tenantResolver)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
I have tried swapping out the CreatedAtAction with an Ok, and that 200 result will return as many times as I click the button in POSTman.
The code inside the Post method successfully processes, and it will move onto the OnActionExecuted method of a Filter that I created. I've tried looking through all of the properties of the ActionExecutedContext object and I don't see anything out of the ordinary. Once I get out of that empty OnActionExecuted method, the call returns the 500 status code and the above stack trace inside the error page. I do have an Exception filter, but that doesn't get touched.
Has anyone had issues with this before?
For reference, here is my Startup Configuration:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMultitenancy<AppTenant, CachingAppTenantResolver>();
services.AddAutoMapper()
.AddSingleton(ConfigureAutoMapper())
.AddMvc(options =>
{
options.Filters.Add<ValidatorActionFilter>();
options.Filters.Add<ErrorHandlingFilter>();
})
.AddFluentValidation(validation => {
validation.RunDefaultMvcValidationAfterFluentValidationExecutes = false;
validation.ImplicitlyValidateChildProperties = true;
validation.RegisterValidatorsFromAssemblyContaining<WidgetModelValidator>();
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
});
services.AddEntityFrameworkSqlServer()
.AddDbContext<MyContext>();
services.Configure<MultitenancyOptions>(configuration.GetSection("Multitenancy"));
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.WithOrigins("http://localhost:4200").AllowAnyHeader().AllowAnyMethod();
});
});
ConfigureContainer(container);
return provider;
}
Try setting CompatibilityVersion.Version_2_0 or 2.1 instead of 2.2?
EndpointRouting is quite a big change under the covers of 2.2, and your 3rd party add-on might not be compatible.
Setting compatibility back to 2.1 will typically not require any code changes in your controller, so it's fairly low-cost.

Categories

Resources