Skip to content

Odd results mixing fully-tokenized attribute-route and wildcard-map within endpoint-routing #18677

Closed
@billbogaiv

Description

@billbogaiv

Describe the bug

The presence of the attribute-route seems to clobber requests that should go through the separate wildcard-mapped middleware. This only seems to affect fully tokenized and path-separated attribute-routes (i.e. {firstName}/{lastName}, etc.). Something like api/{firstName}/{lastName} is not affected.

My expectation using the sample below is that any request starting with /middleware would go through the middleware due to having a more-exact match based on available endpoints.

To Reproduce

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing.Patterns;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Threading.Tasks;

namespace SampleRouteConflict
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app
                .UseHttpsRedirection()
                .UseRouting()
                .UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers();

                    var appBuilder = endpoints.CreateApplicationBuilder();
                    var pattern = RoutePatternFactory.Parse("/middleware");

                    var pipeline = appBuilder
                        .UsePathBase(pattern.RawText)
                        .UseMiddleware<TestRouteMiddleware>()
                        .Build();

                    endpoints.Map(pattern.RawText + "/{**_}", pipeline);
                });
        }
    }

    [ApiController]
    public class TestRouteController : ControllerBase
    {
        [HttpGet]
        [Route("{firstName}/{lastName}")]
        public IActionResult Index(string firstName, string lastName)
        {
            return Ok(new { firstName, lastName });
        }
    }

    public class TestRouteMiddleware
    {
        public TestRouteMiddleware(RequestDelegate next)
        { }

        public async Task Invoke(HttpContext context)
        {
            await context.Response.WriteAsync("got to the middleware");
        }
    }
}

Results

Request API Match Middleware Match 404?
/middleware X
/middleware/test X
/middleware/test1/test2 X
/bill/boga X

Results removing endpoints.MapControllers();

Request API Match Middleware Match 404?
/middleware X
/middleware/test X
/middleware/test1/test2 X
/bill/boga X

Further technical details

.NET Core SDK (reflecting any global.json):
 Version:   3.1.100
 Commit:    cd82f021f4

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.18362
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\3.1.100\

Host (useful for support):
  Version: 3.1.0
  Commit:  65f04fb6db

Metadata

Metadata

Assignees

Labels

area-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templatesinvestigate

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions