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

ASP.NET Identity创建Telegram用户时遇System.ObjectDisposedException的解决

解决ASP.NET Identity创建Telegram用户时的ObjectDisposedException错误

问题根源

你遇到的System.ObjectDisposedException错误,核心原因是你的UpdatesController.Post方法使用了async void。在ASP.NET Core中,控制器动作方法如果用async void,框架无法跟踪异步操作的完成状态——当方法执行到第一个await时,请求上下文会被标记为已完成,对应的Scoped依赖(比如你的AppIdentityContext)会被DI容器提前释放。而后续_userManager.CreateAsync(appUser)还在尝试使用这个已被释放的DbContext,自然就抛出了异常。

另外还有一个小问题:你的TryRegisterUserAsync方法返回值是bool,但你直接返回了IdentityResult类型的createResult,这会导致编译错误,需要改成返回createResult.Succeeded。

解决方案

1. 修正控制器的异步方法签名

把UpdatesController.Post的async void改成async Task,让框架能正确管理异步生命周期:

[Route("bot/[controller]")]
[ApiController]
public class UpdatesController : ControllerBase {
    private readonly IBot _bot;
    private readonly IUpdatesRouter _updateRoute;
    public UpdatesController(IBot bot, IUpdatesRouter updateRoute) {
        _bot = bot;
        _updateRoute = updateRoute;
    }
    [HttpPost]
    // 这里从async void改为async Task
    public async Task Post([FromBody] Update update) {
        if (_updateRoute.IsText(update)) {
            await _bot.HandleTextCommandAsync(update.Message);
        }
    }
}

2. 修正用户注册方法的返回值逻辑

修改Account.TryRegisterUserAsync,返回IdentityResult.Succeeded来正确表示注册是否成功:

public class Account : IAccount {
    private readonly UserManager<AppUser> _userManager;
    public Account(UserManager<AppUser> userManager) => _userManager = userManager;
    public async Task<bool> TryRegisterUserAsync(User user) {
        var appUser = new AppUser {
            IsBot = user.IsBot,
            TelegramId = user.Id,
            // 额外优化:如果Telegram用户没有Username,用TelegramId作为默认值
            UserName = !string.IsNullOrEmpty(user.Username) ? user.Username : user.Id.ToString(),
            TelegramFirstName = user.FirstName,
            TelegramLangCode = user.LanguageCode
        };
        var createResult = await _userManager.CreateAsync(appUser);
        // 返回操作是否成功
        return createResult.Succeeded;
    }
}

额外注意事项

  • Identity的UserName必填:默认情况下,ASP.NET Identity要求UserName不能为空。如果Telegram用户没有设置Username,直接赋值user.Username会导致注册失败,所以上面的代码里加了一个兜底逻辑,用TelegramId作为默认的UserName。
  • Scoped依赖的生命周期:AppIdentityContext是Scoped生命周期,它的生命周期和请求绑定。只要控制器动作方法正确使用async Task,DI容器就会在整个异步操作完成后才释放上下文,避免资源被提前回收。

内容的提问来源于stack exchange,提问作者Роман Тимохов

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:13:29