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

Is it possible to access data generated in Middleware?

我已经建立了一个非常简单的中间件作为测试项目来学习,目前它只是转储请求headers。

我想知道,考虑到下面的 set-up 是否可以:

  1. 在 Startup class 中填充一个字段(然后可以通过 DI 访问)
  2. 或者直接访问中间件中的字段(比如在 OnActionExecuting 中)

启动:

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 中的 OnActionExecuting 方法中访问 testAtestB 中的值以触发 "sandwich" 和 "biscuit"例,如下:

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

这样可行吗?

一种肮脏的方式可能是将您的值放入 Context.Items 集合中的 CheckHeaders.Invoke 方法中一个单独的众所周知的键下,并查询上下文项以了解 [=14] 中是否存在值=] 方法并依赖它来适当地采取行动。