Split sandbox and functional tests websites (#890)

This commit is contained in:
James Newton-King 2018-10-24 13:54:50 +13:00 committed by GitHub
parent bd32ec3837
commit 577be72faa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 333 additions and 181 deletions

View File

@ -19,7 +19,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Routin
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Routing.Tests", "test\Microsoft.AspNetCore.Routing.Tests\Microsoft.AspNetCore.Routing.Tests.csproj", "{636D79ED-7B32-487C-BDA5-D2A1AAA97371}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RoutingSample.Web", "samples\RoutingSample.Web\RoutingSample.Web.csproj", "{DB94E647-C73A-4F52-A126-AA7544CCF33B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RoutingSandbox", "samples\RoutingSample.Web\RoutingSandbox.csproj", "{DB94E647-C73A-4F52-A126-AA7544CCF33B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C430C499-382D-47BD-B351-CF8F89C08CD2}"
ProjectSection(SolutionItems) = preProject
@ -55,6 +55,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{6824486A
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Swaggatherer", "tools\Swaggatherer\Swaggatherer.csproj", "{B8516771-E850-4724-BEC3-63FC00C2AE57}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebSites", "WebSites", "{8E5E51D4-6B03-4FC6-9F34-6E9FA24702BD}"
ProjectSection(SolutionItems) = preProject
test\WebSites\Directory.Build.props = test\WebSites\Directory.Build.props
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RoutingWebSite", "test\WebSites\RoutingWebSite\RoutingWebSite.csproj", "{E91EC5EC-30A8-45EC-9B2F-67E2D6C39D74}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -179,6 +186,18 @@ Global
{B8516771-E850-4724-BEC3-63FC00C2AE57}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{B8516771-E850-4724-BEC3-63FC00C2AE57}.Release|x86.ActiveCfg = Release|Any CPU
{B8516771-E850-4724-BEC3-63FC00C2AE57}.Release|x86.Build.0 = Release|Any CPU
{E91EC5EC-30A8-45EC-9B2F-67E2D6C39D74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E91EC5EC-30A8-45EC-9B2F-67E2D6C39D74}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E91EC5EC-30A8-45EC-9B2F-67E2D6C39D74}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{E91EC5EC-30A8-45EC-9B2F-67E2D6C39D74}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{E91EC5EC-30A8-45EC-9B2F-67E2D6C39D74}.Debug|x86.ActiveCfg = Debug|Any CPU
{E91EC5EC-30A8-45EC-9B2F-67E2D6C39D74}.Debug|x86.Build.0 = Debug|Any CPU
{E91EC5EC-30A8-45EC-9B2F-67E2D6C39D74}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E91EC5EC-30A8-45EC-9B2F-67E2D6C39D74}.Release|Any CPU.Build.0 = Release|Any CPU
{E91EC5EC-30A8-45EC-9B2F-67E2D6C39D74}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{E91EC5EC-30A8-45EC-9B2F-67E2D6C39D74}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{E91EC5EC-30A8-45EC-9B2F-67E2D6C39D74}.Release|x86.ActiveCfg = Release|Any CPU
{E91EC5EC-30A8-45EC-9B2F-67E2D6C39D74}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -194,6 +213,8 @@ Global
{F3D86714-4E64-41A6-9B36-A47B3683CF5D} = {D5F39F59-5725-4127-82E7-67028D006185}
{91F47A60-9A78-4968-B10D-157D9BFAC37F} = {7F5914E2-C63F-4759-898E-462804357C90}
{B8516771-E850-4724-BEC3-63FC00C2AE57} = {6824486A-3EFF-45D1-BEE8-8B137639C890}
{8E5E51D4-6B03-4FC6-9F34-6E9FA24702BD} = {95359B4B-4C85-4B44-A75B-0621905C4CF6}
{E91EC5EC-30A8-45EC-9B2F-67E2D6C39D74} = {8E5E51D4-6B03-4FC6-9F34-6E9FA24702BD}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {36C8D815-B7F1-479D-894B-E606FB8DECDA}

View File

@ -1,62 +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.Threading.Tasks;
using Microsoft.AspNetCore.Routing;
namespace RoutingSample.Web
{
public class PrefixRoute : IRouter
{
private readonly IRouteHandler _target;
private readonly string _prefix;
public PrefixRoute(IRouteHandler target, string prefix)
{
_target = target;
if (prefix == null)
{
prefix = "/";
}
else if (prefix.Length > 0 && prefix[0] != '/')
{
// owin.RequestPath starts with a /
prefix = "/" + prefix;
}
if (prefix.Length > 1 && prefix[prefix.Length - 1] == '/')
{
prefix = prefix.Substring(0, prefix.Length - 1);
}
_prefix = prefix;
}
public Task RouteAsync(RouteContext context)
{
var requestPath = context.HttpContext.Request.Path.Value ?? string.Empty;
if (requestPath.StartsWith(_prefix, StringComparison.OrdinalIgnoreCase))
{
if (requestPath.Length > _prefix.Length)
{
var lastCharacter = requestPath[_prefix.Length];
if (lastCharacter != '/' && lastCharacter != '#' && lastCharacter != '?')
{
return Task.CompletedTask;
}
}
context.Handler = _target.GetRequestHandler(context.HttpContext, context.RouteData);
}
return Task.CompletedTask;
}
public VirtualPathData GetVirtualPath(VirtualPathContext context)
{
return null;
}
}
}

View File

@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
namespace RoutingSample.Web
namespace RoutingSandbox
{
public class Program
{

View File

@ -1,43 +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 Microsoft.Extensions.DependencyInjection;
namespace RoutingSample.Web
{
public static class RouteBuilderExtensions
{
public static IRouteBuilder AddPrefixRoute(
this IRouteBuilder routeBuilder,
string prefix,
IRouteHandler handler)
{
routeBuilder.Routes.Add(new PrefixRoute(handler, prefix));
return routeBuilder;
}
public static IRouteBuilder MapLocaleRoute(
this IRouteBuilder routeBuilder,
string locale,
string routeTemplate,
object defaults)
{
var defaultsDictionary = new RouteValueDictionary(defaults);
defaultsDictionary.Add("locale", locale);
var constraintResolver = routeBuilder.ServiceProvider.GetService<IInlineConstraintResolver>();
var route = new Route(
target: routeBuilder.DefaultHandler,
routeTemplate: routeTemplate,
defaults: defaultsDictionary,
constraints: null,
dataTokens: null,
inlineConstraintResolver: constraintResolver);
routeBuilder.Routes.Add(route);
return routeBuilder;
}
}
}

View File

@ -14,7 +14,7 @@ using Microsoft.AspNetCore.Routing.Patterns;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace RoutingSample.Web
namespace RoutingSandbox
{
public class UseEndpointRoutingStartup
{
@ -23,13 +23,6 @@ namespace RoutingSample.Web
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<EndsWithStringRouteConstraint>();
services.AddRouting(options =>
{
options.ConstraintMap.Add("endsWith", typeof(EndsWithStringRouteConstraint));
});
var endpointDataSource = new DefaultEndpointDataSource(new[]
{
new RouteEndpoint((httpContext) =>
@ -58,28 +51,6 @@ namespace RoutingSample.Web
0,
EndpointMetadataCollection.Empty,
"Plaintext"),
new RouteEndpoint((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 RouteEndpoint((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 RouteEndpoint((httpContext) =>
{
using (var writer = new StreamWriter(httpContext.Response.Body, Encoding.UTF8, 1024, leaveOpen: true))
@ -95,40 +66,6 @@ namespace RoutingSample.Web
0,
new EndpointMetadataCollection(new HttpMethodMetadata(new[]{ "GET", })),
"DFA Graph"),
new RouteEndpoint((httpContext) =>
{
var linkGenerator = httpContext.RequestServices.GetRequiredService<LinkGenerator>();
var response = httpContext.Response;
response.StatusCode = 200;
response.ContentType = "text/plain";
return response.WriteAsync(
"Link: " + linkGenerator.GetPathByRouteValues(httpContext, "WithSingleAsteriskCatchAll", new { }));
},
RoutePatternFactory.Parse("/WithSingleAsteriskCatchAll/{*path}"),
0,
new EndpointMetadataCollection(
new RouteValuesAddressMetadata(
routeName: "WithSingleAsteriskCatchAll",
requiredValues: new RouteValueDictionary())),
"WithSingleAsteriskCatchAll"),
new RouteEndpoint((httpContext) =>
{
var linkGenerator = httpContext.RequestServices.GetRequiredService<LinkGenerator>();
var response = httpContext.Response;
response.StatusCode = 200;
response.ContentType = "text/plain";
return response.WriteAsync(
"Link: " + linkGenerator.GetPathByRouteValues(httpContext, "WithDoubleAsteriskCatchAll", new { }));
},
RoutePatternFactory.Parse("/WithDoubleAsteriskCatchAll/{**path}"),
0,
new EndpointMetadataCollection(
new RouteValuesAddressMetadata(
routeName: "WithDoubleAsteriskCatchAll",
requiredValues: new RouteValueDictionary())),
"WithDoubleAsteriskCatchAll"),
});
services.TryAddEnumerable(ServiceDescriptor.Singleton<EndpointDataSource>(endpointDataSource));

View File

@ -9,7 +9,7 @@ using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Routing.Constraints;
using Microsoft.Extensions.DependencyInjection;
namespace RoutingSample.Web
namespace RoutingSandbox
{
public class UseRouterStartup
{

View File

@ -8,9 +8,11 @@
<StandardTestTfms Condition=" '$(DeveloperBuild)' != 'true' AND '$(OS)' == 'Windows_NT' ">$(StandardTestTfms);net461</StandardTestTfms>
</PropertyGroup>
<PropertyGroup>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Internal.AspNetCore.Sdk" PrivateAssets="All" Version="$(InternalAspNetCoreSdkPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Testing" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
<PackageReference Include="Moq" Version="$(MoqPackageVersion)" />
<PackageReference Include="xunit" Version="$(XunitPackageVersion)" />

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(StandardTestTfms)</TargetFrameworks>
@ -8,4 +8,8 @@
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Routing.Abstractions\Microsoft.AspNetCore.Routing.Abstractions.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Testing" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
</ItemGroup>
</Project>

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(StandardTestTfms)</TargetFrameworks>

View File

@ -6,7 +6,7 @@ using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.TestHost;
using RoutingSample.Web;
using RoutingWebSite;
using Xunit;
namespace Microsoft.AspNetCore.Routing.FunctionalTests

View File

@ -6,7 +6,7 @@
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Routing\Microsoft.AspNetCore.Routing.csproj" />
<ProjectReference Include="..\..\samples\RoutingSample.Web\RoutingSample.Web.csproj" />
<ProjectReference Include="..\WebSites\RoutingWebSite\RoutingWebSite.csproj" />
</ItemGroup>
<ItemGroup>
@ -17,4 +17,4 @@
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="$(MicrosoftAspNetCoreTestHostPackageVersion)" />
</ItemGroup>
</Project>
</Project>

View File

@ -6,7 +6,7 @@ using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.TestHost;
using RoutingSample.Web;
using RoutingWebSite;
using Xunit;
namespace Microsoft.AspNetCore.Routing.FunctionalTests

View File

@ -0,0 +1,11 @@
<Project>
<!-- Skip the parent folder to prevent getting test package references. -->
<Import Project="..\..\Directory.Build.props" />
<PropertyGroup>
<DeveloperBuildTestWebsiteTfms>netcoreapp2.2</DeveloperBuildTestWebsiteTfms>
<StandardTestWebsiteTfms>$(DeveloperBuildTestWebsiteTfms)</StandardTestWebsiteTfms>
<StandardTestWebsiteTfms Condition=" '$(DeveloperBuild)' != 'true' ">netcoreapp2.2</StandardTestWebsiteTfms>
<StandardTestWebsiteTfms Condition=" '$(DeveloperBuild)' != 'true' AND '$(OS)' == 'Windows_NT' ">$(StandardTestWebsiteTfms);net461</StandardTestWebsiteTfms>
</PropertyGroup>
</Project>

View File

@ -6,7 +6,7 @@ using System.Globalization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
namespace RoutingSample.Web
namespace RoutingWebSite
{
internal class EndsWithStringRouteConstraint : IRouteConstraint
{

View File

@ -0,0 +1,72 @@
// 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.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
namespace RoutingWebSite
{
public class Program
{
public const string EndpointRoutingScenario = "endpointrouting";
public const string RouterScenario = "router";
public static void Main(string[] args)
{
var webHost = GetWebHostBuilder(args).Build();
webHost.Run();
}
// For unit testing
public static IWebHostBuilder GetWebHostBuilder(string[] args)
{
string scenario;
if (args.Length == 0)
{
Console.WriteLine("Choose a sample to run:");
Console.WriteLine($"1. {EndpointRoutingScenario}");
Console.WriteLine($"2. {RouterScenario}");
Console.WriteLine();
scenario = Console.ReadLine();
}
else
{
scenario = args[0];
}
Type startupType;
switch (scenario)
{
case "1":
case EndpointRoutingScenario:
startupType = typeof(UseEndpointRoutingStartup);
break;
case "2":
case RouterScenario:
startupType = typeof(UseRouterStartup);
break;
default:
Console.WriteLine($"unknown scenario {scenario}");
Console.WriteLine($"usage: dotnet run -- ({EndpointRoutingScenario}|{RouterScenario})");
throw new InvalidOperationException();
}
return new WebHostBuilder()
.UseKestrel()
.UseIISIntegration()
.ConfigureLogging(b =>
{
b.AddConsole();
b.SetMinimumLevel(LogLevel.Critical);
})
.UseContentRoot(Environment.CurrentDirectory)
.UseStartup(startupType);
}
}
}

View File

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.2</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">$(TargetFrameworks);net461</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Routing\Microsoft.AspNetCore.Routing.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsolePackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="$(MicrosoftAspNetCoreServerIISIntegrationPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(MicrosoftAspNetCoreStaticFilesPackageVersion)" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,148 @@
// 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.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.Patterns;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace RoutingWebSite
{
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!");
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<EndsWithStringRouteConstraint>();
services.AddRouting(options =>
{
options.ConstraintMap.Add("endsWith", typeof(EndsWithStringRouteConstraint));
});
var endpointDataSource = new DefaultEndpointDataSource(new[]
{
new RouteEndpoint((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 RouteEndpoint((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 RouteEndpoint((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 RouteEndpoint((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 RouteEndpoint((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"),
new RouteEndpoint((httpContext) =>
{
var linkGenerator = httpContext.RequestServices.GetRequiredService<LinkGenerator>();
var response = httpContext.Response;
response.StatusCode = 200;
response.ContentType = "text/plain";
return response.WriteAsync(
"Link: " + linkGenerator.GetPathByRouteValues(httpContext, "WithSingleAsteriskCatchAll", new { }));
},
RoutePatternFactory.Parse("/WithSingleAsteriskCatchAll/{*path}"),
0,
new EndpointMetadataCollection(
new RouteValuesAddressMetadata(
routeName: "WithSingleAsteriskCatchAll",
requiredValues: new RouteValueDictionary())),
"WithSingleAsteriskCatchAll"),
new RouteEndpoint((httpContext) =>
{
var linkGenerator = httpContext.RequestServices.GetRequiredService<LinkGenerator>();
var response = httpContext.Response;
response.StatusCode = 200;
response.ContentType = "text/plain";
return response.WriteAsync(
"Link: " + linkGenerator.GetPathByRouteValues(httpContext, "WithDoubleAsteriskCatchAll", new { }));
},
RoutePatternFactory.Parse("/WithDoubleAsteriskCatchAll/{**path}"),
0,
new EndpointMetadataCollection(
new RouteValuesAddressMetadata(
routeName: "WithDoubleAsteriskCatchAll",
requiredValues: new RouteValueDictionary())),
"WithDoubleAsteriskCatchAll"),
});
services.TryAddEnumerable(ServiceDescriptor.Singleton<EndpointDataSource>(endpointDataSource));
}
public void Configure(IApplicationBuilder app)
{
app.UseEndpointRouting();
app.UseStaticFiles();
// Imagine some more stuff here...
app.UseEndpoint();
}
}
}

View File

@ -0,0 +1,43 @@
// 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.Text.RegularExpressions;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Routing.Constraints;
using Microsoft.Extensions.DependencyInjection;
namespace RoutingWebSite
{
public class UseRouterStartup
{
private static readonly TimeSpan RegexMatchTimeout = TimeSpan.FromSeconds(10);
public void ConfigureServices(IServiceCollection services)
{
services.AddRouting();
}
public void Configure(IApplicationBuilder app)
{
app.UseRouter(routes =>
{
routes.DefaultHandler = new RouteHandler((httpContext) =>
{
var request = httpContext.Request;
return httpContext.Response.WriteAsync($"Verb = {request.Method.ToUpperInvariant()} - Path = {request.Path} - Route values - {string.Join(", ", httpContext.GetRouteData().Values)}");
});
routes.MapGet("api/get/{id}", (request, response, routeData) => response.WriteAsync($"API Get {routeData.Values["id"]}"))
.MapMiddlewareRoute("api/middleware", (appBuilder) => appBuilder.Use((httpContext, next) => httpContext.Response.WriteAsync("Middleware!")))
.MapRoute(
name: "AllVerbs",
template: "api/all/{name}/{lastName?}",
defaults: new { lastName = "Doe" },
constraints: new { lastName = new RegexRouteConstraint(new Regex("[a-zA-Z]{3}", RegexOptions.CultureInvariant, RegexMatchTimeout)) });
});
}
}
}