从中间件调用控制器的操作方法

Xam*_*Dev 5 c# middleware asp.net-core-mvc asp.net-core

我的中间件类在不同的类库项目中,控制器在不同的项目中.我想要做的是,如果特定条件不符合,那么从中间件重定向到自定义控制器/操作方法.

但是,我无法使用Response.Redirect方法执行此操作.

我怎样才能在中间件类中做到这一点?

对此有任何帮助表示赞赏!

罗希特

Tom*_*han 6

看来你出于错误的原因使用中间件.

我建议你要么中间件通过简单地将其写入到响应流(而不是转发返回一个(很小)404 Next()),或者根本不这样做在中间件,而是在全球注册IActionFilter在你的MVC应用程序.


我在评论中已经解释了上述建议的基本原理,但我认为重要的是提升到实际的答案:

在中间件管道中,您希望每个组件尽可能独立.在OWIN中,有两件事可以实现这种松耦合:

  • 每个组件的输入和输出具有相同的格式,无论是否有10个其他中间件组件,或者根本没有

  • 惯例是管道的每个部分可以按以下顺序执行以下三项中的一项或多项:

    1. 读取(并修改)传入的请求.

    2. 决定完全处理请求,或将处理转发到下一个组件.

    3. 写入响应流.

坚持这些约定时,从可重用的中间件组件中组合,分解和重新组合管道变得非常容易.(想请求记录?只是在管道的开始挂钩中间件组件.要全线一些一般认证逻辑?在管的AUTH阶段添加的成分.要切换到不同的日志框架?更换记录想要在微服务生态系统中应用相同的日志记录吗?重新使用组件.Ethercetera,ad infinum ...)这很有效,因为组件都保持在他们的边界内,并与Web合同一起工作服务器本身可以理解.

ASP.NET的WebAPI似乎是一个不同的野兽,但实际上它只是一个OWIN分量总是配置来处理请求,从不转发到下一个组件(因此他们已经取得难以注册组件在管道中的WebApi之后...).

您要做的是,打破第二点的合同 - 您想告诉下一个组件如何处理请求.但这不取决于你 - 这取决于下一个组件.


Sha*_*tin 6

这是检查请求和重定向的中间件.它适用于内联中间件或中间件类.

public void Configure(IApplicationBuilder app)
{
    // use inline middleware
    app.Use(async (context, next) =>
    {
        // if specific condition does not meet
        if (context.Request.Path.ToString().Equals("/foo"))
        {
            context.Response.Redirect("path/to/controller/action");
        }
        else
        {
            await next.Invoke();
        }
    });

    // or use a middleware class
    app.UseMiddleware<RedirectMiddleware>();

    app.UseMvc();
}
Run Code Online (Sandbox Code Playgroud)

这是中间件类.

public class RedirectMiddleware
{
    private readonly RequestDelegate _next;

    public RedirectMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        // if specific condition does not meet
        if (context.Request.Path.ToString().Equals("/bar"))
        {
            context.Response.Redirect("path/to/controller/action");
        }
        else
        {
            await _next.Invoke(context);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅文档»基础»中间件.