Split sandbox and functional tests websites (#890)
This commit is contained in:
parent
bd32ec3837
commit
577be72faa
23
Routing.sln
23
Routing.sln
|
|
@ -19,7 +19,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Routin
|
||||||
EndProject
|
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}"
|
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
|
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
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C430C499-382D-47BD-B351-CF8F89C08CD2}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C430C499-382D-47BD-B351-CF8F89C08CD2}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
|
@ -55,6 +55,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{6824486A
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Swaggatherer", "tools\Swaggatherer\Swaggatherer.csproj", "{B8516771-E850-4724-BEC3-63FC00C2AE57}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Swaggatherer", "tools\Swaggatherer\Swaggatherer.csproj", "{B8516771-E850-4724-BEC3-63FC00C2AE57}"
|
||||||
EndProject
|
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
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
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|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.ActiveCfg = Release|Any CPU
|
||||||
{B8516771-E850-4724-BEC3-63FC00C2AE57}.Release|x86.Build.0 = 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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
@ -194,6 +213,8 @@ Global
|
||||||
{F3D86714-4E64-41A6-9B36-A47B3683CF5D} = {D5F39F59-5725-4127-82E7-67028D006185}
|
{F3D86714-4E64-41A6-9B36-A47B3683CF5D} = {D5F39F59-5725-4127-82E7-67028D006185}
|
||||||
{91F47A60-9A78-4968-B10D-157D9BFAC37F} = {7F5914E2-C63F-4759-898E-462804357C90}
|
{91F47A60-9A78-4968-B10D-157D9BFAC37F} = {7F5914E2-C63F-4759-898E-462804357C90}
|
||||||
{B8516771-E850-4724-BEC3-63FC00C2AE57} = {6824486A-3EFF-45D1-BEE8-8B137639C890}
|
{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
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {36C8D815-B7F1-479D-894B-E606FB8DECDA}
|
SolutionGuid = {36C8D815-B7F1-479D-894B-E606FB8DECDA}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace RoutingSample.Web
|
namespace RoutingSandbox
|
||||||
{
|
{
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -14,7 +14,7 @@ using Microsoft.AspNetCore.Routing.Patterns;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
|
|
||||||
namespace RoutingSample.Web
|
namespace RoutingSandbox
|
||||||
{
|
{
|
||||||
public class UseEndpointRoutingStartup
|
public class UseEndpointRoutingStartup
|
||||||
{
|
{
|
||||||
|
|
@ -23,13 +23,6 @@ namespace RoutingSample.Web
|
||||||
|
|
||||||
public void ConfigureServices(IServiceCollection services)
|
public void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddTransient<EndsWithStringRouteConstraint>();
|
|
||||||
|
|
||||||
services.AddRouting(options =>
|
|
||||||
{
|
|
||||||
options.ConstraintMap.Add("endsWith", typeof(EndsWithStringRouteConstraint));
|
|
||||||
});
|
|
||||||
|
|
||||||
var endpointDataSource = new DefaultEndpointDataSource(new[]
|
var endpointDataSource = new DefaultEndpointDataSource(new[]
|
||||||
{
|
{
|
||||||
new RouteEndpoint((httpContext) =>
|
new RouteEndpoint((httpContext) =>
|
||||||
|
|
@ -58,28 +51,6 @@ namespace RoutingSample.Web
|
||||||
0,
|
0,
|
||||||
EndpointMetadataCollection.Empty,
|
EndpointMetadataCollection.Empty,
|
||||||
"Plaintext"),
|
"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) =>
|
new RouteEndpoint((httpContext) =>
|
||||||
{
|
{
|
||||||
using (var writer = new StreamWriter(httpContext.Response.Body, Encoding.UTF8, 1024, leaveOpen: true))
|
using (var writer = new StreamWriter(httpContext.Response.Body, Encoding.UTF8, 1024, leaveOpen: true))
|
||||||
|
|
@ -95,40 +66,6 @@ namespace RoutingSample.Web
|
||||||
0,
|
0,
|
||||||
new EndpointMetadataCollection(new HttpMethodMetadata(new[]{ "GET", })),
|
new EndpointMetadataCollection(new HttpMethodMetadata(new[]{ "GET", })),
|
||||||
"DFA Graph"),
|
"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));
|
services.TryAddEnumerable(ServiceDescriptor.Singleton<EndpointDataSource>(endpointDataSource));
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ using Microsoft.AspNetCore.Routing;
|
||||||
using Microsoft.AspNetCore.Routing.Constraints;
|
using Microsoft.AspNetCore.Routing.Constraints;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace RoutingSample.Web
|
namespace RoutingSandbox
|
||||||
{
|
{
|
||||||
public class UseRouterStartup
|
public class UseRouterStartup
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,11 @@
|
||||||
<StandardTestTfms Condition=" '$(DeveloperBuild)' != 'true' AND '$(OS)' == 'Windows_NT' ">$(StandardTestTfms);net461</StandardTestTfms>
|
<StandardTestTfms Condition=" '$(DeveloperBuild)' != 'true' AND '$(OS)' == 'Windows_NT' ">$(StandardTestTfms);net461</StandardTestTfms>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<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="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
|
||||||
<PackageReference Include="Moq" Version="$(MoqPackageVersion)" />
|
<PackageReference Include="Moq" Version="$(MoqPackageVersion)" />
|
||||||
<PackageReference Include="xunit" Version="$(XunitPackageVersion)" />
|
<PackageReference Include="xunit" Version="$(XunitPackageVersion)" />
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>$(StandardTestTfms)</TargetFrameworks>
|
<TargetFrameworks>$(StandardTestTfms)</TargetFrameworks>
|
||||||
|
|
@ -8,4 +8,8 @@
|
||||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Routing.Abstractions\Microsoft.AspNetCore.Routing.Abstractions.csproj" />
|
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Routing.Abstractions\Microsoft.AspNetCore.Routing.Abstractions.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Testing" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>$(StandardTestTfms)</TargetFrameworks>
|
<TargetFrameworks>$(StandardTestTfms)</TargetFrameworks>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.TestHost;
|
using Microsoft.AspNetCore.TestHost;
|
||||||
using RoutingSample.Web;
|
using RoutingWebSite;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Routing\Microsoft.AspNetCore.Routing.csproj" />
|
<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>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
@ -17,4 +17,4 @@
|
||||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="$(MicrosoftAspNetCoreTestHostPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="$(MicrosoftAspNetCoreTestHostPackageVersion)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -6,7 +6,7 @@ using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.TestHost;
|
using Microsoft.AspNetCore.TestHost;
|
||||||
using RoutingSample.Web;
|
using RoutingWebSite;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -6,7 +6,7 @@ using System.Globalization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
|
|
||||||
namespace RoutingSample.Web
|
namespace RoutingWebSite
|
||||||
{
|
{
|
||||||
internal class EndsWithStringRouteConstraint : IRouteConstraint
|
internal class EndsWithStringRouteConstraint : IRouteConstraint
|
||||||
{
|
{
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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)) });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue