C# .Net核心中间件System.ObjectDisposedException:无法访问已处置的上下文实例

C# .Net核心中间件System.ObjectDisposedException:无法访问已处置的上下文实例,c#,.net,asp.net-core,asp.net-core-5.0,C#,.net,Asp.net Core,Asp.net Core 5.0,这是我的密码 我可能知道为什么,但我不知道怎么做 我知道将dbcontext设置为singleton可以解决这个问题,但似乎有很多副作用 我不想那样。还有别的办法吗 下面是来自中间件的一些代码 中间件如下所示: public class JwtMiddleware { private readonly RequestDelegate _next; private readonly AppSettings _appSettings; public JwtMiddlewa

这是我的密码

我可能知道为什么,但我不知道怎么做

我知道将dbcontext设置为singleton可以解决这个问题,但似乎有很多副作用

我不想那样。还有别的办法吗

下面是来自中间件的一些代码

中间件如下所示:

 public class JwtMiddleware
{
    private readonly RequestDelegate _next;
    private readonly AppSettings _appSettings;

    public JwtMiddleware(RequestDelegate next, IOptions<AppSettings> appSettings)
    {
        _next = next;
        _appSettings = appSettings.Value;
    }

    public async Task Invoke(HttpContext context, IUserService userService)
    {
        var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();

        if (token != null)
            attachUserToContext(context, userService, token);

        await _next(context);
    }

    private void attachUserToContext(HttpContext context, IUserService userService, string token)
    {
        try
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes(_appSettings.SecretKey);
            tokenHandler.ValidateToken(token, new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(key),
                ValidateIssuer = false,
                ValidateAudience = false,
                // 将ClockSkew设置为零,以便令牌正好在令牌过期时过期(而不是5分钟后)
                ClockSkew = TimeSpan.Zero
            }, out SecurityToken validatedToken);

            var jwtToken = (JwtSecurityToken)validatedToken;
            var userId = jwtToken.Claims.First(x => x.Type == "id").Value;

            // 在jwt验证成功时将用户附加到上下文
            context.Items["User"] = userService.GetByIdAsync(userId);
        }
        catch
        {
            // do nothing if jwt validation fails
            // user is not attached to context so request won't have access to secure routes
        }
    }
}
 public interface IUserService
{
    Task<AuthenticateResponse> Authenticate(LoginDto model);
    Task<IdentityUser> GetByIdAsync(string userId);
}

public class UserService : IUserService
{
    private readonly UserManager<IdentityUser> _userManager;
    public AppSettings _JwtSettings { get; }

    public UserService(UserManager<IdentityUser> userManager, IOptions<AppSettings> jwtSettings)
    {
        this._userManager = userManager;
        this._JwtSettings = jwtSettings.Value;
    }

    /// <summary>
    /// 进行身份验证
    /// </summary>
    /// <param name="model">LoginDto模型</param>
    /// <returns>AuthenticateResponse</returns>
    public async Task<AuthenticateResponse> Authenticate(LoginDto model)
    {
        var user = await _userManager.FindByNameAsync(model.UserName);

        // 没用用户或密码错误返回null
        if (user == null && !await _userManager.CheckPasswordAsync(user, model.Password)) return null;

        // 验证成功 生成jwt令牌
        var token = generateJwtToken(user);

        return new AuthenticateResponse(user, token);
    }

    //获取Jwt Token
    private string generateJwtToken(IdentityUser user)
    {
        var tokenHandler = new JwtSecurityTokenHandler();
        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(new[] {
                new Claim(JwtClaimTypes.Audience, _JwtSettings.Audience),
                new Claim(JwtClaimTypes.Issuer, _JwtSettings.Issuer),
                new Claim(JwtClaimTypes.Name, user.UserName),
                new Claim(JwtClaimTypes.Id, user.Id.ToString()),
            }),
            Expires = DateTime.UtcNow.AddDays(1),
            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_JwtSettings.SecretKey)), SecurityAlgorithms.HmacSha256Signature)
        };
        var token = tokenHandler.CreateToken(tokenDescriptor);
        return tokenHandler.WriteToken(token);
    }

    public async Task<IdentityUser> GetByIdAsync(string id)
    {
        var user = await _userManager.FindByIdAsync(id);
        return user;
    }
}
公共类JWT中间件
{
private readonly RequestDelegate\u next;
私有只读应用设置\u应用设置;

公共JwtMiddleware(RequestDelegate下一步,IOOptions

您应该将
void AttachUserContext
更改为
async Task AttachUserContext
,然后将
userService.GetByIdAsync(userId)
更改为
Wait userService.GetByIdAsync(userId)
然后再
等待attachUserToContext
Invoke
@devNull您应该写的是作为答案:)