Move EndpointModel and IEndpointConventionBuilder to HTTP abstractions (#4274)

This commit is contained in:
James Newton-King 2018-12-17 18:38:49 +13:00 committed by GitHub
parent 708dc5cb5a
commit cc899e2be7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 167 additions and 226 deletions

View File

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

View File

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

View File

@ -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}

View File

@ -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
}

View File

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

View File

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

View File

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

View File

@ -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)

View File

@ -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]

View File

@ -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 }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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;

View File

@ -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;

View File

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

View File

@ -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;

View File

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

View File

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

View File

@ -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}

View File

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

View File

@ -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(

View File

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

View File

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