Search code examples
katana

How to use IAppBuilder.UseWebApi after OWIN middleware


I have 3 middleware classes that execute successfully until there are are no more middleware classes. After the middleware classes have been invoked and there are no more I would like to pass the request to the router.

What is the best way of doing this?

For example, I have this code:

// Register middleware. Order is important!
app.Use<Authentication>();
app.Use<Logging>();
app.Use<Example>(configExample);

This works as expected.On every request first Authentication runs, then Logging, then Example.

And I can see that on starting the program, that these app.Use<>() lines instantiate the appropriate middleware by passing in a delegate. That delegate includes a property Target which points at the next middleware class to be run. For obvious reasons the delegate passed to the Example class is is empty (since it's the last middleware class in the chain).

Without altering code in the last-chained middleware class (I would not like order to be important), how can I invoke the router? My router looks something like this:

HttpConfiguration config = new HttpConfiguration();
config.Routes.MapHttpRoute(
    ...
);
config.Routes.MapHttpRoute(
    ...
);
etc.
app.UseWebApi(config);

I think there must be some great logical gap in my understanding since there must be a logical way to end a middleware chain


Solution

  • the answer is that the middleware is passed automatically to the controller when there is no more middleware. but the tutorials I was following used lines of code in the middleware that prevented this.

    I had followed instructions on a neat way to create middleware here: https://www.codeproject.com/Articles/864725/ASP-NET-Understanding-OWIN-Katana-and-the-Middlewa.

    And these two lines:

    IOwinContext context = new OwinContext(environment);
    await context.Response.WriteAsync("<h1>Hello from Example " + _configExample + "</h1>");
    

    resulted in the response from the controller being truncated (or something). This is the code:

    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    
    namespace Avesta.ASP.Middleware
    {
        using AppFunc = Func<IDictionary<string, object>, Task>;
    
        public class Example
        {
            AppFunc _next;
            string _configExample;
    
            public Example(AppFunc next, string configExample)
            {
                _next = next;
                _configExample = configExample;
            }
    
            public async Task Invoke(IDictionary<string, object> env)
            {
                //IOwinContext context = new OwinContext(environment);
                //await context.Response.WriteAsync("<h1>Hello from Example " + _configExample + "</h1>");
                await _next.Invoke(env);
            }
        }
    }