tntwist / NL.Serverless.AspNetCore

Hosting an AspNet Core App inside an Azure Function V3 HTTP Trigger
MIT License
20 stars 3 forks source link

Routing inconsistency #32

Closed alastairtree closed 3 years ago

alastairtree commented 3 years ago

Hello

Thanks for this library - it is great!

I think I have uncovered a routing inconsistency to do with aspnet middleware that is breaking my apps ability to use this library to host in functions. When you run aspnet middleware in the functions host the RouteData does not get populated in the same way as when the app runs under a proper kestral host.

For example place the following middleware in the startup class of the WebApp project, run the app in the 2 environments (aspnet/functions) and observe different data is retrieved from HttpContent.GetRouteData():

  // place me after UseRouting() and just before UseEndpoints() in startup

    app.Use(async (context, next) =>
    {
        // when run under aspnet the following prints 'RouteData: [[action, Get],[controller, Values]]'
        // when run under functions host it prints    'RouteData: [[any, api/values]]'

        var routeValueDictionary = context.GetRouteData().Values;
        Console.WriteLine("RouteData: [" + string.Join(",", routeValueDictionary.Select(x => x.ToString())) + "]");
        await next.Invoke();
    });

As you can see the route data is coming from the functions route and not the routing of the simulated web server. Is there anyway to configure NL.Serverless.AspNetCore so that RouteData will be populated as if the request was real, with the selected controller and action name? Routing is working fine, but I have middleware that relies on the correct RouteData behaviour.

Alastair

alastairtree commented 3 years ago

In case it helps I managed to add an extra middleware in my webapp startup class which replaces the IRoutingFeature behaviours that are "leaking" in from the functions host and restore the route data as it would appear under regular aspnet. This extra middleware need to be applied before whatever middleware needs to call GetRouteData.

// Override the routing feature provided by Azure Functions host
app.Use(async (context, next) =>
{
    context.Features.Get<IRoutingFeature>().RouteData = new RouteData(context.Request.RouteValues);
    await next.Invoke();
});
tntwist commented 3 years ago

Hi,

thanks for creating the issue and great that you found a workaround.

I´ll look for a way to fix it inside the library.

Greetings Nico

tntwist commented 3 years ago

I found the solution: https://github.com/tntwist/NL.Serverless.AspNetCore/commit/4e70f29b697602eb191677bac9406b6279f5daac

The problem seems to be that the IRoutingFeature was already created by the function host. Adding a middleware removing it fixes the invalid route data.

I will update some dependencies and release a new version soon.

tntwist commented 3 years ago

The update of the library should be available soon on NuGet.

Please let me know if the routing values are now correct.

Greetings Nico

alastairtree commented 3 years ago

Yeah that works perfectly - thanks for the quick fix.