对某些控制器使用中间件

sky*_*fer 7 c# middleware asp.net-core-3.1

在我的 ASP Net Core 应用程序中,我需要仅为特定控制器应用自定义中间件。

我找到了这个例子

app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), appBuilder =>
{
    app.UseMiddleware();
});

Run Code Online (Sandbox Code Playgroud)

这是正确的方法吗?

如何检查请求路径是否包含特定路径而不是开头?

gra*_*der 15

(你是)“接近”......但通过一些调整......你可以实现你想要的:

你有

 app.UseMiddleware();
Run Code Online (Sandbox Code Playgroud)

您很可能想要指定要使用的中间件。请参阅下面的“MyMiddlewareOne”示例。

下面是使用Asp.Net Core 3.1进行测试。(我想我是在 3.1.407,但 3.1 或更高版本应该没问题)

简单版本:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;


public class Startup
{

    public void Configure(ILogger<Startup> logger, IApplicationBuilder app, IWebHostEnvironment env)

    {


        app.UseRouting();

        app.UseAuthentication();


        app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), appBuilder =>
        {
            appBuilder.UseMiddleware<MyMiddlewareOne>();
        });

        app.UseEndpoints(endpoints =>
        { blah blah blah } );



    }
}
Run Code Online (Sandbox Code Playgroud)

现在,您应该小心制定规则的复杂程度。

但你可以这样做:

[ApiController]
[Route("apiwideopen/[controller]")]
public class WeatherForecastController : ControllerBase
{
}

[Route("apisecure/[controller]")]
[ApiController]
public class MyNeedsToBeSecureController : ControllerBase
{
}



        app.UseWhen(context => context.Request.Path.StartsWithSegments("/apisecure"), appBuilder =>
        {
            appBuilder.UseMiddleware<MyMiddlewareOne>();
        });
Run Code Online (Sandbox Code Playgroud)

您也可以这样做来封装规则。

        app.UseWhen(context => this.CheckMoreAdvancedRules(context), appBuilder =>
        {
            appBuilder.UseMiddleware<MyMiddlewareOne>();
        });



    private bool CheckMoreAdvancedRules(Microsoft.AspNetCore.Http.HttpContext ctx)
    {
        bool returnValue = false;

        if (null != ctx && ctx.Request.Path.StartsWithSegments("/apisecure"))
        {
            returnValue = true;
        }

        if(!returnValue)
        {
            /* do whatever you want here */
            /* if the moon is blue at midnight (then) returnValue = true; */
        }

        return returnValue;
    }
Run Code Online (Sandbox Code Playgroud)

最后,你要注意

“MapWhen”和“UseWhen”

看:

在使用 MapWhen 进行分支时注册中间件,以便仅针对一组端点运行它

另请参阅这篇文章:

https://www.devtrends.co.uk/blog/conditional-middleware-based-on-request-in-asp.net-core


Boh*_*pak 4

正如这个答案所建议的,如果您需要 MVC 上下文,您应该更喜欢过滤器而不是中间件。

您还可以在这里找到如何将过滤器应用到特定控制器的示例。