【问题标题】:.Net Core Filters in a Gateway API网关 API 中的 .Net Core 过滤器
【发布时间】:2019-08-26 11:49:06
【问题描述】:

我想将过滤器合并到我创建的网关 API 项目中。这个项目中没有控制器(我认为这很重要)。它面向多个微服务,充当反向代理,并执行横切关注点和编排。我需要对管道中的请求应用各种过滤器 - 主要是包含标头数据。我无法应用过滤器——断点不会被命中,也没有例外。

我有 3 个问题:

  • 如何让过滤器工作?

  • 如何在设计时将参数传递给过滤器?

  • 如何在运行时将参数传递给过滤器(依赖项)?见最后一行代码示例

STARTUP.CS

public void ConfigureServices(IServiceCollection services)
        {
            var logger = _loggerFactory.CreateLogger<Startup>();
            services.AddCors(options =>
            {
                options.AddPolicy("app-cors-policy",
                    builder =>
                    {
                        builder
                            .AllowAnyOrigin()
                            .AllowAnyHeader()
                            .AllowAnyMethod()
                            .AllowCredentials()
                            .WithExposedHeaders("Content-Disposition") //headers to be exposed
                        ;
                    });
            });

            services.AddMvc(options =>
            {
                options.Filters.Add(new ContentDispositionFilter(?????));
            });
        }

   public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {           
        app.UseCors("app-cors-policy").UseMvc();

        app.Run(async (context) =>
        {
            _router.Request = context.Request;
            var httpResponseMessage = await _router.RouteRequest();

            if (httpResponseMessage.IsSuccessStatusCode)
            {
//
// *** HOW DO I PASS httpResponseMessage TO A FILTER *** ???
//

【问题讨论】:

    标签: c# asp.net-core .net-core asp.net-core-webapi asp.net-core-2.1


    【解决方案1】:

    嗯,你不能同时做这两件事。不清楚这是否真的是你的要求,但如果是这样,那你就不走运了。

    要在设计时传递东西,您可以像使用任何其他类一样使用构造函数:

    options.Filters.Add(new ContentDispositionFilter("foo"));
    

    这将对应于该类的构造函数,例如:

    public ContentDispositionFilter(string myParam)
    

    要添加运行时依赖项,您必须使用依赖项注入。简单地说,你让构造函数有各种依赖的参数:

    public ContentDispositionFilter(Dependency1 dep1, Dependency2, dep2)
    

    然后,要注册全局过滤器,您必须通过 type 进行注册,而不是引用。你目前的做法是通过引用,你的新方法在哪里。相反,您需要这样做:

    options.Filters.Add(typeof(ContentDispositionFilter));
    

    然后,当然,您需要确保您的过滤器实际上已在服务集合中注册:

    services.AddScoped<ContentDispositionFilter>();
    

    编辑

    值得一提的是,服务注册本身就让您有机会同时做这两件事。您实际上可以像这样将工厂 lambda 传递给它:

    services.AddScoped(p =>
    {
        var dep1 = p.GetRequiredService<Dependency1>();
        return new ContentDispositionFilter("foo", dep1);
    }
    

    所以在这里,你有一些静态的东西(字符串)你正在传递获得运行时服务。 p 参数有一个 IServiceProvider 的实例,因此您可以从中检索您喜欢的任何服务。

    编辑#2

    所以,我刚刚注意到代码块末尾的注释:

    //
    // *** HOW DO I PASS httpResponseMessage TO A FILTER *** ???
    //
    

    简单地说,你不能。不在这里。我不确定你最终想要达到什么目标,但这不是实现它的方法。现在这似乎是一个XY problem。尝试创建一个与您实际想要的直接相关的新问题,而不是您认为可以帮助您实现目标的解决方案。

    【讨论】:

    • 我会试试你的建议。我的问题之一是我无法让过滤器中的代码达到断点(OnResultExecuting/ed)。好像没有注册。另外,我不需要同时这样做。
    • 由于我在一个不使用控制器的环境中,我认为过滤器不是答案,也许中间件是。我的意思是,如果管道中不存在操作或结果,过滤器如何对它们做出反应。
    猜你喜欢
    • 2017-06-09
    • 1970-01-01
    • 2017-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-27
    相关资源
    最近更新 更多