通过OWIN Middleware路由所有请求

时间:2015-11-30 18:27:27

标签: asp.net asp.net-mvc-4 owin

我遇到一些麻烦,得到一些非常基本的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还是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请求图像时,仍然无法触发OWIN。

2 个答案:

答案 0 :(得分:2)

你在问题​​中完全要求了几件事。我会尽力逐一回答。首先,您要为每个请求执行中间件。这可以通过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错误,然后执行自定义操作,则会更好。

答案 1 :(得分:0)

仅需注意,您可能还需要在web.config中将' runAllManagedModulesForAllRequests '设置为 true

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