You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core MVC控制器中如何使用ApplicationDBContext?

问题解答:ASP.NET Core控制器中通过依赖注入访问DbContext的问题

首先直接给你结论:完全可以通过依赖注入使用全局配置的DbContext,不需要每次请求手动新建,Startup里的配置会被DI容器自动复用。你遇到的ObjectDisposedException错误,根源不在依赖注入的方式,而是你控制器Action的异步写法有问题。

错误原因分析

看你的代码,控制器里的Index和AMethod都用了async void作为返回类型:

public async void Index() { ... }
public async void AMethod(string parameter) { ... }

在ASP.NET Core中,async void是异步编程的大忌——这种方法不会返回Task,ASP.NET的请求管道无法跟踪它的执行进度。当请求进来时,控制器构造函数注入的MyContext是Scoped生命周期(默认每个请求一个实例),但如果Action是async void,ASP.NET会在方法开始执行后就认为请求已经完成,提前释放掉MyContext实例。等你后续执行await _userManager.GetUserAsync(User)或者await _context.SaveChangesAsync()时,上下文已经被释放,自然就抛出了Cannot access a disposed object的错误。

解决方案

把所有异步Action的返回类型从async void改成async Task(如果需要返回视图/结果,就用async Task<IActionResult>),这样ASP.NET会正确等待异步操作完成后再结束请求、释放上下文。

另外,你的AMethod里还有个小问题:_context.MyEntity.AddAsync(parameter)的参数应该是你的实体类实例,而不是string,这里大概率是笔误,需要修正。

修正后的代码示例:

[Route("[controller]/[action]")]
public class MyController : Controller
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly ILogger _logger;
    private readonly UrlEncoder _urlEncoder;
    private readonly MyContext _context;

    public MyController(
        UserManager<ApplicationUser> userManager,
        ILogger<ManageController> logger,
        UrlEncoder urlEncoder,
        MyContext context)
    {
        _userManager = userManager;
        _logger = logger;
        _urlEncoder = urlEncoder;
        _context = context;
    }

    [HttpGet]
    public async Task<IActionResult> Index()
    {
        var user = await _userManager.GetUserAsync(User);
        if (user == null)
        {
            throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
        }
        // 这里可以返回视图,比如 return View(user);
        return Ok(user);
    }

    [HttpPost]
    public async Task<IActionResult> AMethod(string parameter)
    {
        // 假设你的实体类是MyEntity,这里创建实例并赋值
        var newEntity = new MyEntity { SomeProperty = parameter };
        await _context.MyEntity.AddAsync(newEntity);
        await _context.SaveChangesAsync();
        return Ok("保存成功");
    }
}

额外说明

  1. DbContext的生命周期:ASP.NET Core默认把DbContext注册为Scoped服务,也就是每个HTTP请求会创建一个实例,请求结束后由DI容器自动释放。你不需要手动调用Dispose(),也不要用using包裹注入的上下文实例,否则会导致提前释放。
  2. 依赖注入的正确性:你在控制器构造函数中注入MyContext的方式是完全正确的,DI容器会自动使用你在Startup.cs(或者Program.cs,.NET 6+)中配置的数据库连接字符串等参数,不需要重复配置。

内容的提问来源于stack exchange,提问作者Anes Belfodil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:53:30