2
votes

I am having some troubles getting some very basic OWIN middleware to handle all requests to the IIS application. I am able to get the OWIN middleware to load per page request but I need it to handle requests for images, 404s, PDFs, and everything that could possible be typed into an address bar under a certain host name.

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");
        }
    }
}

Essentially, whether I request http://localhost/some_bogus_path_and_query.jpg or http://localhost/some_valid_request, all requests would get routed through the Invoke subroutine.

Is this possible to achieve with OWIN?

I have read threads like (How to intercept 404 using Owin middleware) but I am not having any luck. IIS Express keeps serving up 404 errors when I really need OWIN to just write Hello World in all cases, regardless of whether an asset is on disk or not.

Also, I have added runAllManagedModulesForAllRequests="true" to the web.config file and I still cannot get OWIN to fire when I am requesting images via a URL.

2
Map does not support wildcards. Go back to app.Run and runAllManagedModulesForAllRequests.Tratcher

2 Answers

3
votes

You have asked for couple of things altogether in your question. I'll try to answer them one by one. First you want to execute your Middleware for each request. This can be achieved by using StageMarkers within IIS integrated pipeline. All middleware executes after the last stage of StageMarker i.e. PreHandlerExecute. But you can specify when you want to execute your middleware. E.g. To get all incoming request in Middleware try mapping it before either MapHandler or PostResolveCache.

Second, You want to intercept the 404 error redirection. In the same thread that you mentioned; Javier Figueroa answered it in the sample code he provided.

Below is same sample taken from the thread you mentioned:

 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);
        }
    }

In Invoke method as you can see the response has been captured in pipeline which is already generated from IIS integrated pipeline. So the first option that you were thinking to capture is all the requests and then taking the next decision if it's 404 or not which might not work. So it's better if you capture 404 error like in the above sample and then perform your custom actions.

0
votes

Just a note that you may also need 'runAllManagedModulesForAllRequests' set to true in your web.config:

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