ASP.Net 核心 - 尝试激活 *Controller 时无法解析 *Context 类型的服务
ASP.Net Core - Unable to resolve service for type *Context while attempting to activate *Controller
这里是新手。我觉得我已经接近理解了,但是大多数文章都围绕 Startup.cs 展开,而我没有。我被错误困住了:
InvalidOperationException: Unable to resolve service for type 'SFTP.Models.SFTPContext' while attempting to activate 'SFTP.Controllers.ClientInfsController'.
我错过了什么?
Program.cs
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
控制器 - HomeController.cs
using Microsoft.AspNetCore.Mvc;
using SFTP.Models;
using System.Diagnostics;
namespace SFTP.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
控制器 - ClienInfsContoller.cs
#nullable disable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using SFTP.Models;
namespace SFTP.Controllers
{
public class ClientInfsController : Controller
{
private readonly SFTPContext _context;
public ClientInfsController(SFTPContext context)
{
_context = context;
}
// GET: ClientInfs
public async Task<IActionResult> Index()
{
return View(await _context.ClientInfs.ToListAsync());
}
// GET: ClientInfs/Details/5
public async Task<IActionResult> Details(string id)
{
if (id == null)
{
return NotFound();
}
var clientInf = await _context.ClientInfs
.FirstOrDefaultAsync(m => m.Limiters == id);
if (clientInf == null)
{
return NotFound();
}
return View(clientInf);
}
// GET: ClientInfs/Create
public IActionResult Create()
{
return View();
}
// POST: ClientInfs/Create
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Client,Inpath,Outpath,Limiters")] ClientInf clientInf)
{
if (ModelState.IsValid)
{
_context.Add(clientInf);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(clientInf);
}
// GET: ClientInfs/Edit/5
public async Task<IActionResult> Edit(string id)
{
if (id == null)
{
return NotFound();
}
var clientInf = await _context.ClientInfs.FindAsync(id);
if (clientInf == null)
{
return NotFound();
}
return View(clientInf);
}
// POST: ClientInfs/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(string id, [Bind("Client,Inpath,Outpath,Limiters")] ClientInf clientInf)
{
if (id != clientInf.Limiters)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(clientInf);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ClientInfExists(clientInf.Limiters))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(clientInf);
}
// GET: ClientInfs/Delete/5
public async Task<IActionResult> Delete(string id)
{
if (id == null)
{
return NotFound();
}
var clientInf = await _context.ClientInfs
.FirstOrDefaultAsync(m => m.Limiters == id);
if (clientInf == null)
{
return NotFound();
}
return View(clientInf);
}
// POST: ClientInfs/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(string id)
{
var clientInf = await _context.ClientInfs.FindAsync(id);
_context.ClientInfs.Remove(clientInf);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
private bool ClientInfExists(string id)
{
return _context.ClientInfs.Any(e => e.Limiters == id);
}
}
}
型号 - SFTPContext.cs
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using SFTP.Models;
namespace SFTP.Models
{
public partial class SFTPContext : DbContext
{
public SFTPContext()
{
}
public SFTPContext(DbContextOptions<SFTPContext> options)
: base(options)
{
}
public virtual DbSet<ClientInf> ClientInfs { get; set; } = null!;
public virtual DbSet<SftpFileTrack> SftpFileTracks { get; set; } = null!;
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("Data Source=**********;Initial Catalog=SFTP;Integrated Security=True");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ClientInf>(entity =>
{
entity.HasKey(e => e.Limiters)
.HasName("PK__Client_I__7EFD3A29C824FBB5");
entity.ToTable("Client_Inf");
entity.Property(e => e.Limiters)
.HasMaxLength(255)
.IsUnicode(false)
.HasColumnName("LIMITERS");
entity.Property(e => e.Client)
.HasMaxLength(255)
.IsUnicode(false)
.HasColumnName("CLIENT");
entity.Property(e => e.Inpath)
.HasMaxLength(255)
.IsUnicode(false)
.HasColumnName("INPATH");
entity.Property(e => e.Outpath)
.HasMaxLength(255)
.IsUnicode(false)
.HasColumnName("OUTPATH");
});
modelBuilder.Entity<SftpFileTrack>(entity =>
{
entity.HasKey(e => e.Infile)
.HasName("PK__SFTP_Fil__3B2253A7C9D06D81");
entity.ToTable("SFTP_FileTrack");
entity.Property(e => e.Infile)
.HasMaxLength(255)
.IsUnicode(false)
.HasColumnName("INFILE");
entity.Property(e => e.Client)
.HasMaxLength(255)
.IsUnicode(false);
entity.Property(e => e.Infilepath)
.HasMaxLength(255)
.IsUnicode(false)
.HasColumnName("INFILEPath");
entity.Property(e => e.Intime)
.HasColumnType("datetime")
.HasColumnName("INTime");
entity.Property(e => e.IntimeConfirm)
.HasColumnType("datetime")
.HasColumnName("INTimeCONFIRM");
entity.Property(e => e.Outfile)
.HasMaxLength(255)
.IsUnicode(false)
.HasColumnName("OUTFILE");
entity.Property(e => e.Outfilepath)
.HasMaxLength(255)
.IsUnicode(false)
.HasColumnName("OUTFILEPath");
entity.Property(e => e.Outtime)
.HasColumnType("datetime")
.HasColumnName("OUTTime");
entity.Property(e => e.Status)
.HasMaxLength(50)
.IsUnicode(false)
.HasColumnName("STATUS");
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}
型号 - ClientInf.cs
using System;
using System.Collections.Generic;
namespace SFTP.Models
{
public partial class ClientInf
{
public string? Client { get; set; }
public string? Inpath { get; set; }
public string? Outpath { get; set; }
public string Limiters { get; set; } = null!;
}
}
看起来你错过了注入 SFTPContext
,这是 DbContext
到 DI 容器。
Program.cs
builder.Services.AddDbContext<SFTPContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString(/* ConectionString key from appsettings.json */)));
参考
Dependency injection (services) - ASP.NET Core fundamentals | Microsoft Docs
这里是新手。我觉得我已经接近理解了,但是大多数文章都围绕 Startup.cs 展开,而我没有。我被错误困住了:
InvalidOperationException: Unable to resolve service for type 'SFTP.Models.SFTPContext' while attempting to activate 'SFTP.Controllers.ClientInfsController'.
我错过了什么?
Program.cs
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
控制器 - HomeController.cs
using Microsoft.AspNetCore.Mvc;
using SFTP.Models;
using System.Diagnostics;
namespace SFTP.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
控制器 - ClienInfsContoller.cs
#nullable disable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using SFTP.Models;
namespace SFTP.Controllers
{
public class ClientInfsController : Controller
{
private readonly SFTPContext _context;
public ClientInfsController(SFTPContext context)
{
_context = context;
}
// GET: ClientInfs
public async Task<IActionResult> Index()
{
return View(await _context.ClientInfs.ToListAsync());
}
// GET: ClientInfs/Details/5
public async Task<IActionResult> Details(string id)
{
if (id == null)
{
return NotFound();
}
var clientInf = await _context.ClientInfs
.FirstOrDefaultAsync(m => m.Limiters == id);
if (clientInf == null)
{
return NotFound();
}
return View(clientInf);
}
// GET: ClientInfs/Create
public IActionResult Create()
{
return View();
}
// POST: ClientInfs/Create
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Client,Inpath,Outpath,Limiters")] ClientInf clientInf)
{
if (ModelState.IsValid)
{
_context.Add(clientInf);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(clientInf);
}
// GET: ClientInfs/Edit/5
public async Task<IActionResult> Edit(string id)
{
if (id == null)
{
return NotFound();
}
var clientInf = await _context.ClientInfs.FindAsync(id);
if (clientInf == null)
{
return NotFound();
}
return View(clientInf);
}
// POST: ClientInfs/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(string id, [Bind("Client,Inpath,Outpath,Limiters")] ClientInf clientInf)
{
if (id != clientInf.Limiters)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(clientInf);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ClientInfExists(clientInf.Limiters))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(clientInf);
}
// GET: ClientInfs/Delete/5
public async Task<IActionResult> Delete(string id)
{
if (id == null)
{
return NotFound();
}
var clientInf = await _context.ClientInfs
.FirstOrDefaultAsync(m => m.Limiters == id);
if (clientInf == null)
{
return NotFound();
}
return View(clientInf);
}
// POST: ClientInfs/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(string id)
{
var clientInf = await _context.ClientInfs.FindAsync(id);
_context.ClientInfs.Remove(clientInf);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
private bool ClientInfExists(string id)
{
return _context.ClientInfs.Any(e => e.Limiters == id);
}
}
}
型号 - SFTPContext.cs
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using SFTP.Models;
namespace SFTP.Models
{
public partial class SFTPContext : DbContext
{
public SFTPContext()
{
}
public SFTPContext(DbContextOptions<SFTPContext> options)
: base(options)
{
}
public virtual DbSet<ClientInf> ClientInfs { get; set; } = null!;
public virtual DbSet<SftpFileTrack> SftpFileTracks { get; set; } = null!;
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("Data Source=**********;Initial Catalog=SFTP;Integrated Security=True");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ClientInf>(entity =>
{
entity.HasKey(e => e.Limiters)
.HasName("PK__Client_I__7EFD3A29C824FBB5");
entity.ToTable("Client_Inf");
entity.Property(e => e.Limiters)
.HasMaxLength(255)
.IsUnicode(false)
.HasColumnName("LIMITERS");
entity.Property(e => e.Client)
.HasMaxLength(255)
.IsUnicode(false)
.HasColumnName("CLIENT");
entity.Property(e => e.Inpath)
.HasMaxLength(255)
.IsUnicode(false)
.HasColumnName("INPATH");
entity.Property(e => e.Outpath)
.HasMaxLength(255)
.IsUnicode(false)
.HasColumnName("OUTPATH");
});
modelBuilder.Entity<SftpFileTrack>(entity =>
{
entity.HasKey(e => e.Infile)
.HasName("PK__SFTP_Fil__3B2253A7C9D06D81");
entity.ToTable("SFTP_FileTrack");
entity.Property(e => e.Infile)
.HasMaxLength(255)
.IsUnicode(false)
.HasColumnName("INFILE");
entity.Property(e => e.Client)
.HasMaxLength(255)
.IsUnicode(false);
entity.Property(e => e.Infilepath)
.HasMaxLength(255)
.IsUnicode(false)
.HasColumnName("INFILEPath");
entity.Property(e => e.Intime)
.HasColumnType("datetime")
.HasColumnName("INTime");
entity.Property(e => e.IntimeConfirm)
.HasColumnType("datetime")
.HasColumnName("INTimeCONFIRM");
entity.Property(e => e.Outfile)
.HasMaxLength(255)
.IsUnicode(false)
.HasColumnName("OUTFILE");
entity.Property(e => e.Outfilepath)
.HasMaxLength(255)
.IsUnicode(false)
.HasColumnName("OUTFILEPath");
entity.Property(e => e.Outtime)
.HasColumnType("datetime")
.HasColumnName("OUTTime");
entity.Property(e => e.Status)
.HasMaxLength(50)
.IsUnicode(false)
.HasColumnName("STATUS");
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}
型号 - ClientInf.cs
using System;
using System.Collections.Generic;
namespace SFTP.Models
{
public partial class ClientInf
{
public string? Client { get; set; }
public string? Inpath { get; set; }
public string? Outpath { get; set; }
public string Limiters { get; set; } = null!;
}
}
看起来你错过了注入 SFTPContext
,这是 DbContext
到 DI 容器。
Program.cs
builder.Services.AddDbContext<SFTPContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString(/* ConectionString key from appsettings.json */)));
参考
Dependency injection (services) - ASP.NET Core fundamentals | Microsoft Docs