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,提问作者Роман Тимохов
相关产品推荐
相关产品推荐

