通过 OWIN 中间件路由所有请求

Route ALL requests through OWIN Middleware

我在获取一些非常基本的 OWIN 中间件来处理对 IIS 应用程序的所有请求时遇到了一些麻烦。我能够让 OWIN 中间件在每个页面请求中加载,但我需要它来处理对图像、404、PDF 以及可能在特定主机名下的地址栏中输入的所有内容的请求。

namespace HelloWorld
{
    // Note: By default all requests go through this OWIN pipeline. Alternatively you can turn this off by adding an appSetting owin:AutomaticAppStartup with value “false”. 
    // With this turned off you can still have OWIN apps listening on specific routes by adding routes in global.asax file using MapOwinPath or MapOwinRoute extensions on RouteTable.Routes
    public class Startup
    {
        // Invoked once at startup to configure your application.
        public void Configuration(IAppBuilder app)
        {
            app.Map(new PathString("/*"),
                (application) =>
                {
                    app.Run(Invoke);
                });

            //app.Run(Invoke);
        }

        // Invoked once per request.
        public Task Invoke(IOwinContext context)
        {
            context.Response.ContentType = "text/plain";
            return context.Response.WriteAsync("Hello World");
        }
    }
}

基本上,无论我请求 http://localhost/some_bogus_path_and_query.jpg or http://localhost/some_valid_request,所有请求都将通过 Invoke 子例程进行路由。

这可以用 OWIN 实现吗?

我读过像 (How to intercept 404 using Owin middleware) 这样的话题,但我运气不好。当我真的需要 OWIN 在所有情况下只编写 Hello World,无论资产是否在磁盘上时,IIS Express 都会继续提供 404 错误。

此外,我已将 runAllManagedModulesForAllRequests="true" 添加到 web.config 文件中,但当我通过 URL.[=13= 请求图像时仍然无法启动 OWIN ]

您在问题中一共问了两件事。我会尽力一一回答。首先,您要为每个请求执行您的中间件。这可以通过 using StageMarkers within IIS integrated pipeline 来实现。所有中间件都在 StageMarker 的最后阶段之后执行,即 PreHandlerExecute。但是您可以指定何时执行中间件。例如。要在中间件中获取所有传入请求,请尝试在 MapHandlerPostResolveCache.

之前映射它

其次,您想拦截404错误重定向。在同一个 thread that you mentioned; Javier Figueroa 在他提供的示例代码中回答了这个问题。

下面是从您提到的线程中截取的相同示例:

 public async Task Invoke(IDictionary<string, object> arg)
    {
        await _innerMiddleware.Invoke(arg);
        // route to root path if the status code is 404
        // and need support angular html5mode
        if ((int)arg["owin.ResponseStatusCode"] == 404 && _options.Html5Mode)
        {
            arg["owin.RequestPath"] = _options.EntryPath.Value;
            await _innerMiddleware.Invoke(arg);
        }
    }

Invoke 方法中,您可以看到响应已在已从 IIS 集成管道生成的管道中捕获。因此,您考虑捕获的第一个选项是所有请求,然后在是否为 404 时做出下一个决定,这可能行不通。因此,最好像上面的示例一样捕获 404 错误,然后执行自定义操作。

请注意,您可能还需要在 web.config:

<configuration>
   <system.webServer>
      <modules runAllManagedModulesForAllRequests="true" />
   </system.webServer>
</configuration>