在 ASP.custom 中间件中初始化对象并注入它们

Sir*_*irG 1 asp.net-web-api .net-core asp.net-core

我有一个 ASP.NET Core Web API,它读取请求标头中的身份验证令牌并解码其中的值。

我已经编写了自定义中间件来解码令牌。我还创建了一个 UserContext 对象来保存从令牌解码的值,并将解码的值设置到 UserContext 对象中。

我现在希望能够将 UserContext 对象(在自定义中间件中创建)注入我的控制器,但我无法弄清楚如何做到这一点。

请帮忙。

Uma*_*adi 5

您可以使用 HttpContext.Items

在您的中间件,您将有机会获得HttpContext着,当然

您可以将您的用户上下文存储在项目字典中,该字典是瞬态的,范围为一个 http 请求的生命周期。下面是一个示例中间件,其中“上下文”是Http上下文对象。您将在中间件中拥有此对象。

app.Use(async (context, next) =>
{
 context.Items.Add("UserContext", new UserContext());
 await next.Invoke();
});
Run Code Online (Sandbox Code Playgroud)

然后,您可以HttpContext通过注入IHttpContextAccessor对象来访问控制器中的。

 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();
    }
  }
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

创建一个UserContextServiceHttpContext. 制作UserContextService一个单例,但是当您获得用户时,总是返回一个 new UserContext,这是因为您当然处于多线程环境中并且您永远不想持久化此对象,因为您最终可能会读取其他人的UserContext,所以总是返回 new 。在启动类的 ConfigureServices 方法中注册此服务。

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IUserContextService, UserContextService>();
    services.AddSingleton<IRepositry, Repositry>(serviceCollection => new Repositry(serviceCollection.GetService<IUserContextService>()));

}
Run Code Online (Sandbox Code Playgroud)

然后,您可以将您的存储库注入您的 API 控制器,例如

public class ApiController : Controller
{
    public readonly IRepositry _repositry;
    public ApiController(IRepositrycontext repositry)
    {
        _repositry= repositry;
    }

    public IActionResult Get()
    {
        // Get the http context

        return Ok();
    }
 } 
Run Code Online (Sandbox Code Playgroud)