【问题标题】:DBContext Not Resolving When Controller Created (.NET5, ASPCore, EF)创建控制器时 DBContext 未解析(.NET5、ASP Core、EF)
【发布时间】:2021-06-09 13:49:32
【问题描述】:

Here is the Link to the Repository With My Code

除了修复错误,我很高兴在改进我的代码方面提供任何建议,这是我第一个 .NET5 项目供我练习。我阅读了很多试图解决此错误的文档,并且大多数堆栈溢出条目是人们忘记根据下面的代码注册他们的服务,我很确定我做到了。

错误

代码运行良好,但是当我向我的 PersonController 发出请求时,我收到以下错误:

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
      System.InvalidOperationException: Unable to resolve service for type 'firstapi.Models.PersonContext' while attempting to activate 'firstapi.Controllers.PersonController'.
         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__DisplayClass4_0.<CreateActivator>b__0(ControllerContext controllerContext)
         at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_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|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 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)

我的模特

namespace firstapi.Models
{
    public class Person
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public int age { get; set; }
    }
}

我的上下文

using Microsoft.EntityFrameworkCore;

namespace firstapi.Models
{
    public class PersonContext:DbContext
    {
        public PersonContext(DbContextOptions<PersonContext> options) : base(options)
        {
        }
        public DbSet<Person> Persons { get; set; }
    }
}

我的 Startup.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using firstapi.Models;
using Microsoft.EntityFrameworkCore;

namespace firstapi
{
    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.AddControllers();
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "firstapi", Version = "v1" });

                services.AddMvc();

                // Setup our datanase connection string and add our database connection
                var connectionString = Configuration["DbContextSettings:ConnectionString"];
                Console.WriteLine(connectionString);
                services.AddDbContext<PersonContext>(opt => opt.UseNpgsql(connectionString));
            });
        }

        // 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.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "firstapi v1"));
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

我的控制器

using firstapi.Models;
using System.Collections.Generic;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Linq;

namespace firstapi.Controllers
{
   public class PersonController
    {
        private readonly PersonContext People;

        public PersonController(PersonContext people){
            People = people;
        }

        public IEnumerable<Person> index(){
            return People.Persons.ToList();
        }

        public IEnumerable<Person> Post([FromBody]Person person){
            People.Persons.Add(person);
            People.SaveChanges();
            return People.Persons.ToList();
        }

    }
}

我的 appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "DBContextSettings": {
    "ConnectionString": "User ID=test5;Password=test5;Host=localhost;Port=5432;Database=firstdotnet;Pooling=true;"
  }
}

csproj

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <GenerateRuntimeConfigurationFiles>True</GenerateRuntimeConfigurationFiles>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="EntityFramework" Version="6.4.4" />
    <PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="5.0.4" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.2" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
  </ItemGroup>

</Project>

【问题讨论】:

  • 将DbContext服务注册拉出services.AddSwaggerGen

标签: c# asp.net .net asp.net-mvc entity-framework


【解决方案1】:
  1. 删除services.AddMvc()。由于您只有一个 Web API 控制器并且您的目标是 .NET 5.0,因此services.AddControllers() 就足够了。
  2. 将配置数据库连接和 DbContext 的三行移至 services.AddSwaggerGen() 调用上方。 AddSwaggerGen 内部的代码应该只修改选项对象c

【讨论】:

  • 谢谢你,成功了,现在研究如何迁移模型,谢谢你的帮助!
猜你喜欢
  • 2020-02-18
  • 1970-01-01
  • 1970-01-01
  • 2022-01-26
  • 1970-01-01
  • 2018-05-01
  • 2018-04-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多