Merge branch 'master' into merge/release/2.2-to-master
This commit is contained in:
commit
104f9c3517
|
|
@ -7,7 +7,7 @@ resources:
|
|||
- repository: buildtools
|
||||
type: git
|
||||
name: aspnet-BuildTools
|
||||
ref: refs/heads/release/2.2
|
||||
ref: refs/heads/master
|
||||
|
||||
phases:
|
||||
- template: .vsts-pipelines/templates/project-ci.yml@buildtools
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ resources:
|
|||
type: github
|
||||
endpoint: DotNet-Bot GitHub Connection
|
||||
name: aspnet/BuildTools
|
||||
ref: refs/heads/release/2.2
|
||||
ref: refs/heads/master
|
||||
|
||||
phases:
|
||||
- template: .vsts-pipelines/templates/project-ci.yml@buildtools
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Internal;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Routing.Matching;
|
||||
using Microsoft.AspNetCore.Routing.Patterns;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
},
|
||||
"Source": {
|
||||
"Repository": "https://github.com/aspnet/routing.git",
|
||||
"BranchOrCommit": "release/2.2",
|
||||
"BranchOrCommit": "master",
|
||||
"Project": "benchmarkapps/Benchmarks/Benchmarks.csproj"
|
||||
},
|
||||
"Port": 8080
|
||||
|
|
|
|||
|
|
@ -4,33 +4,33 @@
|
|||
</PropertyGroup>
|
||||
<PropertyGroup Label="Package Versions">
|
||||
<BenchmarkDotNetPackageVersion>0.10.13</BenchmarkDotNetPackageVersion>
|
||||
<InternalAspNetCoreSdkPackageVersion>2.2.0-preview1-20180807.2</InternalAspNetCoreSdkPackageVersion>
|
||||
<MicrosoftAspNetCoreAppPackageVersion>2.2.0-preview1-34967</MicrosoftAspNetCoreAppPackageVersion>
|
||||
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>2.2.0-preview1-34967</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>2.2.0-preview1-34967</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
|
||||
<MicrosoftAspNetCoreHostingPackageVersion>2.2.0-preview1-34967</MicrosoftAspNetCoreHostingPackageVersion>
|
||||
<MicrosoftAspNetCoreHttpAbstractionsPackageVersion>2.2.0-preview1-34967</MicrosoftAspNetCoreHttpAbstractionsPackageVersion>
|
||||
<MicrosoftAspNetCoreHttpExtensionsPackageVersion>2.2.0-preview1-34967</MicrosoftAspNetCoreHttpExtensionsPackageVersion>
|
||||
<MicrosoftAspNetCoreHttpPackageVersion>2.2.0-preview1-34967</MicrosoftAspNetCoreHttpPackageVersion>
|
||||
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>2.2.0-preview1-34967</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
|
||||
<MicrosoftAspNetCoreServerKestrelPackageVersion>2.2.0-preview1-34967</MicrosoftAspNetCoreServerKestrelPackageVersion>
|
||||
<MicrosoftAspNetCoreTestHostPackageVersion>2.2.0-preview1-34967</MicrosoftAspNetCoreTestHostPackageVersion>
|
||||
<MicrosoftAspNetCoreTestingPackageVersion>2.2.0-preview1-34967</MicrosoftAspNetCoreTestingPackageVersion>
|
||||
<MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>2.2.0-preview1-34967</MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>2.2.0-preview1-34967</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
|
||||
<MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>2.2.0-preview1-34967</MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationPackageVersion>2.2.0-preview1-34967</MicrosoftExtensionsConfigurationPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>2.2.0-preview1-34967</MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionPackageVersion>2.2.0-preview1-34967</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
||||
<MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>2.2.0-preview1-34967</MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>
|
||||
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>2.2.0-preview1-34967</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsLoggingConsolePackageVersion>2.2.0-preview1-34967</MicrosoftExtensionsLoggingConsolePackageVersion>
|
||||
<MicrosoftExtensionsLoggingPackageVersion>2.2.0-preview1-34967</MicrosoftExtensionsLoggingPackageVersion>
|
||||
<MicrosoftExtensionsLoggingTestingPackageVersion>2.2.0-preview1-34967</MicrosoftExtensionsLoggingTestingPackageVersion>
|
||||
<MicrosoftExtensionsObjectPoolPackageVersion>2.2.0-preview1-34967</MicrosoftExtensionsObjectPoolPackageVersion>
|
||||
<MicrosoftExtensionsOptionsPackageVersion>2.2.0-preview1-34967</MicrosoftExtensionsOptionsPackageVersion>
|
||||
<MicrosoftExtensionsPropertyHelperSourcesPackageVersion>2.2.0-preview1-34967</MicrosoftExtensionsPropertyHelperSourcesPackageVersion>
|
||||
<MicrosoftExtensionsWebEncodersPackageVersion>2.2.0-preview1-34967</MicrosoftExtensionsWebEncodersPackageVersion>
|
||||
<InternalAspNetCoreSdkPackageVersion>3.0.0-alpha1-20180810.1</InternalAspNetCoreSdkPackageVersion>
|
||||
<MicrosoftAspNetCoreAppPackageVersion>3.0.0-alpha1-10275</MicrosoftAspNetCoreAppPackageVersion>
|
||||
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>3.0.0-alpha1-10275</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>3.0.0-alpha1-10275</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
|
||||
<MicrosoftAspNetCoreHostingPackageVersion>3.0.0-alpha1-10275</MicrosoftAspNetCoreHostingPackageVersion>
|
||||
<MicrosoftAspNetCoreHttpAbstractionsPackageVersion>3.0.0-alpha1-10275</MicrosoftAspNetCoreHttpAbstractionsPackageVersion>
|
||||
<MicrosoftAspNetCoreHttpExtensionsPackageVersion>3.0.0-alpha1-10275</MicrosoftAspNetCoreHttpExtensionsPackageVersion>
|
||||
<MicrosoftAspNetCoreHttpPackageVersion>3.0.0-alpha1-10275</MicrosoftAspNetCoreHttpPackageVersion>
|
||||
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>3.0.0-alpha1-10275</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
|
||||
<MicrosoftAspNetCoreServerKestrelPackageVersion>3.0.0-alpha1-10275</MicrosoftAspNetCoreServerKestrelPackageVersion>
|
||||
<MicrosoftAspNetCoreTestHostPackageVersion>3.0.0-alpha1-10275</MicrosoftAspNetCoreTestHostPackageVersion>
|
||||
<MicrosoftAspNetCoreTestingPackageVersion>3.0.0-alpha1-10275</MicrosoftAspNetCoreTestingPackageVersion>
|
||||
<MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>3.0.0-alpha1-10275</MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>3.0.0-alpha1-10275</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
|
||||
<MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>3.0.0-alpha1-10275</MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationPackageVersion>3.0.0-alpha1-10275</MicrosoftExtensionsConfigurationPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>3.0.0-alpha1-10275</MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionPackageVersion>3.0.0-alpha1-10275</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
||||
<MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>3.0.0-alpha1-10275</MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>
|
||||
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>3.0.0-alpha1-10275</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsLoggingConsolePackageVersion>3.0.0-alpha1-10275</MicrosoftExtensionsLoggingConsolePackageVersion>
|
||||
<MicrosoftExtensionsLoggingPackageVersion>3.0.0-alpha1-10275</MicrosoftExtensionsLoggingPackageVersion>
|
||||
<MicrosoftExtensionsLoggingTestingPackageVersion>3.0.0-alpha1-10275</MicrosoftExtensionsLoggingTestingPackageVersion>
|
||||
<MicrosoftExtensionsObjectPoolPackageVersion>3.0.0-alpha1-10275</MicrosoftExtensionsObjectPoolPackageVersion>
|
||||
<MicrosoftExtensionsOptionsPackageVersion>3.0.0-alpha1-10275</MicrosoftExtensionsOptionsPackageVersion>
|
||||
<MicrosoftExtensionsPropertyHelperSourcesPackageVersion>3.0.0-alpha1-10275</MicrosoftExtensionsPropertyHelperSourcesPackageVersion>
|
||||
<MicrosoftExtensionsWebEncodersPackageVersion>3.0.0-alpha1-10275</MicrosoftExtensionsWebEncodersPackageVersion>
|
||||
<MicrosoftNETCoreApp20PackageVersion>2.0.9</MicrosoftNETCoreApp20PackageVersion>
|
||||
<MicrosoftNETCoreApp21PackageVersion>2.1.2</MicrosoftNETCoreApp21PackageVersion>
|
||||
<MicrosoftNETCoreApp22PackageVersion>2.2.0-preview1-26618-02</MicrosoftNETCoreApp22PackageVersion>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
<PropertyGroup>
|
||||
<!-- These properties are use by the automation that updates dependencies.props -->
|
||||
<LineupPackageId>Internal.AspNetCore.Universe.Lineup</LineupPackageId>
|
||||
<LineupPackageVersion>2.2.0-*</LineupPackageVersion>
|
||||
<LineupPackageRestoreSource>https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json</LineupPackageRestoreSource>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
version:2.2.0-preview1-20180807.2
|
||||
commithash:11495dbd236104434e08cb1152fcb58cf2a20923
|
||||
version:3.0.0-alpha1-20180810.1
|
||||
commithash:45c32b4f020e14a9295be31866051a18d293309d
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/release/2.2/tools/korebuild.schema.json",
|
||||
"channel": "release/2.2"
|
||||
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/master/tools/korebuild.schema.json",
|
||||
"channel": "master"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
// 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.Routing;
|
||||
using Microsoft.AspNetCore.Routing.Matching;
|
||||
using Microsoft.AspNetCore.Routing.Patterns;
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
public static class EndpointDataSourceBuilderExtensions
|
||||
{
|
||||
public static EndpointBuilder MapHello(this EndpointDataSourceBuilder builder, string template, string greeter)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
var pipeline = builder.CreateApplicationBuilder()
|
||||
.UseHello(greeter)
|
||||
.Build();
|
||||
|
||||
return builder.MapEndpoint(
|
||||
(next) => pipeline,
|
||||
template,
|
||||
"Hello");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// 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 Microsoft.Extensions.Options;
|
||||
using RoutingSample.Web.HelloExtension;
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
public static class HelloAppBuilderExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseHello(this IApplicationBuilder app, string greeter)
|
||||
{
|
||||
if (app == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(app));
|
||||
}
|
||||
|
||||
return app.UseMiddleware<HelloMiddleware>(Options.Create(new HelloOptions
|
||||
{
|
||||
Greeter = greeter
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// 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.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace RoutingSample.Web.HelloExtension
|
||||
{
|
||||
public class HelloMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly HelloOptions _helloOptions;
|
||||
private readonly byte[] _helloPayload;
|
||||
|
||||
public HelloMiddleware(RequestDelegate next, IOptions<HelloOptions> helloOptions)
|
||||
{
|
||||
_next = next;
|
||||
_helloOptions = helloOptions.Value;
|
||||
|
||||
var payload = new List<byte>();
|
||||
payload.AddRange(Encoding.UTF8.GetBytes("Hello"));
|
||||
if (!string.IsNullOrEmpty(_helloOptions.Greeter))
|
||||
{
|
||||
payload.Add((byte)' ');
|
||||
payload.AddRange(Encoding.UTF8.GetBytes(_helloOptions.Greeter));
|
||||
}
|
||||
_helloPayload = payload.ToArray();
|
||||
}
|
||||
|
||||
public Task InvokeAsync(HttpContext context)
|
||||
{
|
||||
var response = context.Response;
|
||||
var payloadLength = _helloPayload.Length;
|
||||
response.StatusCode = 200;
|
||||
response.ContentType = "text/plain";
|
||||
response.ContentLength = payloadLength;
|
||||
return response.Body.WriteAsync(_helloPayload, 0, payloadLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
// 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 RoutingSample.Web.HelloExtension
|
||||
{
|
||||
public class HelloOptions
|
||||
{
|
||||
public string Greeter { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -5,21 +5,18 @@ using System;
|
|||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Internal;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Routing.Internal;
|
||||
using Microsoft.AspNetCore.Routing.Matching;
|
||||
using Microsoft.AspNetCore.Routing.Patterns;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
|
||||
namespace RoutingSample.Web
|
||||
{
|
||||
public class UseEndpointRoutingStartup
|
||||
{
|
||||
private static readonly byte[] _homePayload = Encoding.UTF8.GetBytes("Endpoint Routing sample endpoints:" + Environment.NewLine + "/plaintext");
|
||||
private static readonly byte[] _helloWorldPayload = Encoding.UTF8.GetBytes("Hello, World!");
|
||||
private static readonly byte[] _plainTextPayload = Encoding.UTF8.GetBytes("Plain text!");
|
||||
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
|
|
@ -29,80 +26,74 @@ namespace RoutingSample.Web
|
|||
{
|
||||
options.ConstraintMap.Add("endsWith", typeof(EndsWithStringMatchProcessor));
|
||||
});
|
||||
|
||||
var endpointDataSource = new DefaultEndpointDataSource(new[]
|
||||
{
|
||||
new MatcherEndpoint((next) => (httpContext) =>
|
||||
{
|
||||
var response = httpContext.Response;
|
||||
var payloadLength = _homePayload.Length;
|
||||
response.StatusCode = 200;
|
||||
response.ContentType = "text/plain";
|
||||
response.ContentLength = payloadLength;
|
||||
return response.Body.WriteAsync(_homePayload, 0, payloadLength);
|
||||
},
|
||||
RoutePatternFactory.Parse("/"),
|
||||
0,
|
||||
EndpointMetadataCollection.Empty,
|
||||
"Home"),
|
||||
new MatcherEndpoint((next) => (httpContext) =>
|
||||
{
|
||||
var response = httpContext.Response;
|
||||
var payloadLength = _helloWorldPayload.Length;
|
||||
response.StatusCode = 200;
|
||||
response.ContentType = "text/plain";
|
||||
response.ContentLength = payloadLength;
|
||||
return response.Body.WriteAsync(_helloWorldPayload, 0, payloadLength);
|
||||
},
|
||||
RoutePatternFactory.Parse("/plaintext"),
|
||||
0,
|
||||
EndpointMetadataCollection.Empty,
|
||||
"Plaintext"),
|
||||
new MatcherEndpoint((next) => (httpContext) =>
|
||||
{
|
||||
var response = httpContext.Response;
|
||||
response.StatusCode = 200;
|
||||
response.ContentType = "text/plain";
|
||||
return response.WriteAsync("WithConstraints");
|
||||
},
|
||||
RoutePatternFactory.Parse("/withconstraints/{id:endsWith(_001)}"),
|
||||
0,
|
||||
EndpointMetadataCollection.Empty,
|
||||
"withconstraints"),
|
||||
new MatcherEndpoint((next) => (httpContext) =>
|
||||
{
|
||||
var response = httpContext.Response;
|
||||
response.StatusCode = 200;
|
||||
response.ContentType = "text/plain";
|
||||
return response.WriteAsync("withoptionalconstraints");
|
||||
},
|
||||
RoutePatternFactory.Parse("/withoptionalconstraints/{id:endsWith(_001)?}"),
|
||||
0,
|
||||
EndpointMetadataCollection.Empty,
|
||||
"withoptionalconstraints"),
|
||||
new MatcherEndpoint((next) => (httpContext) =>
|
||||
{
|
||||
using (var writer = new StreamWriter(httpContext.Response.Body, Encoding.UTF8, 1024, leaveOpen: true))
|
||||
{
|
||||
var graphWriter = httpContext.RequestServices.GetRequiredService<DfaGraphWriter>();
|
||||
var dataSource = httpContext.RequestServices.GetRequiredService<CompositeEndpointDataSource>();
|
||||
graphWriter.Write(dataSource, writer);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
RoutePatternFactory.Parse("/graph"),
|
||||
0,
|
||||
new EndpointMetadataCollection(new HttpMethodMetadata(new[]{ "GET", })),
|
||||
"DFA Graph"),
|
||||
});
|
||||
|
||||
services.TryAddEnumerable(ServiceDescriptor.Singleton<EndpointDataSource>(endpointDataSource));
|
||||
}
|
||||
|
||||
public void Configure(Microsoft.AspNetCore.Builder.IApplicationBuilder app)
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseEndpointRouting();
|
||||
app.UseEndpointRouting(builder =>
|
||||
{
|
||||
builder.MapHello("/helloworld", "World");
|
||||
|
||||
builder.MapEndpoint(
|
||||
(next) => (httpContext) =>
|
||||
{
|
||||
var response = httpContext.Response;
|
||||
var payloadLength = _homePayload.Length;
|
||||
response.StatusCode = 200;
|
||||
response.ContentType = "text/plain";
|
||||
response.ContentLength = payloadLength;
|
||||
return response.Body.WriteAsync(_homePayload, 0, payloadLength);
|
||||
},
|
||||
"/",
|
||||
"Home");
|
||||
builder.MapEndpoint(
|
||||
(next) => (httpContext) =>
|
||||
{
|
||||
var response = httpContext.Response;
|
||||
var payloadLength = _plainTextPayload.Length;
|
||||
response.StatusCode = 200;
|
||||
response.ContentType = "text/plain";
|
||||
response.ContentLength = payloadLength;
|
||||
return response.Body.WriteAsync(_plainTextPayload, 0, payloadLength);
|
||||
},
|
||||
"/plaintext",
|
||||
"Plaintext");
|
||||
builder.MapEndpoint(
|
||||
(next) => (httpContext) =>
|
||||
{
|
||||
var response = httpContext.Response;
|
||||
response.StatusCode = 200;
|
||||
response.ContentType = "text/plain";
|
||||
return response.WriteAsync("WithConstraints");
|
||||
},
|
||||
"/withconstraints/{id:endsWith(_001)}",
|
||||
"withconstraints");
|
||||
builder.MapEndpoint(
|
||||
(next) => (httpContext) =>
|
||||
{
|
||||
var response = httpContext.Response;
|
||||
response.StatusCode = 200;
|
||||
response.ContentType = "text/plain";
|
||||
return response.WriteAsync("withoptionalconstraints");
|
||||
},
|
||||
"/withoptionalconstraints/{id:endsWith(_001)?}",
|
||||
"withoptionalconstraints");
|
||||
builder.MapEndpoint(
|
||||
(next) => (httpContext) =>
|
||||
{
|
||||
using (var writer = new StreamWriter(httpContext.Response.Body, Encoding.UTF8, 1024, leaveOpen: true))
|
||||
{
|
||||
var graphWriter = httpContext.RequestServices.GetRequiredService<DfaGraphWriter>();
|
||||
var dataSource = httpContext.RequestServices.GetRequiredService<CompositeEndpointDataSource>();
|
||||
graphWriter.Write(dataSource, writer);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
"/graph",
|
||||
"DFA Graph",
|
||||
new object[] { new HttpMethodMetadata(new[] { "GET", }) });
|
||||
});
|
||||
|
||||
// Imagine some more stuff here...
|
||||
|
||||
|
|
|
|||
|
|
@ -7,16 +7,28 @@ using Microsoft.AspNetCore.Routing;
|
|||
using Microsoft.AspNetCore.Routing.Internal;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Microsoft.AspNetCore.Internal
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
public static class EndpointRoutingApplicationBuilderExtensions
|
||||
{
|
||||
private const string EndpointRoutingRegisteredKey = "__EndpointRoutingMiddlewareRegistered";
|
||||
|
||||
public static IApplicationBuilder UseEndpointRouting(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseEndpointRouting(null);
|
||||
}
|
||||
|
||||
public static IApplicationBuilder UseEndpointRouting(this IApplicationBuilder builder, Action<EndpointDataSourceBuilder> configure)
|
||||
{
|
||||
VerifyRoutingIsRegistered(builder);
|
||||
|
||||
if (configure != null)
|
||||
{
|
||||
var dataSourceBuilder = (DefaultEndpointDataSourceBuilder)builder.ApplicationServices.GetRequiredService<EndpointDataSourceBuilder>();
|
||||
dataSourceBuilder.ApplicationBuilder = builder;
|
||||
configure(dataSourceBuilder);
|
||||
}
|
||||
|
||||
builder.Properties[EndpointRoutingRegisteredKey] = true;
|
||||
|
||||
return builder.UseMiddleware<EndpointRoutingMiddleware>();
|
||||
|
|
@ -50,4 +62,4 @@ namespace Microsoft.AspNetCore.Internal
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
// 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 Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Routing.Matching;
|
||||
using Microsoft.AspNetCore.Routing.Patterns;
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
public static class MapEndpointEndpointDataSourceBuilderExtensions
|
||||
{
|
||||
public static MatcherEndpointBuilder MapEndpoint(
|
||||
this EndpointDataSourceBuilder builder,
|
||||
Func<RequestDelegate, RequestDelegate> invoker,
|
||||
string pattern,
|
||||
string displayName)
|
||||
{
|
||||
return MapEndpoint(builder, invoker, pattern, displayName, metadata: null);
|
||||
}
|
||||
|
||||
public static MatcherEndpointBuilder MapEndpoint(
|
||||
this EndpointDataSourceBuilder builder,
|
||||
Func<RequestDelegate, RequestDelegate> invoker,
|
||||
RoutePattern pattern,
|
||||
string displayName)
|
||||
{
|
||||
return MapEndpoint(builder, invoker, pattern, displayName, metadata: null);
|
||||
}
|
||||
|
||||
public static MatcherEndpointBuilder MapEndpoint(
|
||||
this EndpointDataSourceBuilder builder,
|
||||
Func<RequestDelegate, RequestDelegate> invoker,
|
||||
string pattern,
|
||||
string displayName,
|
||||
IList<object> metadata)
|
||||
{
|
||||
return MapEndpoint(builder, invoker, RoutePatternFactory.Parse(pattern), displayName, metadata);
|
||||
}
|
||||
|
||||
public static MatcherEndpointBuilder MapEndpoint(
|
||||
this EndpointDataSourceBuilder builder,
|
||||
Func<RequestDelegate, RequestDelegate> invoker,
|
||||
RoutePattern pattern,
|
||||
string displayName,
|
||||
IList<object> metadata)
|
||||
{
|
||||
const int defaultOrder = 0;
|
||||
|
||||
var endpointBuilder = new MatcherEndpointBuilder(
|
||||
invoker,
|
||||
pattern,
|
||||
defaultOrder);
|
||||
endpointBuilder.DisplayName = displayName;
|
||||
if (metadata != null)
|
||||
{
|
||||
foreach (var item in metadata)
|
||||
{
|
||||
endpointBuilder.Metadata.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
builder.Endpoints.Add(endpointBuilder);
|
||||
return endpointBuilder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
// 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.Extensions.FileProviders;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace Microsoft.AspNetCore.Routing
|
||||
{
|
||||
internal class BuilderEndpointDataSource : EndpointDataSource
|
||||
{
|
||||
private readonly EndpointDataSourceBuilder _builder;
|
||||
|
||||
public BuilderEndpointDataSource(EndpointDataSourceBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
_builder = builder;
|
||||
}
|
||||
|
||||
public override IChangeToken GetChangeToken()
|
||||
{
|
||||
return NullChangeToken.Singleton;
|
||||
}
|
||||
|
||||
public override IReadOnlyList<Endpoint> Endpoints => _builder.Endpoints.Select(b => b.Build()).ToArray();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
// 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.Builder;
|
||||
|
||||
namespace Microsoft.AspNetCore.Routing
|
||||
{
|
||||
internal class DefaultEndpointDataSourceBuilder : EndpointDataSourceBuilder
|
||||
{
|
||||
public IApplicationBuilder ApplicationBuilder { get; set; }
|
||||
|
||||
public override ICollection<EndpointBuilder> Endpoints { get; } = new List<EndpointBuilder>();
|
||||
|
||||
public override IApplicationBuilder CreateApplicationBuilder() => ApplicationBuilder.New();
|
||||
}
|
||||
}
|
||||
|
|
@ -59,6 +59,12 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
return new CompositeEndpointDataSource(options.Value.DataSources);
|
||||
});
|
||||
|
||||
//
|
||||
// Endpoint Infrastructure
|
||||
//
|
||||
services.TryAddSingleton<EndpointDataSource, BuilderEndpointDataSource>();
|
||||
services.TryAddSingleton<EndpointDataSourceBuilder, DefaultEndpointDataSourceBuilder>();
|
||||
|
||||
//
|
||||
// Default matcher implementation
|
||||
//
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.AspNetCore.Routing
|
||||
{
|
||||
public abstract class EndpointBuilder
|
||||
{
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
public IList<object> Metadata { get; } = new List<object>();
|
||||
|
||||
public abstract Endpoint Build();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// 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.Builder;
|
||||
|
||||
namespace Microsoft.AspNetCore.Routing
|
||||
{
|
||||
public abstract class EndpointDataSourceBuilder
|
||||
{
|
||||
public abstract ICollection<EndpointBuilder> Endpoints { get; }
|
||||
|
||||
public abstract IApplicationBuilder CreateApplicationBuilder();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
// 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 Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing.Patterns;
|
||||
|
||||
namespace Microsoft.AspNetCore.Routing.Matching
|
||||
{
|
||||
public sealed class MatcherEndpointBuilder : EndpointBuilder
|
||||
{
|
||||
public Func<RequestDelegate, RequestDelegate> Invoker { get; set; }
|
||||
|
||||
public RoutePattern RoutePattern { get; set; }
|
||||
|
||||
public int Order { get; set; }
|
||||
|
||||
public MatcherEndpointBuilder(
|
||||
Func<RequestDelegate, RequestDelegate> invoker,
|
||||
RoutePattern routePattern,
|
||||
int order)
|
||||
{
|
||||
Invoker = invoker;
|
||||
RoutePattern = routePattern;
|
||||
Order = order;
|
||||
}
|
||||
|
||||
public override Endpoint Build()
|
||||
{
|
||||
var matcherEndpoint = new MatcherEndpoint(
|
||||
Invoker,
|
||||
RoutePattern,
|
||||
Order,
|
||||
new EndpointMetadataCollection(Metadata),
|
||||
DisplayName);
|
||||
|
||||
return matcherEndpoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
|||
{
|
||||
// Arrange
|
||||
var expectedContentType = "text/plain";
|
||||
var expectedContent = "Hello, World!";
|
||||
var expectedContent = "Plain text!";
|
||||
|
||||
// Act
|
||||
var response = await _client.GetAsync("/plaintext");
|
||||
|
|
@ -62,6 +62,25 @@ namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
|||
Assert.Equal(expectedContent, actualContent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MatchesHelloMiddleware_AndReturnsPlaintext()
|
||||
{
|
||||
// Arrange
|
||||
var expectedContentType = "text/plain";
|
||||
var expectedContent = "Hello World";
|
||||
|
||||
// Act
|
||||
var response = await _client.GetAsync("/helloworld");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.NotNull(response.Content);
|
||||
Assert.NotNull(response.Content.Headers.ContentType);
|
||||
Assert.Equal(expectedContentType, response.Content.Headers.ContentType.MediaType);
|
||||
var actualContent = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal(expectedContent, actualContent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MatchesEndpoint_WithSuccessfulConstraintMatch()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ using System;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder.Internal;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Internal;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
|
|
@ -13,7 +12,7 @@ using Xunit;
|
|||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
public class EndpointRoutingBuilderExtensionsTest
|
||||
public class EndpointRoutingApplicationBuilderExtensionsTest
|
||||
{
|
||||
[Fact]
|
||||
public void UseEndpointRouting_ServicesNotRegistered_Throws()
|
||||
|
|
@ -109,6 +108,26 @@ namespace Microsoft.AspNetCore.Builder
|
|||
Assert.NotNull(httpContext.Features.Get<IEndpointFeature>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UseEndpointRouting_CallWithBuilder_SetsEndpointBuilder()
|
||||
{
|
||||
// Arrange
|
||||
var services = CreateServices();
|
||||
|
||||
var app = new ApplicationBuilder(services);
|
||||
|
||||
// Act
|
||||
app.UseEndpointRouting(builder =>
|
||||
{
|
||||
builder.MapEndpoint(d => null, "/", "Test endpoint");
|
||||
});
|
||||
|
||||
// Assert
|
||||
var dataSourceBuilder = (DefaultEndpointDataSourceBuilder)services.GetRequiredService<EndpointDataSourceBuilder>();
|
||||
var endpointBuilder = Assert.Single(dataSourceBuilder.Endpoints);
|
||||
Assert.Equal("Test endpoint", endpointBuilder.DisplayName);
|
||||
}
|
||||
|
||||
private IServiceProvider CreateServices()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
// 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.Text;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Routing.Matching;
|
||||
using Microsoft.AspNetCore.Routing.Patterns;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
public class MapEndpointEndpointDataSourceBuilderExtensionsTest
|
||||
{
|
||||
[Fact]
|
||||
public void MapEndpoint_StringPattern_BuildsEndpoint()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultEndpointDataSourceBuilder();
|
||||
Func<RequestDelegate, RequestDelegate> invoker = (d) => null;
|
||||
|
||||
// Act
|
||||
var endpointBuilder = builder.MapEndpoint(invoker, "/", "Display name!");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(endpointBuilder, Assert.Single(builder.Endpoints));
|
||||
Assert.Equal(invoker, endpointBuilder.Invoker);
|
||||
Assert.Equal("Display name!", endpointBuilder.DisplayName);
|
||||
Assert.Equal("/", endpointBuilder.RoutePattern.RawText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapEndpoint_TypedPattern_BuildsEndpoint()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultEndpointDataSourceBuilder();
|
||||
Func<RequestDelegate, RequestDelegate> invoker = (d) => null;
|
||||
|
||||
// Act
|
||||
var endpointBuilder = builder.MapEndpoint(invoker, RoutePatternFactory.Parse("/"), "Display name!");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(endpointBuilder, Assert.Single(builder.Endpoints));
|
||||
Assert.Equal(invoker, endpointBuilder.Invoker);
|
||||
Assert.Equal("Display name!", endpointBuilder.DisplayName);
|
||||
Assert.Equal("/", endpointBuilder.RoutePattern.RawText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapEndpoint_StringPatternAndMetadata_BuildsEndpoint()
|
||||
{
|
||||
// Arrange
|
||||
var metadata = new object();
|
||||
var builder = new DefaultEndpointDataSourceBuilder();
|
||||
Func<RequestDelegate, RequestDelegate> invoker = (d) => null;
|
||||
|
||||
// Act
|
||||
var endpointBuilder = builder.MapEndpoint(invoker, "/", "Display name!", new[] { metadata });
|
||||
|
||||
// Assert
|
||||
Assert.Equal(endpointBuilder, Assert.Single(builder.Endpoints));
|
||||
Assert.Equal(invoker, endpointBuilder.Invoker);
|
||||
Assert.Equal("Display name!", endpointBuilder.DisplayName);
|
||||
Assert.Equal("/", endpointBuilder.RoutePattern.RawText);
|
||||
Assert.Equal(metadata, Assert.Single(endpointBuilder.Metadata));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapEndpoint_TypedPatternAndMetadata_BuildsEndpoint()
|
||||
{
|
||||
// Arrange
|
||||
var metadata = new object();
|
||||
var builder = new DefaultEndpointDataSourceBuilder();
|
||||
Func<RequestDelegate, RequestDelegate> invoker = (d) => null;
|
||||
|
||||
// Act
|
||||
var endpointBuilder = builder.MapEndpoint(invoker, RoutePatternFactory.Parse("/"), "Display name!", new[] { metadata });
|
||||
|
||||
// Assert
|
||||
Assert.Equal(endpointBuilder, Assert.Single(builder.Endpoints));
|
||||
Assert.Equal(invoker, endpointBuilder.Invoker);
|
||||
Assert.Equal("Display name!", endpointBuilder.DisplayName);
|
||||
Assert.Equal("/", endpointBuilder.RoutePattern.RawText);
|
||||
Assert.Equal(metadata, Assert.Single(endpointBuilder.Metadata));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
// 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.Text;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing.Patterns;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Routing.Matching
|
||||
{
|
||||
public class MatcherEndpointBuilderTest
|
||||
{
|
||||
[Fact]
|
||||
public void Build_AllValuesSet_EndpointCreated()
|
||||
{
|
||||
const int defaultOrder = 0;
|
||||
object metadata = new object();
|
||||
Func<RequestDelegate, RequestDelegate> invoker = (d) => null;
|
||||
|
||||
var builder = new MatcherEndpointBuilder(invoker, RoutePatternFactory.Parse("/"), defaultOrder)
|
||||
{
|
||||
DisplayName = "Display name!",
|
||||
Metadata = { metadata }
|
||||
};
|
||||
|
||||
var endpoint = Assert.IsType<MatcherEndpoint>(builder.Build());
|
||||
Assert.Equal("Display name!", endpoint.DisplayName);
|
||||
Assert.Equal(defaultOrder, endpoint.Order);
|
||||
Assert.Equal(invoker, endpoint.Invoker);
|
||||
Assert.Equal("/", endpoint.RoutePattern.RawText);
|
||||
Assert.Equal(metadata, Assert.Single(endpoint.Metadata));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<Project>
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>2.2.0</VersionPrefix>
|
||||
<VersionSuffix>preview1</VersionSuffix>
|
||||
<VersionPrefix>3.0.0</VersionPrefix>
|
||||
<VersionSuffix>alpha1</VersionSuffix>
|
||||
<PackageVersion Condition="'$(IsFinalBuild)' == 'true' AND '$(VersionSuffix)' == 'rtm' ">$(VersionPrefix)</PackageVersion>
|
||||
<PackageVersion Condition="'$(IsFinalBuild)' == 'true' AND '$(VersionSuffix)' != 'rtm' ">$(VersionPrefix)-$(VersionSuffix)-final</PackageVersion>
|
||||
<BuildNumber Condition="'$(BuildNumber)' == ''">t000</BuildNumber>
|
||||
|
|
|
|||
Loading…
Reference in New Issue