.net - 是否可以从 aspnet core api 中的中间件向 Controller 发送值?

标签 .net asp.net-web-api http-headers asp.net-core middleware

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

例如,我想捕获一个特定的 header 并发送到 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 

最佳答案

我所做的就是利用这些东西:

  • 依赖注入(inject)(Unity)
  • ActionFilterAttribute(因为我可以访问 IDependencyResolver)
  • HierarchicalLifetimeManager(所以每个请求我都会得到一个新实例)(阅读依赖范围)

Action 过滤器

    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);
        }
    }

token 提供者

    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;
        }
    }

统一配置

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

Controller

[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 core 使用内置的 DI 容器。 将 TokenProvider 注册为 Transient,以便为每个请求获取一个新的:

services.AddTransient<TokenProvider>();

关于.net - 是否可以从 aspnet core api 中的中间件向 Controller 发送值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39017590/

相关文章:

http - 如果 HTTP/1.0 客户端请求连接 : keep-alive,,它会理解分块编码吗?

javascript - 获取ajax请求的请求头

http-headers - HTTP header 中的 "Content-Length"字段是什么?

c# - 解决方案结构/最佳实践

c# - 在不知道确切结构的情况下计算大量嵌套的 XmlNodes

rest - 未能序列化内容类型的响应正文

c# - WebApi 路由标识与同一 URL 匹配的多个 Controller 类型。怎么解决?

c# - ActiveX 在默认安全设置下无法正常工作

c# - 在 C# 中加密文件名而不在结果字符串中包含不可用的字符

jquery - XMLHTTPRequest 无法加载 http ://. .. Access-Control-Allow-Origin 不允许来源 http://localhost:port