网关API中的.Net核心筛选器

时间:2019-04-04 16:18:30

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

我想将过滤器合并到我创建的Gateway 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 *** ???
//

1 个答案:

答案 0 :(得分: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。尝试创建一个与您实际上想要的东西直接相关的新问题,而不是您认为将使您到达那里的解决方案。

相关问题