您可以使用HttpContext.Items
在您的中间件中,您当然可以访问HttpContext
您可以将您的用户上下文存储在项目字典中,该字典是瞬态的,并且范围仅限于一个 http 请求的生命周期。下面是一个示例中间件,其中 'context' 是 Http 上下文对象。您将在中间件中拥有此对象。
app.Use(async (context, next) =>
{
context.Items.Add("UserContext", new UserContext());
await next.Invoke();
});
然后,您可以通过注入 IHttpContextAccessor 对象来访问控制器中的 HttpContext。
public class ApiController : Controller
{
public readonly IHttpContextAccessor _context;
public ApiController(IHttpContextAccessor context)
{
_context = context;
}
public IActionResult Get()
{
// Get the http context
UserContext userContext = (UserContext) _context.HttpContext.Items["UserContext"];
return Ok();
}
}
从IHttpContextAccessor,你可以得到HttpContext对象,你可以从中得到Items字典。
当然,做一些检查以查看密钥“UserContext”是否存在,但我认为这对你有用
编辑
因为您希望将其传递给其他存储库/服务。
而不是将HttpContextAccessor 传递给所有人,您可以这样做。创建一个服务,封装UserContext 对象的创建。
它可能看起来像这样。
public interface IRepositry { }
public class Repositry : IRepositry
{
private IUserContextService _userContextService;
public Repositry(IUserContextService userContextService)
{
_userContextService = userContextService;
}
}
public class UserContext
{
}
public interface IUserContextService
{
UserContext GetUser();
}
public class UserContextService : IUserContextService
{
private readonly IHttpContextAccessor _context;
public UserContextService(IHttpContextAccessor context)
{
_context = context;
}
public UserContext GetUser()
{
var token = _context.HttpContext.Request.Headers["UserToken"];
// do something with the token to create the UserContext;
return new UserContext();
}
}
创建一个从HttpContext 读取的UserContextService。将UserContextService 设为单例,但是当您获取用户时,始终返回一个新的UserContext,这是因为您当然处于多线程环境中,并且您永远不想保留此对象,因为您最终可能会阅读其他人的UserContext,所以总是返回新的。在启动类的 ConfigureServices 方法中注册此服务。
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IUserContextService, UserContextService>();
services.AddSingleton<IRepositry, Repositry>(serviceCollection => new Repositry(serviceCollection.GetService<IUserContextService>()));
}
然后您可以将您的存储库注入到您的 API 控制器中,例如
public class ApiController : Controller
{
public readonly IRepositry _repositry;
public ApiController(IRepositrycontext repositry)
{
_repositry= repositry;
}
public IActionResult Get()
{
// Get the http context
return Ok();
}
}