是否可以从aspnet核心api中的中间件向控制器发送值? [英] Is it possible to send values to controller from middleware in aspnet core api?

查看:115
本文介绍了是否可以从aspnet核心api中的中间件向控制器发送值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否可以将值从中间件发送到controllerAPI?

I want to know if is it possible to send value from middleware to controllerAPI ?

例如,我想抓住一个特定的标题并发送给控制器。

For example, I want catch one particular header and send to the controller.

类似的东西:

 public class UserTokenValidatorsMiddleware
{
    private readonly RequestDelegate _next;
    //private IContactsRepository ContactsRepo { get; set; }

    public UserTokenValidatorsMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (!context.Request.Path.Value.Contains("auth"))
        {
            if (!context.Request.Headers.Keys.Contains("user-token"))
            {
                context.Response.StatusCode = 400; //Bad Request                
                await context.Response.WriteAsync("User token is missing");
                return;
            }
            // Here I want send the header to all controller asked. 
        }

        await _next.Invoke(context);
    }
}

#region ExtensionMethod
public static class UserTokenValidatorsExtension
{
    public static IApplicationBuilder ApplyUserTokenValidation(this IApplicationBuilder app)
    {
        app.UseMiddleware<UserTokenValidatorsMiddleware>();
        return app;
    }
}
#endregion 


推荐答案

我做的是利用这些东西:

What I did was making use of these things:


  • 依赖注入(Unity)

  • ActionFilterAttribute (因为我可以访问IDependencyResolver)

  • HierarchicalLifetimeManager (所以每个请求都有一个新实例)(了解依赖范围)

  • Dependency Injection (Unity)
  • ActionFilterAttribute (because I have access to the IDependencyResolver)
  • HierarchicalLifetimeManager(so I get a new instance per request)(Read about dependency scope)

动作过滤器

    public class TokenFetcherAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            var token = actionContext.Request.Headers.Authorization.Parameter;
            var scheme = actionContext.Request.Headers.Authorization.Scheme;

            if (token == null || scheme != "Bearer")
                return;

            var tokenProvider = (TokenProvider) actionContext.Request.GetDependencyScope().GetService(typeof(TokenProvider));
            tokenProvider.SetToken(token);
        }
    }

TokenProvider

    public class TokenProvider
    {
        public string Token { get; private set; }

        public void SetToken(string token)
        {
            if(Token != null)
                throw new InvalidOperationException("Token is already set in this session.");

            Token = token;
        }
    }

Unity配置

container.RegisterType<TokenProvider>(new HierarchicalLifetimeManager()); // Gets a new TokenProvider per request

控制器

[TokenFetcher]
public class SomeController : ApiController
{
    private TokenProvider tokenProvider;

    // The token will not be set when ctor is called, but will be set before method is called.
    private string Token => tokenProvider.Token;

    public SomeController(TokenProvider provider)
    {
        tokeProvider = provider;
    }

    public string Get()
    {
         return $"Token is {Token}";
    }
}

更新

对于asp.net核心,请使用内置DI容器。
TokenProvider 注册为Transient,以便为每个请求获取一个新的:

For asp.net core use the builtin DI container. Register the TokenProvider as Transient to get a new one per request:

services.AddTransient<TokenProvider>();

这篇关于是否可以从aspnet核心api中的中间件向控制器发送值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆