是否可以访问中间件中生成的数据?

时间:2018-04-09 13:36:10

标签: c# asp.net-core-2.0 asp.net-core-middleware

我已经设置了一个非常简单的中间件作为要学习的测试项目,目前它只是转储请求标头。

我想知道,如果有可能的话,下面的设置:

  1. 在Startup类中填充一个字段(然后可以通过DI访问)
  2. 或直接访问中间件中的字段(例如在OnActionExecuting中)
  3. 启动:

    using HeaderAuthentication;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Logging;
    
    namespace ServiceLayer
    {
        // ReSharper disable once ClassNeverInstantiated.Global
        public class Startup
        {
            private IConfiguration Configuration { get; }
    
            public Startup(IConfiguration Configuration)
            {
                this.Configuration = Configuration;
            }
    
            // ReSharper disable once UnusedMember.Global
            public void ConfigureServices(IServiceCollection Services)
            {
                Services.AddMvc().AddJsonOptions(Options =>
                   Options.SerializerSettings.ReferenceLoopHandling =
                       Newtonsoft.Json.ReferenceLoopHandling.Ignore
                );
            }
    
            // ReSharper disable once UnusedMember.Global
            public void Configure(
                IApplicationBuilder App,
                IHostingEnvironment Env,
                ILoggerFactory LoggerFactory
            )
            {
                App.UseHeaderChecking();
    
                if (Env.IsDevelopment())
                {
                    App.UseDeveloperExceptionPage();
                }
    
                App.UseMvc();
            }
        }
    }
    

    扩展方法:

    using Microsoft.AspNetCore.Builder;
    
    namespace HeaderAuthentication
    {
        public static class RequestHeaderCheckingMiddleware
        {
            public static IApplicationBuilder UseHeaderChecking(
                this IApplicationBuilder Builder
            )
            {
                return Builder.UseMiddleware<CheckHeaders>();
            }
        }
    }
    

    CheckHeader代码:

    using InterfaceLayer.Entities;
    using Microsoft.AspNetCore.Http;
    using System;
    using System.Threading.Tasks;
    
    namespace HeaderAuthentication
    {
        public class CheckHeaders
        {
            private readonly RequestDelegate Next;
    
            public CheckHeaders(RequestDelegate NextDelegate)
            {
                Next = NextDelegate;
            }
    
            public Task Invoke(HttpContext Context, SupportContext Support)
            {
                if (Context.Request == null)
                {
                    //return null;
                }
    
                var testA = GetRequestHeader(Context, "X-HeaderTest-A"); // sandwich
                var testB = GetRequestHeader(Context, "X-HeaderTest-B"); // biscuit
    
                return Next(Context);
            }
    
            private static string GetRequestHeader(HttpContext Context, string Key)
            {
                if (!Context.Request.Headers.TryGetValue(Key, out var buffer))
                {
                    return string.Empty;
                }
    
                return buffer;
            }
        }
    }
    

    我希望在我的BaseController中的testA方法中访问testBOnActionExecuting内的值,以触发&#34;三明治&#34;和&#34;饼干&#34;案例如下:

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.Filters;
    using System.Threading.Tasks;
    
    namespace ServiceLayer.Controllers
    {
        public partial class BaseController : Controller
        {
            public BaseController()
            {
            }
    
            public override void OnActionExecuting(ActionExecutingContext Context)
            {
                switch (testValue)
                {
                    case "sandwich":
                        break;
                    case "biscuit":
                        break;
                }
    
                base.OnActionExecuting(Context);
            }
        }
    }
    

    这可行吗?

1 个答案:

答案 0 :(得分:2)

一种肮脏的方式可能是您在CheckHeaders.Invoke方法中的单独的已知密钥下的Context.Items集合中的值,并在BaseController.OnActionExecuting方法中查询上下文项是否存在值并依赖于它采取适当的行动。