diff --git a/src/Http/Routing/samples/MapActionSample/Startup.cs b/src/Http/Routing/samples/MapActionSample/Startup.cs index 2efb7dd71e5b..e3c44398834b 100644 --- a/src/Http/Routing/samples/MapActionSample/Startup.cs +++ b/src/Http/Routing/samples/MapActionSample/Startup.cs @@ -28,10 +28,9 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) app.UseEndpoints(endpoints => { - [HttpPost("/EchoTodo")] JsonResult EchoTodo([FromBody] Todo todo) => new(todo); - endpoints.MapAction((Func)EchoTodo); + endpoints.MapPost("/EchoTodo", (Func)EchoTodo); endpoints.MapPost("/EchoTodoProto", async httpContext => { diff --git a/src/Http/Routing/src/Builder/MapActionEndpointRouteBuilderExtensions.cs b/src/Http/Routing/src/Builder/MapActionEndpointRouteBuilderExtensions.cs index f8dbad11be27..e816c1cdb779 100644 --- a/src/Http/Routing/src/Builder/MapActionEndpointRouteBuilderExtensions.cs +++ b/src/Http/Routing/src/Builder/MapActionEndpointRouteBuilderExtensions.cs @@ -22,68 +22,6 @@ public static class MapActionEndpointRouteBuilderExtensions private static readonly string[] PutVerb = new[] { "PUT" }; private static readonly string[] DeleteVerb = new[] { "DELETE" }; - /// - /// Adds a to the that matches the pattern specified via attributes. - /// - /// The to add the route to. - /// The delegate executed when the endpoint is matched. - /// An that can be used to further customize the endpoint. - public static MapActionEndpointConventionBuilder MapAction( - this IEndpointRouteBuilder endpoints, - Delegate action) - { - if (endpoints is null) - { - throw new ArgumentNullException(nameof(endpoints)); - } - - if (action is null) - { - throw new ArgumentNullException(nameof(action)); - } - - var requestDelegate = MapActionExpressionTreeBuilder.BuildRequestDelegate(action); - - var routeAttributes = action.Method.GetCustomAttributes().OfType(); - var conventionBuilders = new List(); - - const int defaultOrder = 0; - - foreach (var routeAttribute in routeAttributes) - { - if (routeAttribute.RoutePattern is not string pattern) - { - continue; - } - - var routeName = (routeAttribute as IRouteNameMetadata)?.RouteName; - var routeOrder = (routeAttribute as IRouteOrderMetadata)?.RouteOrder; - - var conventionBuilder = endpoints.Map(pattern, requestDelegate); - - conventionBuilder.Add(endpointBuilder => - { - foreach (var attribute in action.Method.GetCustomAttributes()) - { - endpointBuilder.Metadata.Add(attribute); - } - - endpointBuilder.DisplayName = routeName ?? pattern; - - ((RouteEndpointBuilder)endpointBuilder).Order = routeOrder ?? defaultOrder; - }); - - conventionBuilders.Add(conventionBuilder); - } - - if (conventionBuilders.Count == 0) - { - throw new InvalidOperationException("Action must have a pattern. Is it missing a Route attribute?"); - } - - return new MapActionEndpointConventionBuilder(conventionBuilders); - } - /// /// Adds a to the that matches HTTP GET requests /// for the specified pattern. @@ -168,8 +106,8 @@ public static MapActionEndpointConventionBuilder MapMethods( throw new ArgumentNullException(nameof(httpMethods)); } - var displayName = $"{pattern} HTTP: {string.Join(", ", httpMethods)}"; - var builder = endpoints.Map(RoutePatternFactory.Parse(pattern), action, displayName); + var builder = endpoints.Map(RoutePatternFactory.Parse(pattern), action); + builder.WithDisplayName($"{pattern} HTTP: {string.Join(", ", httpMethods)}"); builder.WithMetadata(new HttpMethodMetadata(httpMethods)); return builder; } @@ -202,15 +140,6 @@ public static MapActionEndpointConventionBuilder Map( this IEndpointRouteBuilder endpoints, RoutePattern pattern, Delegate action) - { - return Map(endpoints, pattern, action, displayName: null); - } - - private static MapActionEndpointConventionBuilder Map( - this IEndpointRouteBuilder endpoints, - RoutePattern pattern, - Delegate action, - string? displayName) { if (endpoints is null) { @@ -239,39 +168,16 @@ private static MapActionEndpointConventionBuilder Map( // Add delegate attributes as metadata var attributes = action.Method.GetCustomAttributes(); - string? routeName = null; - int? routeOrder = null; // This can be null if the delegate is a dynamic method or compiled from an expression tree if (attributes is not null) { foreach (var attribute in attributes) { - if (attribute is IRoutePatternMetadata patternMetadata && patternMetadata.RoutePattern is not null) - { - throw new InvalidOperationException($"'{attribute.GetType()}' implements {nameof(IRoutePatternMetadata)} which is not supported by this method."); - } - if (attribute is IHttpMethodMetadata methodMetadata && methodMetadata.HttpMethods.Any()) - { - throw new InvalidOperationException($"'{attribute.GetType()}' implements {nameof(IHttpMethodMetadata)} which is not supported by this method."); - } - - if (attribute is IRouteNameMetadata nameMetadata && nameMetadata.RouteName is string name) - { - routeName = name; - } - if (attribute is IRouteOrderMetadata orderMetadata && orderMetadata.RouteOrder is int order) - { - routeOrder = order; - } - builder.Metadata.Add(attribute); } } - builder.DisplayName = routeName ?? displayName ?? builder.DisplayName; - builder.Order = routeOrder ?? defaultOrder; - var dataSource = endpoints.DataSources.OfType().FirstOrDefault(); if (dataSource is null) { diff --git a/src/Http/Routing/src/IRouteOrderMetadata.cs b/src/Http/Routing/src/IRouteOrderMetadata.cs deleted file mode 100644 index 4326b24e5625..000000000000 --- a/src/Http/Routing/src/IRouteOrderMetadata.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -namespace Microsoft.AspNetCore.Routing -{ - /// - /// Interface for attributes which can supply a route order for attribute routing. - /// - public interface IRouteOrderMetadata - { - /// - /// Gets the route order. The order determines the order of route execution. Routes with a lower - /// order value are tried first. When a route doesn't specify a value, it gets a default value of 0. - /// A null value for the Order property means that the user didn't specify an explicit order for the - /// route. - /// - int? RouteOrder { get; } - } -} diff --git a/src/Http/Routing/src/IRoutePatternMetadata.cs b/src/Http/Routing/src/IRoutePatternMetadata.cs deleted file mode 100644 index 615a67abfbeb..000000000000 --- a/src/Http/Routing/src/IRoutePatternMetadata.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -namespace Microsoft.AspNetCore.Routing -{ - /// - /// Interface for attributes which can supply a route pattern for attribute routing. - /// - public interface IRoutePatternMetadata - { - /// - /// The route pattern. May be . - /// - string? RoutePattern { get; } - } -} diff --git a/src/Http/Routing/src/PublicAPI.Unshipped.txt b/src/Http/Routing/src/PublicAPI.Unshipped.txt index a4c37efae127..bc8b253e7bfb 100644 --- a/src/Http/Routing/src/PublicAPI.Unshipped.txt +++ b/src/Http/Routing/src/PublicAPI.Unshipped.txt @@ -12,15 +12,10 @@ Microsoft.AspNetCore.Routing.DataTokensMetadata.DataTokens.get -> System.Collect Microsoft.AspNetCore.Routing.DataTokensMetadata.DataTokensMetadata(System.Collections.Generic.IReadOnlyDictionary! dataTokens) -> void Microsoft.AspNetCore.Routing.IDataTokensMetadata.DataTokens.get -> System.Collections.Generic.IReadOnlyDictionary! Microsoft.AspNetCore.Routing.IRouteNameMetadata.RouteName.get -> string? -Microsoft.AspNetCore.Routing.IRouteOrderMetadata -Microsoft.AspNetCore.Routing.IRouteOrderMetadata.RouteOrder.get -> int? -Microsoft.AspNetCore.Routing.IRoutePatternMetadata -Microsoft.AspNetCore.Routing.IRoutePatternMetadata.RoutePattern.get -> string? Microsoft.AspNetCore.Routing.RouteNameMetadata.RouteName.get -> string? Microsoft.AspNetCore.Routing.RouteNameMetadata.RouteNameMetadata(string? routeName) -> void static Microsoft.AspNetCore.Builder.MapActionEndpointRouteBuilderExtensions.Map(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder! endpoints, Microsoft.AspNetCore.Routing.Patterns.RoutePattern! pattern, System.Delegate! action) -> Microsoft.AspNetCore.Builder.MapActionEndpointConventionBuilder! static Microsoft.AspNetCore.Builder.MapActionEndpointRouteBuilderExtensions.Map(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder! endpoints, string! pattern, System.Delegate! action) -> Microsoft.AspNetCore.Builder.MapActionEndpointConventionBuilder! -static Microsoft.AspNetCore.Builder.MapActionEndpointRouteBuilderExtensions.MapAction(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder! endpoints, System.Delegate! action) -> Microsoft.AspNetCore.Builder.MapActionEndpointConventionBuilder! static Microsoft.AspNetCore.Builder.MapActionEndpointRouteBuilderExtensions.MapDelete(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder! endpoints, string! pattern, System.Delegate! action) -> Microsoft.AspNetCore.Builder.MapActionEndpointConventionBuilder! static Microsoft.AspNetCore.Builder.MapActionEndpointRouteBuilderExtensions.MapGet(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder! endpoints, string! pattern, System.Delegate! action) -> Microsoft.AspNetCore.Builder.MapActionEndpointConventionBuilder! static Microsoft.AspNetCore.Builder.MapActionEndpointRouteBuilderExtensions.MapMethods(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder! endpoints, string! pattern, System.Collections.Generic.IEnumerable! httpMethods, System.Delegate! action) -> Microsoft.AspNetCore.Builder.MapActionEndpointConventionBuilder! diff --git a/src/Http/Routing/test/FunctionalTests/MapActionTest.cs b/src/Http/Routing/test/FunctionalTests/MapActionTest.cs index 3723b3ca5b02..e627307eb7b3 100644 --- a/src/Http/Routing/test/FunctionalTests/MapActionTest.cs +++ b/src/Http/Routing/test/FunctionalTests/MapActionTest.cs @@ -19,48 +19,6 @@ namespace Microsoft.AspNetCore.Routing.FunctionalTests { public class MapActionTest { - [Fact] - public async Task MapAction_FromBodyWorksWithJsonPayload() - { - [HttpPost("/EchoTodo/{id}")] - Todo EchoTodo([FromRoute] int id, [FromBody] Todo todo) => todo with { Id = id }; - - using var host = new HostBuilder() - .ConfigureWebHost(webHostBuilder => - { - webHostBuilder - .Configure(app => - { - app.UseRouting(); - app.UseEndpoints(b => b.MapAction((Func)EchoTodo)); - }) - .UseTestServer(); - }) - .ConfigureServices(services => - { - services.AddRouting(); - }) - .Build(); - - using var server = host.GetTestServer(); - await host.StartAsync(); - var client = server.CreateClient(); - - var todo = new Todo - { - Name = "Write tests!" - }; - - var response = await client.PostAsJsonAsync("/EchoTodo/42", todo); - response.EnsureSuccessStatusCode(); - - var echoedTodo = await response.Content.ReadFromJsonAsync(); - - Assert.NotNull(echoedTodo); - Assert.Equal(todo.Name, echoedTodo?.Name); - Assert.Equal(42, echoedTodo?.Id); - } - [Fact] public async Task MapPost_FromBodyWorksWithJsonPayload() { diff --git a/src/Http/Routing/test/UnitTests/Builder/MapActionEndpointRouteBuilderExtensionsTest.cs b/src/Http/Routing/test/UnitTests/Builder/MapActionEndpointRouteBuilderExtensionsTest.cs index ea68f2d96e31..37c66218c892 100644 --- a/src/Http/Routing/test/UnitTests/Builder/MapActionEndpointRouteBuilderExtensionsTest.cs +++ b/src/Http/Routing/test/UnitTests/Builder/MapActionEndpointRouteBuilderExtensionsTest.cs @@ -6,9 +6,8 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using Microsoft.AspNetCore.Routing; -using Microsoft.AspNetCore.Routing.Patterns; -using Microsoft.AspNetCore.Routing.TestObjects; using Moq; using Xunit; @@ -27,74 +26,39 @@ private RouteEndpointBuilder GetRouteEndpointBuilder(IEndpointRouteBuilder endpo } [Fact] - public void MapAction_BuildsEndpointFromAttributes() + public void MapEndpoint_PrecedenceOfMetadata_BuilderMetadataReturned() { - const string customPattern = "/CustomTemplate"; - const string customMethod = "CUSTOM_METHOD"; - - [CustomRouteMetadata(Pattern = customPattern, Methods = new[] { customMethod })] - void TestAction() { }; - var builder = new DefaultEndpointRouteBuilder(Mock.Of()); - _ = builder.MapAction((Action)TestAction); - - var routeEndpointBuilder = GetRouteEndpointBuilder(builder); - Assert.Equal(customPattern, routeEndpointBuilder.RoutePattern.RawText); - - var dataSource = GetBuilderEndpointDataSource(builder); - var endpoint = Assert.Single(dataSource.Endpoints); - - var httpMethodMetadata = Assert.Single(endpoint.Metadata.OfType()); - var method = Assert.Single(httpMethodMetadata.HttpMethods); - Assert.Equal(customMethod, method); - } - - [Fact] - public void MapAction_BuildsEndpointWithRouteNameAndOrder() - { - const string customName = "Custom Name"; - const int customOrder = 1337; - // This is tested separately because MapAction requires a Pattern and the other overloads forbit it. - [CustomRouteMetadata(Pattern = "/", Name = customName, Order = customOrder)] - void TestAction() { }; + [HttpMethod("ATTRIBUTE")] + void TestAction() + { + } - var builder = new DefaultEndpointRouteBuilder(Mock.Of()); - _ = builder.MapAction((Action)TestAction); + var endpointBuilder = builder.MapMethods("/", new[] { "METHOD" }, (Action)TestAction); + endpointBuilder.WithMetadata(new HttpMethodMetadata(new[] { "BUILDER" })); - var dataSource = GetBuilderEndpointDataSource(builder); - // Trigger Endpoint build by calling getter. + var dataSource = Assert.Single(builder.DataSources); var endpoint = Assert.Single(dataSource.Endpoints); - var routeEndpointBuilder = GetRouteEndpointBuilder(builder); - Assert.Equal(customName, routeEndpointBuilder.DisplayName); - Assert.Equal(customOrder, routeEndpointBuilder.Order); - } - - [Theory] - [MemberData(nameof(MapActionMethods))] - public void MapOverloads_BuildsEndpointWithRouteNameAndOrder(Action mapOverload) - { - const string customName = "Custom Name"; - const int customOrder = 1337; + var metadataArray = endpoint.Metadata.Where(m => m is not CompilerGeneratedAttribute).ToArray(); - [CustomRouteMetadata(Name = customName, Order = customOrder)] - void TestAction() { }; + Assert.Equal(3, metadataArray.Length); + Assert.Equal("ATTRIBUTE", GetMethod(metadataArray[0])); + Assert.Equal("METHOD", GetMethod(metadataArray[1])); + Assert.Equal("BUILDER", GetMethod(metadataArray[2])); - var builder = new DefaultEndpointRouteBuilder(Mock.Of()); - mapOverload(builder, (Action)TestAction); + Assert.Equal("BUILDER", endpoint.Metadata.GetMetadata()!.HttpMethods.Single()); - var dataSource = GetBuilderEndpointDataSource(builder); - // Trigger Endpoint build by calling getter. - var endpoint = Assert.Single(dataSource.Endpoints); - - var routeEndpointBuilder = GetRouteEndpointBuilder(builder); - Assert.Equal(customName, routeEndpointBuilder.DisplayName); - Assert.Equal(customOrder, routeEndpointBuilder.Order); + string GetMethod(object metadata) + { + var httpMethodMetadata = Assert.IsAssignableFrom(metadata); + return Assert.Single(httpMethodMetadata.HttpMethods); + } } [Fact] - public void MapGet_BuildsEndpointWithRouteNameAndOrder() + public void MapGet_BuildsEndpointWithCorrectMethod() { var builder = new DefaultEndpointRouteBuilder(Mock.Of()); _ = builder.MapGet("/", (Action)(() => { })); @@ -107,10 +71,14 @@ public void MapGet_BuildsEndpointWithRouteNameAndOrder() Assert.NotNull(methodMetadata); var method = Assert.Single(methodMetadata!.HttpMethods); Assert.Equal("GET", method); + + var routeEndpointBuilder = GetRouteEndpointBuilder(builder); + Assert.Equal("/ HTTP: GET", routeEndpointBuilder.DisplayName); + Assert.Equal("/", routeEndpointBuilder.RoutePattern.RawText); } [Fact] - public void MapPost_BuildsEndpointWithRouteNameAndOrder() + public void MapPost_BuildsEndpointWithCorrectMethod() { var builder = new DefaultEndpointRouteBuilder(Mock.Of()); _ = builder.MapPost("/", (Action)(() => { })); @@ -123,10 +91,14 @@ public void MapPost_BuildsEndpointWithRouteNameAndOrder() Assert.NotNull(methodMetadata); var method = Assert.Single(methodMetadata!.HttpMethods); Assert.Equal("POST", method); + + var routeEndpointBuilder = GetRouteEndpointBuilder(builder); + Assert.Equal("/ HTTP: POST", routeEndpointBuilder.DisplayName); + Assert.Equal("/", routeEndpointBuilder.RoutePattern.RawText); } [Fact] - public void MapPut_BuildsEndpointWithRouteNameAndOrder() + public void MapPut_BuildsEndpointWithCorrectMethod() { var builder = new DefaultEndpointRouteBuilder(Mock.Of()); _ = builder.MapPut("/", (Action)(() => { })); @@ -139,10 +111,14 @@ public void MapPut_BuildsEndpointWithRouteNameAndOrder() Assert.NotNull(methodMetadata); var method = Assert.Single(methodMetadata!.HttpMethods); Assert.Equal("PUT", method); + + var routeEndpointBuilder = GetRouteEndpointBuilder(builder); + Assert.Equal("/ HTTP: PUT", routeEndpointBuilder.DisplayName); + Assert.Equal("/", routeEndpointBuilder.RoutePattern.RawText); } [Fact] - public void MapDelete_BuildsEndpointWithRouteNameAndOrder() + public void MapDelete_BuildsEndpointWithCorrectMethod() { var builder = new DefaultEndpointRouteBuilder(Mock.Of()); _ = builder.MapDelete("/", (Action)(() => { })); @@ -155,69 +131,22 @@ public void MapDelete_BuildsEndpointWithRouteNameAndOrder() Assert.NotNull(methodMetadata); var method = Assert.Single(methodMetadata!.HttpMethods); Assert.Equal("DELETE", method); - } - - [Theory] - [MemberData(nameof(MapActionMethods))] - public void MapOverloads_RejectActionsWithPatternMetadata(Action mapOverload) - { - [CustomRouteMetadata(Pattern = "/")] - void TestAction() { }; - var builder = new DefaultEndpointRouteBuilder(Mock.Of()); - var ex = Assert.Throws(() => mapOverload(builder, (Action)TestAction)); - Assert.Contains(nameof(IRoutePatternMetadata), ex.Message); + var routeEndpointBuilder = GetRouteEndpointBuilder(builder); + Assert.Equal("/ HTTP: DELETE", routeEndpointBuilder.DisplayName); + Assert.Equal("/", routeEndpointBuilder.RoutePattern.RawText); } - [Theory] - [MemberData(nameof(MapActionMethods))] - public void MapOverloads_RejectActionsWithMethodMetadata(Action mapOverload) + private class HttpMethodAttribute : Attribute, IHttpMethodMetadata { - [CustomRouteMetadata(Methods = new[] { "GET" })] - void TestAction() { }; + public bool AcceptCorsPreflight => false; - var builder = new DefaultEndpointRouteBuilder(Mock.Of()); - var ex = Assert.Throws(() => mapOverload(builder, (Action)TestAction)); - Assert.Contains(nameof(IHttpMethodMetadata), ex.Message); - } + public IReadOnlyList HttpMethods { get; } - public static IEnumerable MapActionMethods => new object[][] - { - new object[] - { - (Action)( - (builder, action) => builder.MapGet("/", action)) - }, - new object[] - { - (Action)( - (builder, action) => builder.MapPost("/", action)) - }, - new object[] + public HttpMethodAttribute(params string[] httpMethods) { - (Action)( - (builder, action) => builder.MapPut("/", action)) - }, - new object[] - { - (Action)( - (builder, action) => builder.MapDelete("/", action)) - }, - new object[] - { - (Action)( - (builder, action) => builder.MapMethods("/", Array.Empty(), action)) - }, - new object[] - { - (Action)( - (builder, action) => builder.Map("/", action)) - }, - new object[] - { - (Action)( - (builder, action) => builder.Map(RoutePatternFactory.Parse("/"), action)) - }, - }; + HttpMethods = httpMethods; + } + } } } diff --git a/src/Http/Routing/test/UnitTests/Builder/MapEndpointEndpointDataSourceBuilderExtensionsTest.cs b/src/Http/Routing/test/UnitTests/Builder/MapEndpointEndpointDataSourceBuilderExtensionsTest.cs index deff542b1f86..9fd992bcd7e3 100644 --- a/src/Http/Routing/test/UnitTests/Builder/MapEndpointEndpointDataSourceBuilderExtensionsTest.cs +++ b/src/Http/Routing/test/UnitTests/Builder/MapEndpointEndpointDataSourceBuilderExtensionsTest.cs @@ -149,10 +149,5 @@ private class Attribute1 : Attribute private class Attribute2 : Attribute { } - - private class Metadata - { - - } } } diff --git a/src/Http/Routing/test/UnitTests/TestObjects/CustomRouteMetadataAttribute.cs b/src/Http/Routing/test/UnitTests/TestObjects/CustomRouteMetadataAttribute.cs deleted file mode 100644 index bf14d2ce7a0b..000000000000 --- a/src/Http/Routing/test/UnitTests/TestObjects/CustomRouteMetadataAttribute.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#nullable enable - -using System; -using System.Collections.Generic; - -namespace Microsoft.AspNetCore.Routing.TestObjects -{ - internal class CustomRouteMetadataAttribute : Attribute, IRoutePatternMetadata, IHttpMethodMetadata, IRouteNameMetadata, IRouteOrderMetadata - { - public string? Pattern { get; set; } - - public string? Name { get; set; } - - public int Order { get; set; } = 0; - - public string[] Methods { get; set; } = Array.Empty(); - - string? IRoutePatternMetadata.RoutePattern => Pattern; - - string? IRouteNameMetadata.RouteName => Name; - - int? IRouteOrderMetadata.RouteOrder => Order; - - IReadOnlyList IHttpMethodMetadata.HttpMethods => Methods; - - bool IHttpMethodMetadata.AcceptCorsPreflight => false; - } -} diff --git a/src/Mvc/Mvc.Core/src/AcceptVerbsAttribute.cs b/src/Mvc/Mvc.Core/src/AcceptVerbsAttribute.cs index 5ba2157094cb..83cb7914e6b1 100644 --- a/src/Mvc/Mvc.Core/src/AcceptVerbsAttribute.cs +++ b/src/Mvc/Mvc.Core/src/AcceptVerbsAttribute.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Mvc.Routing; -using Microsoft.AspNetCore.Routing; namespace Microsoft.AspNetCore.Mvc { @@ -13,7 +12,7 @@ namespace Microsoft.AspNetCore.Mvc /// Specifies what HTTP methods an action supports. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)] - public sealed class AcceptVerbsAttribute : Attribute, IHttpMethodMetadata, IActionHttpMethodProvider, IRouteTemplateProvider + public sealed class AcceptVerbsAttribute : Attribute, IActionHttpMethodProvider, IRouteTemplateProvider { private readonly List _httpMethods; @@ -46,9 +45,6 @@ public AcceptVerbsAttribute(params string[] methods) /// public IEnumerable HttpMethods => _httpMethods; - IReadOnlyList IHttpMethodMetadata.HttpMethods => _httpMethods; - bool IHttpMethodMetadata.AcceptCorsPreflight => false; - /// /// The route template. May be null. /// diff --git a/src/Mvc/Mvc.Core/src/Routing/HttpMethodAttribute.cs b/src/Mvc/Mvc.Core/src/Routing/HttpMethodAttribute.cs index dd0d25b6e4b9..dd5c7ff7df22 100644 --- a/src/Mvc/Mvc.Core/src/Routing/HttpMethodAttribute.cs +++ b/src/Mvc/Mvc.Core/src/Routing/HttpMethodAttribute.cs @@ -7,7 +7,6 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; -using Microsoft.AspNetCore.Routing; namespace Microsoft.AspNetCore.Mvc.Routing { @@ -15,7 +14,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing /// Identifies an action that supports a given set of HTTP methods. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)] - public abstract class HttpMethodAttribute : Attribute, IHttpMethodMetadata, IActionHttpMethodProvider, IRouteTemplateProvider + public abstract class HttpMethodAttribute : Attribute, IActionHttpMethodProvider, IRouteTemplateProvider { private readonly List _httpMethods; @@ -51,9 +50,6 @@ public HttpMethodAttribute(IEnumerable httpMethods, string? template) /// public IEnumerable HttpMethods => _httpMethods; - IReadOnlyList IHttpMethodMetadata.HttpMethods => _httpMethods; - bool IHttpMethodMetadata.AcceptCorsPreflight => false; - /// public string? Template { get; } @@ -75,6 +71,5 @@ public int Order /// [DisallowNull] public string? Name { get; set; } - } } diff --git a/src/Mvc/Mvc.Core/src/Routing/IRouteTemplateProvider.cs b/src/Mvc/Mvc.Core/src/Routing/IRouteTemplateProvider.cs index f15e76abc64c..0934bad99f24 100644 --- a/src/Mvc/Mvc.Core/src/Routing/IRouteTemplateProvider.cs +++ b/src/Mvc/Mvc.Core/src/Routing/IRouteTemplateProvider.cs @@ -3,14 +3,12 @@ #nullable enable -using Microsoft.AspNetCore.Routing; - namespace Microsoft.AspNetCore.Mvc.Routing { /// /// Interface for attributes which can supply a route template for attribute routing. /// - public interface IRouteTemplateProvider : IRoutePatternMetadata, IRouteOrderMetadata, IRouteNameMetadata + public interface IRouteTemplateProvider { /// /// The route template. May be . @@ -30,14 +28,5 @@ public interface IRouteTemplateProvider : IRoutePatternMetadata, IRouteOrderMeta /// of relying on selection of a route based on the given set of route values. /// string? Name { get; } - - /// - string? IRoutePatternMetadata.RoutePattern => Template; - - /// - int? IRouteOrderMetadata.RouteOrder => Order; - - /// - string? IRouteNameMetadata.RouteName => Name; } }