Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix multiple routes of same template in attribute-based routing #2250

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@ internal sealed class HttpRequestRouteHelper
{
// WebAPI attribute routing flows here. Use reflection to not take a dependency on microsoft.aspnet.webapi.core\[version]\lib\[framework]\System.Web.Http.

if (msSubRoutes is Array attributeRouting && attributeRouting.Length == 1)
if (msSubRoutes is Array attributeRouting && attributeRouting.Length >= 1)
{
// There could be more than one subroute, each with a different method.
// But the template is the same across them, so we simply take the template
// from the first route.
var subRouteData = attributeRouting.GetValue(0);

_ = this.routeFetcher.TryFetch(subRouteData, out var route);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public enum QueryRedactionDisableBehavior
[InlineData("https://localhost:443/about_attr_route/10", "https", "/about_attr_route/10", null, null, "localhost", 443, "HEAD", "HEAD", null, 2, "about_attr_route/{customerId}", "HEAD about_attr_route/{customerId}")]
[InlineData("http://localhost:1880/api/weatherforecast", "http", "/api/weatherforecast", null, null, "localhost", 1880, "GET", "GET", null, 3, "api/{controller}/{id}", "GET api/{controller}/{id}")]
[InlineData("https://localhost:1843/subroute/10", "https", "/subroute/10", null, null, "localhost", 1843, "GET", "GET", null, 4, "subroute/{customerId}", "GET subroute/{customerId}")]
[InlineData("https://localhost:1843/subroute/10", "https", "/subroute/10", null, null, "localhost", 1843, "GET", "GET", null, 5, "subroute/{customerId}", "GET subroute/{customerId}")]
[InlineData("http://localhost/api/value", "http", "/api/value", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, "/api/value")] // Request will be filtered
[InlineData("http://localhost/api/value", "http", "/api/value", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, "{ThrowException}")] // Filter user code will throw an exception
[InlineData("http://localhost/", "http", "/", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, null, true, "System.InvalidOperationException")] // Test RecordException option
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using System.Net.Http;
using System.Web;
using System.Web.Routing;

Expand Down Expand Up @@ -40,6 +41,75 @@ public static HttpContext BuildHttpContext(string url, int routeType, string? ro
"MS_SubRoutes",
value);
break;
case 5: // Multi-method attribute routing WebAPI.
routeData = new RouteData();
var multiMethodSubroutes = new[]
{
new
{
Route = new
{
RouteTemplate = routeTemplate,
DataTokens = new Dictionary<string, object>
{
["actions"] = new[]
{
new
{
SupportedHttpMethods = new[]
{
HttpMethod.Get,
},
},
},
},
},
},
new
{
Route = new
{
RouteTemplate = routeTemplate,
DataTokens = new Dictionary<string, object>
{
["actions"] = new[]
{
new
{
SupportedHttpMethods = new[]
{
HttpMethod.Put,
},
},
},
},
},
},
new
{
Route = new
{
RouteTemplate = routeTemplate,
DataTokens = new Dictionary<string, object>
{
["actions"] = new[]
{
new
{
SupportedHttpMethods = new[]
{
HttpMethod.Delete,
},
},
},
},
},
},
};
routeData.Values.Add(
"MS_SubRoutes",
multiMethodSubroutes);
break;
default:
throw new NotSupportedException();
}
Expand Down