C# .Net核心中间件System.ObjectDisposedException:无法访问已处置的上下文实例
这是我的密码 我可能知道为什么,但我不知道怎么做 我知道将dbcontext设置为singleton可以解决这个问题,但似乎有很多副作用 我不想那样。还有别的办法吗 下面是来自中间件的一些代码 中间件如下所示: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
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您应该写的是作为答案:)