InvalidOperationException:尝试激活 'OESAC.Pages.Courses.IndexModel' 时无法解析类型 'OESAC.Data.MyDbContext' 的服务
InvalidOperationException: Unable to resolve service for type 'OESAC.Data.MyDbContext' while attempting to activate 'OESAC.Pages.Courses.IndexModel'
我在 Whosebug 和全世界搜索了解决方案。很确定如果它是一条蛇它会咬我。
Razor Pages Web 应用程序,VS 2017,运行并显示主页。我想显示一个 Pages/Courses/Index.chstml 页面连接到课程 table。当我单击课程 link 时,一切都崩溃了。
这是我的 "MyDbContext" class:
using Microsoft.EntityFrameworkCore;
namespace OESAC.Data
{
public class MyDbContext : DbContext
{
public DbSet<Courses> Courses { get; set; }
public DbSet<Sponsors> Sponsors{ get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite(@"Data source=oesac_new.db");
}
}
}
这是触发错误的索引文件。它位于 Pages.Courses 文件夹中:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using OESAC.Data;
namespace OESAC.Pages.Courses
{
public class IndexModel : PageModel
{
private readonly OESAC.Data.MyDbContext _context;
public IndexModel(OESAC.Data.MyDbContext context)
{
_context = context;
}
public List<OESAC.Data.Courses> Courses { get;set; }
public async Task OnGetAsync()
{
Courses = await _context.Courses.ToListAsync();
}
}
}
这是错误:
System.InvalidOperationException: Unable to resolve service for type 'OESAC.Data.MyDbContext' while attempting to activate 'OESAC.Pages.Courses.IndexModel'.
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method(Closure , IServiceProvider , Object[] )
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.DefaultPageModelActivatorProvider.<>c__DisplayClass1_0.<CreateActivator>b__0(PageContext context)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.DefaultPageModelFactoryProvider.<>c__DisplayClass3_0.<CreateModelFactory>b__0(PageContext pageContext)
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.CreateInstance()
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.InvokeInnerFilterAsync()
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 Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
好的,我开始拼凑错误并得到了一些帮助。
我发现提到了这个,并将其添加到我的 Startup.cs ConfigureServices
.NET Core 中的一切都是围绕依赖注入构建的,而不是使用诸如 ConfigurationManager 之类的静态实例。
您可以通过几种不同的方式来做到这一点。
首先是在 Startup.cs ConfigureServices 中注册您的 DbContext,方法如下:
services.AddDbContext<MyDbContext>(options => options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
以上内容的问答位置如下:
How to pass connection string from appsettings.[name].json to DbContext in .NET Core?
============================================= ======
我必须添加的第二项是我在另一个线程中找到的(我更改了上下文名称以反映我的 MyDbContext):
如错误所述,如果您通过 AddDbContext 配置 MyDbContext,那么您还需要添加一个构造函数,该构造函数将 DbContextOptions 类型的参数接收到您的 MyDbContext class 中,如下所示
public MyDbContext(DbContextOptions<MyDbContext> options)
: base(options)
{ }
如果您不这样做,ASP.Net Core 将无法注入您使用 AddDbContext 设置的配置。(请记住第一个 URL 我发现说 "Everything in .NET Core is built around dependency injection instead of using static instances")。自我提醒:了解什么是依赖注入 LOL
去图吧。你会认为脚手架会完成这一切。真让人头疼。
我在 Whosebug 上再次发现:
我在 Whosebug 和全世界搜索了解决方案。很确定如果它是一条蛇它会咬我。 Razor Pages Web 应用程序,VS 2017,运行并显示主页。我想显示一个 Pages/Courses/Index.chstml 页面连接到课程 table。当我单击课程 link 时,一切都崩溃了。
这是我的 "MyDbContext" class:
using Microsoft.EntityFrameworkCore;
namespace OESAC.Data
{
public class MyDbContext : DbContext
{
public DbSet<Courses> Courses { get; set; }
public DbSet<Sponsors> Sponsors{ get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite(@"Data source=oesac_new.db");
}
}
}
这是触发错误的索引文件。它位于 Pages.Courses 文件夹中:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using OESAC.Data;
namespace OESAC.Pages.Courses
{
public class IndexModel : PageModel
{
private readonly OESAC.Data.MyDbContext _context;
public IndexModel(OESAC.Data.MyDbContext context)
{
_context = context;
}
public List<OESAC.Data.Courses> Courses { get;set; }
public async Task OnGetAsync()
{
Courses = await _context.Courses.ToListAsync();
}
}
}
这是错误:
System.InvalidOperationException: Unable to resolve service for type 'OESAC.Data.MyDbContext' while attempting to activate 'OESAC.Pages.Courses.IndexModel'.
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method(Closure , IServiceProvider , Object[] )
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.DefaultPageModelActivatorProvider.<>c__DisplayClass1_0.<CreateActivator>b__0(PageContext context)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.DefaultPageModelFactoryProvider.<>c__DisplayClass3_0.<CreateModelFactory>b__0(PageContext pageContext)
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.CreateInstance()
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.InvokeInnerFilterAsync()
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 Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
好的,我开始拼凑错误并得到了一些帮助。
我发现提到了这个,并将其添加到我的 Startup.cs ConfigureServices
.NET Core 中的一切都是围绕依赖注入构建的,而不是使用诸如 ConfigurationManager 之类的静态实例。 您可以通过几种不同的方式来做到这一点。 首先是在 Startup.cs ConfigureServices 中注册您的 DbContext,方法如下:
services.AddDbContext<MyDbContext>(options => options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
以上内容的问答位置如下: How to pass connection string from appsettings.[name].json to DbContext in .NET Core?
============================================= ======
我必须添加的第二项是我在另一个线程中找到的(我更改了上下文名称以反映我的 MyDbContext):
如错误所述,如果您通过 AddDbContext 配置 MyDbContext,那么您还需要添加一个构造函数,该构造函数将 DbContextOptions 类型的参数接收到您的 MyDbContext class 中,如下所示
public MyDbContext(DbContextOptions<MyDbContext> options)
: base(options)
{ }
如果您不这样做,ASP.Net Core 将无法注入您使用 AddDbContext 设置的配置。(请记住第一个 URL 我发现说 "Everything in .NET Core is built around dependency injection instead of using static instances")。自我提醒:了解什么是依赖注入 LOL
去图吧。你会认为脚手架会完成这一切。真让人头疼。
我在 Whosebug 上再次发现: