首页 > 解决方案 > ASP.NET Core Web API:尝试激活时无法解析服务类型

问题描述

这是我第一次尝试 .NET API 并使用 .NET 核心。我曾经能够使用 ADO.NET 将数据库连接到项目,但显然不再支持,所以我使用 EF Core 使用这些包:microsoft.entityframeworkcore\5.0.8、microsoft.entityframeworkcore.sqlserver\5.0。 6,和 microsoft.entityframeworkcore.tools\5.0.6。

然后我为数据库中的两个表生成了模型和数据库上下文,这似乎工作正常。但是,当我尝试访问 localhost/api/Statewides 时,我收到此错误:

System.InvalidOperationException: Unable to resolve service for type 'TestAPI.Models.RoadWay_HistoryContext' while attempting to activate 'TestAPI.Controllers.StatewidesController'.
   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__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__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 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: text/plain
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: close
Host: localhost:44324
Referer: https://localhost:44324/swagger/index.html
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
sec-ch-ua-mobile: ?0
sec-fetch-site: same-origin
sec-fetch-mode: cors
sec-fetch-dest: empty

我真的不知道这意味着什么……我将提供数据库上下文和模型以及控制器和启动文件。如果您需要其他任何东西来回答这个问题,我会很乐意提供。

全州控制器

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 TestAPI.Models;

namespace TestAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class StatewidesController : ControllerBase
    {
        private readonly RoadWay_HistoryContext _context;

        public StatewidesController(RoadWay_HistoryContext context)
        {
            _context = context;
        }

        // GET: api/Statewides
        [HttpGet]
        public async Task<ActionResult<IEnumerable<Statewide>>> GetStatewides()
        {
            return await _context.Statewides.ToListAsync();
        }

        // GET: api/Statewides/5
        [HttpGet("{id}")]
        public async Task<ActionResult<Statewide>> GetStatewide(long id)
        {
            var statewide = await _context.Statewides.FindAsync(id);

            if (statewide == null)
            {
                return NotFound();
            }

            return statewide;
        }

        // PUT: api/Statewides/5
        // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
        [HttpPut("{id}")]
        public async Task<IActionResult> PutStatewide(long id, Statewide statewide)
        {
            if (id != statewide.Id)
            {
                return BadRequest();
            }

            _context.Entry(statewide).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!StatewideExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return NoContent();
        }

        // POST: api/Statewides
        // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
        [HttpPost]
        public async Task<ActionResult<Statewide>> PostStatewide(Statewide statewide)
        {
            _context.Statewides.Add(statewide);
            await _context.SaveChangesAsync();

            return CreatedAtAction("GetStatewide", new { id = statewide.Id }, statewide);
        }

        // DELETE: api/Statewides/5
        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteStatewide(long id)
        {
            var statewide = await _context.Statewides.FindAsync(id);
            if (statewide == null)
            {
                return NotFound();
            }

            _context.Statewides.Remove(statewide);
            await _context.SaveChangesAsync();

            return NoContent();
        }

        private bool StatewideExists(long id)
        {
            return _context.Statewides.Any(e => e.Id == id);
        }
    }
}

全州.cs

using System;
using System.Collections.Generic;

#nullable disable

namespace TestAPI.Models
{
    public partial class Statewide
    {
        public Statewide()
        {
            DocumentsNavigation = new HashSet<Document>();
        }

        public long Id { get; set; }
        public string County { get; set; }
        public string SignSys { get; set; }
        public string RouteNoOrigImport { get; set; }
        public int? RouteNo { get; set; }
        public int? SuppDes { get; set; }
        public string LocalName { get; set; }
        public DateTime? DateNumber { get; set; }
        public string Method { get; set; }
        public string OriginalL { get; set; }
        public string OriginalD { get; set; }
        public string Projects { get; set; }
        public string Documents { get; set; }
        public string Comments { get; set; }
        public int? District { get; set; }
        public bool DuplicateOk { get; set; }
        public string RightofWay { get; set; }
        public bool ReservedRoute { get; set; }
        public string ReservedBy { get; set; }
        public DateTime? ReservedDate { get; set; }
        public bool CpWorkCompleted { get; set; }
        public string WorkComments { get; set; }
        public string CpProjectNo { get; set; }
        public int? ReservedCat { get; set; }
        public string AddUser { get; set; }
        public DateTime? DateAdded { get; set; }

        public virtual ICollection<Document> DocumentsNavigation { get; set; }
    }
}

数据库上下文

using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;

#nullable disable

namespace TestAPI.Models
{
    public partial class RoadWay_HistoryContext : DbContext
    {
        public RoadWay_HistoryContext()
        {
        }

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

        public virtual DbSet<Document> Documents { get; set; }
        public virtual DbSet<Statewide> Statewides { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
                optionsBuilder.UseSqlServer("Server=dotb6gisdbst01;Database=RoadWay_History;Trusted_Connection=True;");
            }
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.HasAnnotation("Relational:Collation", "SQL_Latin1_General_CP1_CI_AS");

            modelBuilder.Entity<Document>(entity =>
            {
                entity.Property(e => e.Id).HasColumnName("ID");

                entity.Property(e => e.AddUser)
                    .HasMaxLength(25)
                    .HasColumnName("Add_User");

                entity.Property(e => e.DateAdded)
                    .HasColumnType("date")
                    .HasColumnName("Date_Added");

                entity.Property(e => e.DocLocation)
                    .HasMaxLength(255)
                    .HasColumnName("Doc_Location");

                entity.Property(e => e.DocType)
                    .HasMaxLength(255)
                    .HasColumnName("Doc_Type");

                entity.Property(e => e.FileContents)
                    .HasMaxLength(255)
                    .HasColumnName("File_Contents");

                entity.Property(e => e.OrderDate)
                    .HasColumnType("date")
                    .HasColumnName("Order_Date");

                entity.Property(e => e.StatewideId).HasColumnName("Statewide_ID");

                entity.HasOne(d => d.Statewide)
                    .WithMany(p => p.DocumentsNavigation)
                    .HasForeignKey(d => d.StatewideId)
                    .HasConstraintName("FK_Documents_Statewide");
            });

            modelBuilder.Entity<Statewide>(entity =>
            {
                entity.ToTable("Statewide");

                entity.Property(e => e.Id).HasColumnName("ID");

                entity.Property(e => e.AddUser)
                    .HasMaxLength(25)
                    .HasColumnName("Add_User");

                entity.Property(e => e.County)
                    .HasMaxLength(255)
                    .HasColumnName("COUNTY");

                entity.Property(e => e.CpProjectNo)
                    .HasMaxLength(255)
                    .HasColumnName("CP_ProjectNo");

                entity.Property(e => e.CpWorkCompleted).HasColumnName("CP_WorkCompleted");

                entity.Property(e => e.DateAdded)
                    .HasColumnType("date")
                    .HasColumnName("Date_Added");

                entity.Property(e => e.DateNumber).HasColumnType("date");

                entity.Property(e => e.DuplicateOk).HasColumnName("Duplicate OK");

                entity.Property(e => e.LocalName).HasMaxLength(255);

                entity.Property(e => e.Method).HasMaxLength(255);

                entity.Property(e => e.OriginalD).HasMaxLength(255);

                entity.Property(e => e.OriginalL).HasMaxLength(255);

                entity.Property(e => e.ReservedDate).HasColumnType("date");

                entity.Property(e => e.RightofWay).HasMaxLength(255);

                entity.Property(e => e.RouteNoOrigImport).HasMaxLength(255);

                entity.Property(e => e.SignSys).HasMaxLength(255);

                entity.Property(e => e.WorkComments)
                    .HasMaxLength(255)
                    .HasColumnName("Work_Comments");
            });

            OnModelCreatingPartial(modelBuilder);
        }

        partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
    }
}

启动.cs

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 System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace TestAPI
{
    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 = "TestAPI", Version = "v1" });
            });
        }

        // 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", "TestAPI v1"));
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

标签: c#entity-frameworkasp.net-coreasp.net-core-webapi

解决方案


您收到此错误是因为您尚未注册RoadWay_HistoryContext到服务容器。通过依赖注入使用的所有服务都必须注册。这就是当您尝试使用它们时类能够解析服务的方式。这是通过将此行添加到方法中来修复它的ConfigureServices方法。

services.AddDbContext<RoadWay_HistoryContext>(opts => opts.UseSqlServer(Configuration.GetConnectionString("ConnectionName")));

更新

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "ConnectionStrings": {
    "ConnectionName": "Server=ServerOfDatabase;Database=DatabaseName;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

推荐阅读