Move EndpointModel and IEndpointConventionBuilder to HTTP abstractions (#4274)
This commit is contained in:
parent
708dc5cb5a
commit
cc899e2be7
|
|
@ -0,0 +1,35 @@
|
|||
// 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.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
/// <summary>
|
||||
/// A base class for building an new <see cref="Endpoint"/>.
|
||||
/// </summary>
|
||||
public abstract class EndpointBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the delegate used to process requests for the endpoint.
|
||||
/// </summary>
|
||||
public RequestDelegate RequestDelegate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the informational display name of this endpoint.
|
||||
/// </summary>
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of metadata associated with this endpoint.
|
||||
/// </summary>
|
||||
public IList<object> Metadata { get; } = new List<object>();
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of <see cref="Endpoint"/> from the <see cref="EndpointBuilder"/>.
|
||||
/// </summary>
|
||||
/// <returns>The created <see cref="Endpoint"/>.</returns>
|
||||
public abstract Endpoint Build();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
/// <summary>
|
||||
/// Builds conventions that will be used for customization of <see cref="EndpointBuilder"/> instances.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This interface is used at application startup to customize endpoints for the application.
|
||||
/// </remarks>
|
||||
public interface IEndpointConventionBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the specified convention to the builder. Conventions are used to customize <see cref="EndpointBuilder"/> instances.
|
||||
/// </summary>
|
||||
/// <param name="convention">The convention to add to the builder.</param>
|
||||
void Add(Action<EndpointBuilder> convention);
|
||||
}
|
||||
}
|
||||
|
|
@ -109,6 +109,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server
|
|||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{DC519C5E-CA6E-48CA-BF35-B46305B83013}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IISIntegration", "..\Servers\IIS\src\Microsoft.AspNetCore.Server.IISIntegration\Microsoft.AspNetCore.Server.IISIntegration.csproj", "{DF1EF1B6-9795-4957-979C-F62F58F91743}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.HttpOverrides", "..\Middleware\HttpOverrides\src\Microsoft.AspNetCore.HttpOverrides.csproj", "{611794D2-EF3A-422A-A077-23E61C7ADE49}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -575,6 +579,30 @@ Global
|
|||
{1909E2E3-D435-47AA-B2AB-D6EC58BEDC0D}.Release|x64.Build.0 = Release|Any CPU
|
||||
{1909E2E3-D435-47AA-B2AB-D6EC58BEDC0D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{1909E2E3-D435-47AA-B2AB-D6EC58BEDC0D}.Release|x86.Build.0 = Release|Any CPU
|
||||
{DF1EF1B6-9795-4957-979C-F62F58F91743}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DF1EF1B6-9795-4957-979C-F62F58F91743}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DF1EF1B6-9795-4957-979C-F62F58F91743}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{DF1EF1B6-9795-4957-979C-F62F58F91743}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{DF1EF1B6-9795-4957-979C-F62F58F91743}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{DF1EF1B6-9795-4957-979C-F62F58F91743}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{DF1EF1B6-9795-4957-979C-F62F58F91743}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DF1EF1B6-9795-4957-979C-F62F58F91743}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DF1EF1B6-9795-4957-979C-F62F58F91743}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{DF1EF1B6-9795-4957-979C-F62F58F91743}.Release|x64.Build.0 = Release|Any CPU
|
||||
{DF1EF1B6-9795-4957-979C-F62F58F91743}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{DF1EF1B6-9795-4957-979C-F62F58F91743}.Release|x86.Build.0 = Release|Any CPU
|
||||
{611794D2-EF3A-422A-A077-23E61C7ADE49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{611794D2-EF3A-422A-A077-23E61C7ADE49}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{611794D2-EF3A-422A-A077-23E61C7ADE49}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{611794D2-EF3A-422A-A077-23E61C7ADE49}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{611794D2-EF3A-422A-A077-23E61C7ADE49}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{611794D2-EF3A-422A-A077-23E61C7ADE49}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{611794D2-EF3A-422A-A077-23E61C7ADE49}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{611794D2-EF3A-422A-A077-23E61C7ADE49}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{611794D2-EF3A-422A-A077-23E61C7ADE49}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{611794D2-EF3A-422A-A077-23E61C7ADE49}.Release|x64.Build.0 = Release|Any CPU
|
||||
{611794D2-EF3A-422A-A077-23E61C7ADE49}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{611794D2-EF3A-422A-A077-23E61C7ADE49}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -621,6 +649,8 @@ Global
|
|||
{EEA036BB-E6B8-4D01-907B-D4B34B4368DB} = {793FFE24-138A-4C3D-81AB-18D625E36230}
|
||||
{1909E2E3-D435-47AA-B2AB-D6EC58BEDC0D} = {793FFE24-138A-4C3D-81AB-18D625E36230}
|
||||
{DC519C5E-CA6E-48CA-BF35-B46305B83013} = {14A7B3DE-46C8-4245-B0BD-9AFF3795C163}
|
||||
{DF1EF1B6-9795-4957-979C-F62F58F91743} = {793FFE24-138A-4C3D-81AB-18D625E36230}
|
||||
{611794D2-EF3A-422A-A077-23E61C7ADE49} = {793FFE24-138A-4C3D-81AB-18D625E36230}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {85B5E151-2E9D-419C-83DD-0DDCF446C83A}
|
||||
|
|
|
|||
|
|
@ -182,16 +182,16 @@ namespace Microsoft.AspNetCore.Builder
|
|||
|
||||
const int defaultOrder = 0;
|
||||
|
||||
var routeEndpointModel = new RouteEndpointModel(
|
||||
var routeEndpointBuilder = new RouteEndpointBuilder(
|
||||
requestDelegate,
|
||||
pattern,
|
||||
defaultOrder);
|
||||
routeEndpointModel.DisplayName = displayName;
|
||||
routeEndpointBuilder.DisplayName = displayName;
|
||||
if (metadata != null)
|
||||
{
|
||||
foreach (var item in metadata)
|
||||
{
|
||||
routeEndpointModel.Metadata.Add(item);
|
||||
routeEndpointBuilder.Metadata.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -203,7 +203,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
builder.DataSources.Add(modelEndpointDataSource);
|
||||
}
|
||||
|
||||
return modelEndpointDataSource.AddEndpointModel(routeEndpointModel);
|
||||
return modelEndpointDataSource.AddEndpointBuilder(routeEndpointBuilder);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Routing
|
||||
{
|
||||
public abstract class EndpointModel
|
||||
{
|
||||
public RequestDelegate RequestDelegate { get; set; }
|
||||
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
public IList<object> Metadata { get; } = new List<object>();
|
||||
|
||||
public abstract Endpoint Build();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +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.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNetCore.Routing
|
||||
{
|
||||
public interface IEndpointConventionBuilder
|
||||
{
|
||||
void Apply(Action<EndpointModel> convention);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
|
@ -19,9 +20,9 @@ namespace Microsoft.AspNetCore.Routing
|
|||
_endpointConventionBuilders = new List<EndpointConventionBuilder>();
|
||||
}
|
||||
|
||||
public IEndpointConventionBuilder AddEndpointModel(EndpointModel endpointModel)
|
||||
public IEndpointConventionBuilder AddEndpointBuilder(EndpointBuilder endpointBuilder)
|
||||
{
|
||||
var builder = new EndpointConventionBuilder(endpointModel);
|
||||
var builder = new EndpointConventionBuilder(endpointBuilder);
|
||||
_endpointConventionBuilders.Add(builder);
|
||||
|
||||
return builder;
|
||||
|
|
@ -35,21 +36,21 @@ namespace Microsoft.AspNetCore.Routing
|
|||
public override IReadOnlyList<Endpoint> Endpoints => _endpointConventionBuilders.Select(e => e.Build()).ToArray();
|
||||
|
||||
// for testing
|
||||
internal IEnumerable<EndpointModel> EndpointModels => _endpointConventionBuilders.Select(b => b.EndpointModel);
|
||||
internal IEnumerable<EndpointBuilder> EndpointBuilders => _endpointConventionBuilders.Select(b => b.EndpointBuilder);
|
||||
|
||||
private class EndpointConventionBuilder : IEndpointConventionBuilder
|
||||
{
|
||||
internal EndpointModel EndpointModel { get; }
|
||||
internal EndpointBuilder EndpointBuilder { get; }
|
||||
|
||||
private readonly List<Action<EndpointModel>> _conventions;
|
||||
private readonly List<Action<EndpointBuilder>> _conventions;
|
||||
|
||||
public EndpointConventionBuilder(EndpointModel endpointModel)
|
||||
public EndpointConventionBuilder(EndpointBuilder endpointBuilder)
|
||||
{
|
||||
EndpointModel = endpointModel;
|
||||
_conventions = new List<Action<EndpointModel>>();
|
||||
EndpointBuilder = endpointBuilder;
|
||||
_conventions = new List<Action<EndpointBuilder>>();
|
||||
}
|
||||
|
||||
public void Apply(Action<EndpointModel> convention)
|
||||
public void Add(Action<EndpointBuilder> convention)
|
||||
{
|
||||
_conventions.Add(convention);
|
||||
}
|
||||
|
|
@ -58,11 +59,11 @@ namespace Microsoft.AspNetCore.Routing
|
|||
{
|
||||
foreach (var convention in _conventions)
|
||||
{
|
||||
convention(EndpointModel);
|
||||
convention(EndpointBuilder);
|
||||
}
|
||||
|
||||
return EndpointModel.Build();
|
||||
return EndpointBuilder.Build();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// 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.
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing.Patterns;
|
||||
|
||||
namespace Microsoft.AspNetCore.Routing
|
||||
{
|
||||
public sealed class RouteEndpointModel : EndpointModel
|
||||
public sealed class RouteEndpointBuilder : EndpointBuilder
|
||||
{
|
||||
public RoutePattern RoutePattern { get; set; }
|
||||
|
||||
public int Order { get; set; }
|
||||
|
||||
public RouteEndpointModel(
|
||||
public RouteEndpointBuilder(
|
||||
RequestDelegate requestDelegate,
|
||||
RoutePattern routePattern,
|
||||
int order)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// 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.
|
||||
|
||||
using System;
|
||||
|
|
@ -19,9 +19,9 @@ namespace Microsoft.AspNetCore.Builder
|
|||
return Assert.IsType<ModelEndpointDataSource>(Assert.Single(endpointRouteBuilder.DataSources));
|
||||
}
|
||||
|
||||
private RouteEndpointModel GetRouteEndpointBuilder(IEndpointRouteBuilder endpointRouteBuilder)
|
||||
private RouteEndpointBuilder GetRouteEndpointBuilder(IEndpointRouteBuilder endpointRouteBuilder)
|
||||
{
|
||||
return Assert.IsType<RouteEndpointModel>(Assert.Single(GetBuilderEndpointDataSource(endpointRouteBuilder).EndpointModels));
|
||||
return Assert.IsType<RouteEndpointBuilder>(Assert.Single(GetBuilderEndpointDataSource(endpointRouteBuilder).EndpointBuilders));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// 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.
|
||||
|
||||
using System;
|
||||
|
|
@ -10,7 +10,7 @@ using Xunit;
|
|||
|
||||
namespace Microsoft.AspNetCore.Routing
|
||||
{
|
||||
public class RouteEndpointModelTest
|
||||
public class RouteEndpointBuilderTest
|
||||
{
|
||||
[Fact]
|
||||
public void Build_AllValuesSet_EndpointCreated()
|
||||
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Routing
|
|||
var metadata = new object();
|
||||
RequestDelegate requestDelegate = (d) => null;
|
||||
|
||||
var builder = new RouteEndpointModel(requestDelegate, RoutePatternFactory.Parse("/"), defaultOrder)
|
||||
var builder = new RouteEndpointBuilder(requestDelegate, RoutePatternFactory.Parse("/"), defaultOrder)
|
||||
{
|
||||
DisplayName = "Display name!",
|
||||
Metadata = { metadata }
|
||||
|
|
@ -1,25 +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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using RoutingSample.Web.AuthorizationMiddleware;
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
public static class AuthorizationAppBuilderExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseAuthorization(this IApplicationBuilder app)
|
||||
{
|
||||
if (app == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(app));
|
||||
}
|
||||
|
||||
return app.UseMiddleware<AuthorizationMiddleware>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RoutingSample.Web.AuthorizationMiddleware
|
||||
{
|
||||
public class AuthorizationMetadata
|
||||
{
|
||||
public AuthorizationMetadata(IEnumerable<string> roles)
|
||||
{
|
||||
if (roles == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(roles));
|
||||
}
|
||||
|
||||
Roles = roles.ToArray();
|
||||
}
|
||||
|
||||
public IReadOnlyList<string> Roles { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,59 +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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace RoutingSample.Web.AuthorizationMiddleware
|
||||
{
|
||||
public class AuthorizationMiddleware
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly RequestDelegate _next;
|
||||
|
||||
public AuthorizationMiddleware(ILogger<AuthorizationMiddleware> logger, RequestDelegate next)
|
||||
{
|
||||
if (logger == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
if (next == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(next));
|
||||
}
|
||||
|
||||
_logger = logger;
|
||||
_next = next;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext httpContext)
|
||||
{
|
||||
var endpoint = httpContext.Features.Get<IEndpointFeature>()?.Endpoint;
|
||||
if (endpoint != null)
|
||||
{
|
||||
var metadata = endpoint.Metadata.GetMetadata<AuthorizationMetadata>();
|
||||
// Only run authorization if endpoint has metadata
|
||||
if (metadata != null)
|
||||
{
|
||||
if (!httpContext.Request.Query.TryGetValue("x-role", out var role) ||
|
||||
!metadata.Roles.Contains(role.ToString()))
|
||||
{
|
||||
httpContext.Response.StatusCode = 401;
|
||||
httpContext.Response.ContentType = "text/plain";
|
||||
await httpContext.Response.WriteAsync($"Unauthorized access to '{endpoint.DisplayName}'.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await _next(httpContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +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.
|
||||
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using RoutingSample.Web.AuthorizationMiddleware;
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
public static class EndpointConventionBuilderExtensions
|
||||
{
|
||||
public static IEndpointConventionBuilder RequireAuthorization(this IEndpointConventionBuilder builder, params string[] roles)
|
||||
{
|
||||
builder.Apply(endpointBuilder => endpointBuilder.Metadata.Add(new AuthorizationMetadata(roles)));
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Routing.Patterns;
|
||||
|
|
@ -16,7 +17,7 @@ namespace RoutingSandbox.Framework
|
|||
internal class FrameworkEndpointDataSource : EndpointDataSource, IEndpointConventionBuilder
|
||||
{
|
||||
private readonly RoutePatternTransformer _routePatternTransformer;
|
||||
private readonly List<Action<EndpointModel>> _conventions;
|
||||
private readonly List<Action<EndpointBuilder>> _conventions;
|
||||
|
||||
public List<RoutePattern> Patterns { get; }
|
||||
public List<HubMethod> HubMethods { get; }
|
||||
|
|
@ -26,7 +27,7 @@ namespace RoutingSandbox.Framework
|
|||
public FrameworkEndpointDataSource(RoutePatternTransformer routePatternTransformer)
|
||||
{
|
||||
_routePatternTransformer = routePatternTransformer;
|
||||
_conventions = new List<Action<EndpointModel>>();
|
||||
_conventions = new List<Action<EndpointBuilder>>();
|
||||
|
||||
Patterns = new List<RoutePattern>();
|
||||
HubMethods = new List<HubMethod>();
|
||||
|
|
@ -62,18 +63,18 @@ namespace RoutingSandbox.Framework
|
|||
continue;
|
||||
}
|
||||
|
||||
var endpointModel = new RouteEndpointModel(
|
||||
var endpointBuilder = new RouteEndpointBuilder(
|
||||
hubMethod.RequestDelegate,
|
||||
resolvedPattern,
|
||||
order++);
|
||||
endpointModel.DisplayName = $"{hubMethod.Hub}.{hubMethod.Method}";
|
||||
endpointBuilder.DisplayName = $"{hubMethod.Hub}.{hubMethod.Method}";
|
||||
|
||||
foreach (var convention in _conventions)
|
||||
{
|
||||
convention(endpointModel);
|
||||
convention(endpointBuilder);
|
||||
}
|
||||
|
||||
endpoints.Add(endpointModel.Build());
|
||||
endpoints.Add(endpointBuilder.Build());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -85,7 +86,7 @@ namespace RoutingSandbox.Framework
|
|||
return NullChangeToken.Singleton;
|
||||
}
|
||||
|
||||
public void Apply(Action<EndpointModel> convention)
|
||||
public void Add(Action<EndpointBuilder> convention)
|
||||
{
|
||||
_conventions.Add(convention);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Routing.Patterns;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// 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.
|
||||
|
||||
using System;
|
||||
|
|
|
|||
|
|
@ -35,9 +35,6 @@ namespace RoutingSandbox
|
|||
{
|
||||
builder.MapHello("/helloworld", "World");
|
||||
|
||||
builder.MapHello("/helloworld-secret", "Secret World")
|
||||
.RequireAuthorization("swordfish");
|
||||
|
||||
builder.MapGet(
|
||||
"/",
|
||||
(httpContext) =>
|
||||
|
|
@ -94,10 +91,6 @@ namespace RoutingSandbox
|
|||
});
|
||||
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// 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.
|
||||
|
||||
using System;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.Apply(endpointBuilder =>
|
||||
builder.Add(endpointBuilder =>
|
||||
{
|
||||
endpointBuilder.Metadata.Add(new EnableCorsAttribute(policyName));
|
||||
});
|
||||
|
|
@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
configurePolicy(policyBuilder);
|
||||
var policy = policyBuilder.Build();
|
||||
|
||||
builder.Apply(endpointBuilder =>
|
||||
builder.Add(endpointBuilder =>
|
||||
{
|
||||
endpointBuilder.Metadata.Add(new CorsPolicyMetadata(policy));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure
|
|||
// Assert
|
||||
var addCorsPolicy = Assert.Single(testConventionBuilder.Conventions);
|
||||
|
||||
var endpointModel = new TestEndpointModel();
|
||||
var endpointModel = new TestEndpointBuilder();
|
||||
addCorsPolicy(endpointModel);
|
||||
var endpoint = endpointModel.Build();
|
||||
|
||||
|
|
@ -45,9 +45,9 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure
|
|||
// Assert
|
||||
var addCorsPolicy = Assert.Single(testConventionBuilder.Conventions);
|
||||
|
||||
var endpointModel = new TestEndpointModel();
|
||||
addCorsPolicy(endpointModel);
|
||||
var endpoint = endpointModel.Build();
|
||||
var endpointBuilder = new TestEndpointBuilder();
|
||||
addCorsPolicy(endpointBuilder);
|
||||
var endpoint = endpointBuilder.Build();
|
||||
|
||||
var metadata = endpoint.Metadata.GetMetadata<ICorsPolicyMetadata>();
|
||||
Assert.NotNull(metadata);
|
||||
|
|
@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure
|
|||
Assert.True(metadata.Policy.AllowAnyOrigin);
|
||||
}
|
||||
|
||||
private class TestEndpointModel : EndpointModel
|
||||
private class TestEndpointBuilder : EndpointBuilder
|
||||
{
|
||||
public override Endpoint Build()
|
||||
{
|
||||
|
|
@ -65,9 +65,9 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure
|
|||
|
||||
private class TestEndpointConventionBuilder : IEndpointConventionBuilder
|
||||
{
|
||||
public IList<Action<EndpointModel>> Conventions { get; } = new List<Action<EndpointModel>>();
|
||||
public IList<Action<EndpointBuilder>> Conventions { get; } = new List<Action<EndpointBuilder>>();
|
||||
|
||||
public void Apply(Action<EndpointModel> convention)
|
||||
public void Add(Action<EndpointBuilder> convention)
|
||||
{
|
||||
Conventions.Add(convention);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,6 +251,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleDestination", "CORS\s
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleOrigin", "CORS\samples\SampleOrigin\SampleOrigin.csproj", "{198FFE3B-0346-4856-A6C9-8752D51C4EB3}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IISIntegration", "..\Servers\IIS\src\Microsoft.AspNetCore.Server.IISIntegration\Microsoft.AspNetCore.Server.IISIntegration.csproj", "{F6206539-038C-410A-86F7-3919D49A28C7}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -1377,6 +1379,18 @@ Global
|
|||
{198FFE3B-0346-4856-A6C9-8752D51C4EB3}.Release|x64.Build.0 = Release|Any CPU
|
||||
{198FFE3B-0346-4856-A6C9-8752D51C4EB3}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{198FFE3B-0346-4856-A6C9-8752D51C4EB3}.Release|x86.Build.0 = Release|Any CPU
|
||||
{F6206539-038C-410A-86F7-3919D49A28C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F6206539-038C-410A-86F7-3919D49A28C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F6206539-038C-410A-86F7-3919D49A28C7}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{F6206539-038C-410A-86F7-3919D49A28C7}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{F6206539-038C-410A-86F7-3919D49A28C7}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F6206539-038C-410A-86F7-3919D49A28C7}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{F6206539-038C-410A-86F7-3919D49A28C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F6206539-038C-410A-86F7-3919D49A28C7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F6206539-038C-410A-86F7-3919D49A28C7}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{F6206539-038C-410A-86F7-3919D49A28C7}.Release|x64.Build.0 = Release|Any CPU
|
||||
{F6206539-038C-410A-86F7-3919D49A28C7}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F6206539-038C-410A-86F7-3919D49A28C7}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -1486,6 +1500,7 @@ Global
|
|||
{E025D98E-BD85-474A-98A9-E7F44F392F8E} = {4967DE1B-FEC2-4C2B-8F7F-6262D67C9434}
|
||||
{52CDD110-77DD-4C4D-8C72-4570F6EF20DD} = {7CF63806-4C4F-4C48-8922-A75113975308}
|
||||
{198FFE3B-0346-4856-A6C9-8752D51C4EB3} = {7CF63806-4C4F-4C48-8922-A75113975308}
|
||||
{F6206539-038C-410A-86F7-3919D49A28C7} = {ACA6DDB9-7592-47CE-A740-D15BF307E9E0}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {83786312-A93B-4BB4-AB06-7C6913A59AFA}
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ namespace Microsoft.AspNetCore.Builder
|
|||
{
|
||||
public DefaultEndpointConventionBuilder()
|
||||
{
|
||||
Conventions = new List<Action<EndpointModel>>();
|
||||
Conventions = new List<Action<EndpointBuilder>>();
|
||||
}
|
||||
|
||||
public List<Action<EndpointModel>> Conventions { get; }
|
||||
public List<Action<EndpointBuilder>> Conventions { get; }
|
||||
|
||||
public void Apply(Action<EndpointModel> convention)
|
||||
public void Add(Action<EndpointBuilder> convention)
|
||||
{
|
||||
Conventions.Add(convention);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
|||
RouteValueDictionary dataTokens,
|
||||
bool suppressLinkGeneration,
|
||||
bool suppressPathMatching,
|
||||
List<Action<EndpointModel>> conventions)
|
||||
List<Action<EndpointBuilder>> conventions)
|
||||
{
|
||||
RequestDelegate requestDelegate = (context) =>
|
||||
{
|
||||
|
|
@ -281,17 +281,16 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
|||
return invoker.InvokeAsync();
|
||||
};
|
||||
|
||||
var model = new RouteEndpointModel(requestDelegate, routePattern, order);
|
||||
|
||||
var endpointBuilder = new RouteEndpointBuilder(requestDelegate, routePattern, order);
|
||||
AddEndpointMetadata(
|
||||
model.Metadata,
|
||||
endpointBuilder.Metadata,
|
||||
action,
|
||||
routeName,
|
||||
dataTokens,
|
||||
suppressLinkGeneration,
|
||||
suppressPathMatching);
|
||||
|
||||
model.DisplayName = action.DisplayName;
|
||||
endpointBuilder.DisplayName = action.DisplayName;
|
||||
|
||||
// REVIEW: When should conventions be run
|
||||
// Metadata should have lower precedence that data source metadata
|
||||
|
|
@ -299,11 +298,11 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
|||
{
|
||||
foreach (var convention in conventions)
|
||||
{
|
||||
convention(model);
|
||||
convention(endpointBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
return (RouteEndpoint)model.Build();
|
||||
return (RouteEndpoint)endpointBuilder.Build();
|
||||
}
|
||||
|
||||
private static void AddEndpointMetadata(
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// 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.
|
||||
|
||||
using System;
|
||||
|
|
@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
throw new ArgumentNullException(nameof(authorizeData));
|
||||
}
|
||||
|
||||
builder.Apply(endpointBuilder =>
|
||||
builder.Add(endpointBuilder =>
|
||||
{
|
||||
foreach (var data in authorizeData)
|
||||
{
|
||||
|
|
@ -47,4 +47,4 @@ namespace Microsoft.AspNetCore.Builder
|
|||
return builder.RequireAuthorization(policyNames.Select(n => new AuthorizeAttribute(n)).ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// 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.
|
||||
|
||||
using System;
|
||||
|
|
@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Authorization.Test
|
|||
// Assert
|
||||
var convention = Assert.Single(builder.Conventions);
|
||||
|
||||
var endpointModel = new RouteEndpointModel((context) => Task.CompletedTask, RoutePatternFactory.Parse("/"), 0);
|
||||
var endpointModel = new RouteEndpointBuilder((context) => Task.CompletedTask, RoutePatternFactory.Parse("/"), 0);
|
||||
convention(endpointModel);
|
||||
|
||||
Assert.Equal(metadata, Assert.Single(endpointModel.Metadata));
|
||||
|
|
@ -44,7 +44,7 @@ namespace Microsoft.AspNetCore.Authorization.Test
|
|||
// Assert
|
||||
var convention = Assert.Single(builder.Conventions);
|
||||
|
||||
var endpointModel = new RouteEndpointModel((context) => Task.CompletedTask, RoutePatternFactory.Parse("/"), 0);
|
||||
var endpointModel = new RouteEndpointBuilder((context) => Task.CompletedTask, RoutePatternFactory.Parse("/"), 0);
|
||||
convention(endpointModel);
|
||||
|
||||
Assert.Equal("policy", Assert.IsAssignableFrom<IAuthorizeData>(Assert.Single(endpointModel.Metadata)).Policy);
|
||||
|
|
@ -52,9 +52,9 @@ namespace Microsoft.AspNetCore.Authorization.Test
|
|||
|
||||
private class TestEndpointConventionBuilder : IEndpointConventionBuilder
|
||||
{
|
||||
public IList<Action<EndpointModel>> Conventions { get; } = new List<Action<EndpointModel>>();
|
||||
public IList<Action<EndpointBuilder>> Conventions { get; } = new List<Action<EndpointBuilder>>();
|
||||
|
||||
public void Apply(Action<EndpointModel> convention)
|
||||
public void Add(Action<EndpointBuilder> convention)
|
||||
{
|
||||
Conventions.Add(convention);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue