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

Remove MapAction overload #30563

Merged
merged 2 commits into from
Mar 2, 2021
Merged
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
3 changes: 1 addition & 2 deletions src/Http/Routing/samples/MapActionSample/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Todo, JsonResult>)EchoTodo);
endpoints.MapPost("/EchoTodo", (Func<Todo, JsonResult>)EchoTodo);

endpoints.MapPost("/EchoTodoProto", async httpContext =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,68 +22,6 @@ public static class MapActionEndpointRouteBuilderExtensions
private static readonly string[] PutVerb = new[] { "PUT" };
private static readonly string[] DeleteVerb = new[] { "DELETE" };

/// <summary>
/// Adds a <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that matches the pattern specified via attributes.
/// </summary>
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
/// <param name="action">The delegate executed when the endpoint is matched.</param>
/// <returns>An <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
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<IRoutePatternMetadata>();
var conventionBuilders = new List<IEndpointConventionBuilder>();

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);
}

/// <summary>
/// Adds a <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that matches HTTP GET requests
/// for the specified pattern.
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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<ModelEndpointDataSource>().FirstOrDefault();
if (dataSource is null)
{
Expand Down
19 changes: 0 additions & 19 deletions src/Http/Routing/src/IRouteOrderMetadata.cs

This file was deleted.

16 changes: 0 additions & 16 deletions src/Http/Routing/src/IRoutePatternMetadata.cs

This file was deleted.

5 changes: 0 additions & 5 deletions src/Http/Routing/src/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,10 @@ Microsoft.AspNetCore.Routing.DataTokensMetadata.DataTokens.get -> System.Collect
Microsoft.AspNetCore.Routing.DataTokensMetadata.DataTokensMetadata(System.Collections.Generic.IReadOnlyDictionary<string!, object?>! dataTokens) -> void
Microsoft.AspNetCore.Routing.IDataTokensMetadata.DataTokens.get -> System.Collections.Generic.IReadOnlyDictionary<string!, object?>!
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<string!>! httpMethods, System.Delegate! action) -> Microsoft.AspNetCore.Builder.MapActionEndpointConventionBuilder!
Expand Down
42 changes: 0 additions & 42 deletions src/Http/Routing/test/FunctionalTests/MapActionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<int, Todo, Todo>)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<Todo>();

Assert.NotNull(echoedTodo);
Assert.Equal(todo.Name, echoedTodo?.Name);
Assert.Equal(42, echoedTodo?.Id);
}

[Fact]
public async Task MapPost_FromBodyWorksWithJsonPayload()
{
Expand Down
Loading