【问题标题】:Is it possible to access data generated in Middleware?是否可以访问中间件中生成的数据?
【发布时间】:2023-03-21 12:03:01
【问题描述】:

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

我想知道,鉴于以下设置是否有可能:

  1. 在 Startup 类中填充一个字段(然后可以通过 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 中的值,以触发“三明治”和“饼干”情况,如下所示:

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

这可行吗?

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 听起来一点也不,事实上,这可能是唯一简单的方法。
    • 这听起来比我预期的要干净,谢谢 Alexander
    • 另一种可能性是将服务注册到服务集合,它将所需的值作为范围服务返回给您,并通过依赖注入在基本控制器的实例化点实例化它。这可能比第一个解决方案更干净。
    • 同意,一旦我启动并运行它,我会调查一下;两者都探索总比半途而废要好
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-27
    • 1970-01-01
    • 2022-08-04
    • 2021-04-29
    • 1970-01-01
    相关资源
    最近更新 更多