Merge pull request #8633 from dotnet-maestro-bot/merge/release/2.2-to-master

[automated] Merge branch 'release/2.2' => 'master'
This commit is contained in:
James Newton-King 2018-10-23 23:04:29 +13:00 committed by GitHub
commit 5c51e831aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 987 additions and 174 deletions

View File

@ -16,88 +16,88 @@
<BenchmarksOnlyMySqlConnectorPackageVersion>0.43.0</BenchmarksOnlyMySqlConnectorPackageVersion>
<BenchmarksOnlyNpgsqlEntityFrameworkCorePostgreSQLPackageVersion>2.1.1.1</BenchmarksOnlyNpgsqlEntityFrameworkCorePostgreSQLPackageVersion>
<BenchmarksOnlyPomeloEntityFrameworkCoreMySqlPackageVersion>2.1.1</BenchmarksOnlyPomeloEntityFrameworkCoreMySqlPackageVersion>
<InternalAspNetCoreAnalyzersPackageVersion>3.0.0-alpha1-10617</InternalAspNetCoreAnalyzersPackageVersion>
<MicrosoftAspNetCoreAllPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreAllPackageVersion>
<MicrosoftAspNetCoreAnalyzerTestingPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreAnalyzerTestingPackageVersion>
<MicrosoftAspNetCoreAntiforgeryPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreAntiforgeryPackageVersion>
<MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>
<MicrosoftAspNetCoreAuthenticationCorePackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreAuthenticationCorePackageVersion>
<MicrosoftAspNetCoreAuthenticationJwtBearerPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreAuthenticationJwtBearerPackageVersion>
<MicrosoftAspNetCoreAuthenticationPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreAuthenticationPackageVersion>
<MicrosoftAspNetCoreAuthorizationPolicyPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreAuthorizationPolicyPackageVersion>
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
<MicrosoftAspNetCoreChunkingCookieManagerSourcesPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreChunkingCookieManagerSourcesPackageVersion>
<MicrosoftAspNetCoreCorsPackageVersion>3.0.0-a-alpha1-master-16559</MicrosoftAspNetCoreCorsPackageVersion>
<MicrosoftAspNetCoreCookiePolicyPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreCookiePolicyPackageVersion>
<MicrosoftAspNetCoreDiagnosticsAbstractionsPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreDiagnosticsAbstractionsPackageVersion>
<MicrosoftAspNetCoreDiagnosticsPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreDiagnosticsPackageVersion>
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
<InternalAspNetCoreAnalyzersPackageVersion>3.0.0-alpha1-10654</InternalAspNetCoreAnalyzersPackageVersion>
<MicrosoftAspNetCoreAllPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreAllPackageVersion>
<MicrosoftAspNetCoreAnalyzerTestingPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreAnalyzerTestingPackageVersion>
<MicrosoftAspNetCoreAntiforgeryPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreAntiforgeryPackageVersion>
<MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>
<MicrosoftAspNetCoreAuthenticationCorePackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreAuthenticationCorePackageVersion>
<MicrosoftAspNetCoreAuthenticationJwtBearerPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreAuthenticationJwtBearerPackageVersion>
<MicrosoftAspNetCoreAuthenticationPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreAuthenticationPackageVersion>
<MicrosoftAspNetCoreAuthorizationPolicyPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreAuthorizationPolicyPackageVersion>
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
<MicrosoftAspNetCoreChunkingCookieManagerSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreChunkingCookieManagerSourcesPackageVersion>
<MicrosoftAspNetCoreCookiePolicyPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreCookiePolicyPackageVersion>
<MicrosoftAspNetCoreCorsPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreCorsPackageVersion>
<MicrosoftAspNetCoreDiagnosticsAbstractionsPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreDiagnosticsAbstractionsPackageVersion>
<MicrosoftAspNetCoreDiagnosticsPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreDiagnosticsPackageVersion>
<MicrosoftAspNetCoreHostingAbstractions20PackageVersion>2.0.0</MicrosoftAspNetCoreHostingAbstractions20PackageVersion>
<MicrosoftAspNetCoreHostingPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreHostingPackageVersion>
<MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>
<MicrosoftAspNetCoreHttpExtensionsPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreHttpExtensionsPackageVersion>
<MicrosoftAspNetCoreHttpPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreHttpPackageVersion>
<MicrosoftAspNetCoreJsonPatchPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreJsonPatchPackageVersion>
<MicrosoftAspNetCoreLocalizationPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreLocalizationPackageVersion>
<MicrosoftAspNetCoreLocalizationRoutingPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreLocalizationRoutingPackageVersion>
<MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>
<MicrosoftAspNetCoreRangeHelperSourcesPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreRangeHelperSourcesPackageVersion>
<MicrosoftAspNetCoreRazorDesignPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreRazorDesignPackageVersion>
<MicrosoftAspNetCoreRazorLanguagePackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreRazorLanguagePackageVersion>
<MicrosoftAspNetCoreRazorRuntimePackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreRazorRuntimePackageVersion>
<MicrosoftAspNetCoreRazorTagHelpersTestingSourcesPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreRazorTagHelpersTestingSourcesPackageVersion>
<MicrosoftAspNetCoreResponseCachingAbstractionsPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreResponseCachingAbstractionsPackageVersion>
<MicrosoftAspNetCoreResponseCachingPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreResponseCachingPackageVersion>
<MicrosoftAspNetCoreRoutingAbstractionsPackageVersion>3.0.0-a-alpha1-master-builder-17073</MicrosoftAspNetCoreRoutingAbstractionsPackageVersion>
<MicrosoftAspNetCoreRoutingPackageVersion>3.0.0-a-alpha1-master-builder-17073</MicrosoftAspNetCoreRoutingPackageVersion>
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
<MicrosoftAspNetCoreServerKestrelPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreServerKestrelPackageVersion>
<MicrosoftAspNetCoreSessionPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreSessionPackageVersion>
<MicrosoftAspNetCoreStaticFilesPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreStaticFilesPackageVersion>
<MicrosoftAspNetCoreTestHostPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreTestHostPackageVersion>
<MicrosoftAspNetCoreTestingPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreTestingPackageVersion>
<MicrosoftAspNetCoreWebUtilitiesPackageVersion>3.0.0-alpha1-10617</MicrosoftAspNetCoreWebUtilitiesPackageVersion>
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
<MicrosoftAspNetCoreHostingPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreHostingPackageVersion>
<MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>
<MicrosoftAspNetCoreHttpExtensionsPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreHttpExtensionsPackageVersion>
<MicrosoftAspNetCoreHttpPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreHttpPackageVersion>
<MicrosoftAspNetCoreJsonPatchPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreJsonPatchPackageVersion>
<MicrosoftAspNetCoreLocalizationPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreLocalizationPackageVersion>
<MicrosoftAspNetCoreLocalizationRoutingPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreLocalizationRoutingPackageVersion>
<MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>
<MicrosoftAspNetCoreRangeHelperSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreRangeHelperSourcesPackageVersion>
<MicrosoftAspNetCoreRazorDesignPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreRazorDesignPackageVersion>
<MicrosoftAspNetCoreRazorLanguagePackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreRazorLanguagePackageVersion>
<MicrosoftAspNetCoreRazorRuntimePackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreRazorRuntimePackageVersion>
<MicrosoftAspNetCoreRazorTagHelpersTestingSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreRazorTagHelpersTestingSourcesPackageVersion>
<MicrosoftAspNetCoreResponseCachingAbstractionsPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreResponseCachingAbstractionsPackageVersion>
<MicrosoftAspNetCoreResponseCachingPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreResponseCachingPackageVersion>
<MicrosoftAspNetCoreRoutingAbstractionsPackageVersion>3.0.0-a-alpha1-master-builder-17095</MicrosoftAspNetCoreRoutingAbstractionsPackageVersion>
<MicrosoftAspNetCoreRoutingPackageVersion>3.0.0-a-alpha1-master-builder-17095</MicrosoftAspNetCoreRoutingPackageVersion>
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
<MicrosoftAspNetCoreServerKestrelPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreServerKestrelPackageVersion>
<MicrosoftAspNetCoreSessionPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreSessionPackageVersion>
<MicrosoftAspNetCoreStaticFilesPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreStaticFilesPackageVersion>
<MicrosoftAspNetCoreTestHostPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreTestHostPackageVersion>
<MicrosoftAspNetCoreTestingPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreTestingPackageVersion>
<MicrosoftAspNetCoreWebUtilitiesPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreWebUtilitiesPackageVersion>
<MicrosoftAspNetWebApiClientPackageVersion>5.2.6</MicrosoftAspNetWebApiClientPackageVersion>
<MicrosoftBuildUtilitiesCorePackageVersion>15.6.82</MicrosoftBuildUtilitiesCorePackageVersion>
<MicrosoftBuildUtilitiesCorePackageVersion>15.8.166</MicrosoftBuildUtilitiesCorePackageVersion>
<MicrosoftCodeAnalysisCSharpPackageVersion>2.8.0</MicrosoftCodeAnalysisCSharpPackageVersion>
<MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>2.8.0</MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>
<MicrosoftCodeAnalysisRazorPackageVersion>3.0.0-alpha1-10617</MicrosoftCodeAnalysisRazorPackageVersion>
<MicrosoftCodeAnalysisRazorPackageVersion>3.0.0-alpha1-10654</MicrosoftCodeAnalysisRazorPackageVersion>
<MicrosoftDiaSymReaderNativePackageVersion>1.7.0</MicrosoftDiaSymReaderNativePackageVersion>
<MicrosoftExtensionsCachingMemoryPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsCachingMemoryPackageVersion>
<MicrosoftExtensionsClosedGenericMatcherSourcesPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsClosedGenericMatcherSourcesPackageVersion>
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
<MicrosoftExtensionsConfigurationJsonPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsConfigurationJsonPackageVersion>
<MicrosoftExtensionsConfigurationPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsConfigurationPackageVersion>
<MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>
<MicrosoftExtensionsDependencyInjectionPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsDependencyInjectionPackageVersion>
<MicrosoftExtensionsCachingMemoryPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsCachingMemoryPackageVersion>
<MicrosoftExtensionsClosedGenericMatcherSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsClosedGenericMatcherSourcesPackageVersion>
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
<MicrosoftExtensionsConfigurationJsonPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsConfigurationJsonPackageVersion>
<MicrosoftExtensionsConfigurationPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsConfigurationPackageVersion>
<MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>
<MicrosoftExtensionsDependencyInjectionPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsDependencyInjectionPackageVersion>
<MicrosoftExtensionsDependencyModelPackageVersion>3.0.0-preview1-26907-05</MicrosoftExtensionsDependencyModelPackageVersion>
<MicrosoftExtensionsDiagnosticAdapterPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsDiagnosticAdapterPackageVersion>
<MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
<MicrosoftExtensionsFileProvidersCompositePackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsFileProvidersCompositePackageVersion>
<MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
<MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>
<MicrosoftExtensionsLocalizationPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsLocalizationPackageVersion>
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
<MicrosoftExtensionsLoggingConsolePackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsLoggingConsolePackageVersion>
<MicrosoftExtensionsLoggingDebugPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsLoggingDebugPackageVersion>
<MicrosoftExtensionsLoggingPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsLoggingPackageVersion>
<MicrosoftExtensionsLoggingTestingPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsLoggingTestingPackageVersion>
<MicrosoftExtensionsObjectMethodExecutorSourcesPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsObjectMethodExecutorSourcesPackageVersion>
<MicrosoftExtensionsOptionsPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsOptionsPackageVersion>
<MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion>
<MicrosoftExtensionsPrimitivesPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsPrimitivesPackageVersion>
<MicrosoftExtensionsPropertyActivatorSourcesPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsPropertyActivatorSourcesPackageVersion>
<MicrosoftExtensionsPropertyHelperSourcesPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsPropertyHelperSourcesPackageVersion>
<MicrosoftExtensionsSecurityHelperSourcesPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsSecurityHelperSourcesPackageVersion>
<MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>
<MicrosoftExtensionsValueStopwatchSourcesPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsValueStopwatchSourcesPackageVersion>
<MicrosoftExtensionsWebEncodersPackageVersion>3.0.0-alpha1-10617</MicrosoftExtensionsWebEncodersPackageVersion>
<MicrosoftExtensionsDiagnosticAdapterPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsDiagnosticAdapterPackageVersion>
<MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
<MicrosoftExtensionsFileProvidersCompositePackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsFileProvidersCompositePackageVersion>
<MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
<MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>
<MicrosoftExtensionsLocalizationPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsLocalizationPackageVersion>
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
<MicrosoftExtensionsLoggingConsolePackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsLoggingConsolePackageVersion>
<MicrosoftExtensionsLoggingDebugPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsLoggingDebugPackageVersion>
<MicrosoftExtensionsLoggingPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsLoggingPackageVersion>
<MicrosoftExtensionsLoggingTestingPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsLoggingTestingPackageVersion>
<MicrosoftExtensionsObjectMethodExecutorSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsObjectMethodExecutorSourcesPackageVersion>
<MicrosoftExtensionsOptionsPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsOptionsPackageVersion>
<MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion>
<MicrosoftExtensionsPrimitivesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsPrimitivesPackageVersion>
<MicrosoftExtensionsPropertyActivatorSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsPropertyActivatorSourcesPackageVersion>
<MicrosoftExtensionsPropertyHelperSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsPropertyHelperSourcesPackageVersion>
<MicrosoftExtensionsSecurityHelperSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsSecurityHelperSourcesPackageVersion>
<MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>
<MicrosoftExtensionsValueStopwatchSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsValueStopwatchSourcesPackageVersion>
<MicrosoftExtensionsWebEncodersPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsWebEncodersPackageVersion>
<MicrosoftNETCoreApp20PackageVersion>2.0.9</MicrosoftNETCoreApp20PackageVersion>
<MicrosoftNETCoreApp21PackageVersion>2.1.3</MicrosoftNETCoreApp21PackageVersion>
<MicrosoftNETCoreApp22PackageVersion>2.2.0-preview2-26905-02</MicrosoftNETCoreApp22PackageVersion>
<MicrosoftNetHttpHeadersPackageVersion>3.0.0-alpha1-10617</MicrosoftNetHttpHeadersPackageVersion>
<MicrosoftNETSdkRazorPackageVersion>3.0.0-alpha1-10617</MicrosoftNETSdkRazorPackageVersion>
<MicrosoftNETCoreApp22PackageVersion>2.2.0-preview3-27014-02</MicrosoftNETCoreApp22PackageVersion>
<MicrosoftNetHttpHeadersPackageVersion>3.0.0-alpha1-10654</MicrosoftNetHttpHeadersPackageVersion>
<MicrosoftNETSdkRazorPackageVersion>3.0.0-alpha1-10654</MicrosoftNETSdkRazorPackageVersion>
<MicrosoftNETTestSdkPackageVersion>15.6.1</MicrosoftNETTestSdkPackageVersion>
<MoqPackageVersion>4.10.0</MoqPackageVersion>
<NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion>

View File

@ -271,26 +271,64 @@ namespace Microsoft.AspNetCore.Mvc.Internal
List<Action<EndpointModel>> conventions)
{
var newPathSegments = routePattern.PathSegments.ToList();
var hasLinkGenerationEndpoint = false;
// Create a mutable copy
var nonInlineDefaultsCopy = nonInlineDefaults != null
? new RouteValueDictionary(nonInlineDefaults)
: null;
var resolvedRouteValues = ResolveActionRouteValues(action, allDefaults);
for (var i = 0; i < newPathSegments.Count; i++)
{
// Check if the pattern can be shortened because the remaining parameters are optional
//
// e.g. Matching pattern {controller=Home}/{action=Index}/{id?} against HomeController.Index
// can resolve to the following endpoints:
// - /Home/Index/{id?}
// - /Home
// e.g. Matching pattern {controller=Home}/{action=Index} against HomeController.Index
// can resolve to the following endpoints: (sorted by RouteEndpoint.Order)
// - /
if (UseDefaultValuePlusRemainingSegmentsOptional(i, action, allDefaults, newPathSegments))
// - /Home
// - /Home/Index
if (UseDefaultValuePlusRemainingSegmentsOptional(
i,
action,
resolvedRouteValues,
allDefaults,
ref nonInlineDefaultsCopy,
newPathSegments))
{
// The route pattern has matching default values AND an optional parameter
// For link generation we need to include an endpoint with parameters and default values
// so the link is correctly shortened
// e.g. {controller=Home}/{action=Index}/{id=17}
if (!hasLinkGenerationEndpoint)
{
var ep = CreateEndpoint(
action,
resolvedRouteValues,
name,
GetPattern(ref patternStringBuilder, newPathSegments),
newPathSegments,
nonInlineDefaultsCopy,
routeOrder++,
dataTokens,
suppressLinkGeneration,
true,
conventions);
endpoints.Add(ep);
hasLinkGenerationEndpoint = true;
}
var subPathSegments = newPathSegments.Take(i);
var subEndpoint = CreateEndpoint(
action,
resolvedRouteValues,
name,
GetPattern(ref patternStringBuilder, subPathSegments),
subPathSegments,
nonInlineDefaults,
nonInlineDefaultsCopy,
routeOrder++,
dataTokens,
suppressLinkGeneration,
@ -299,15 +337,84 @@ namespace Microsoft.AspNetCore.Mvc.Internal
endpoints.Add(subEndpoint);
}
List<RoutePatternPart> segmentParts = null; // Initialize only as needed
var segment = newPathSegments[i];
for (var j = 0; j < segment.Parts.Count; j++)
{
var part = segment.Parts[j];
UpdatePathSegments(i, action, resolvedRouteValues, routePattern, newPathSegments, ref allParameterPolicies);
}
if (part.IsParameter &&
part is RoutePatternParameterPart parameterPart &&
action.RouteValues.ContainsKey(parameterPart.Name))
var finalEndpoint = CreateEndpoint(
action,
resolvedRouteValues,
name,
GetPattern(ref patternStringBuilder, newPathSegments),
newPathSegments,
nonInlineDefaultsCopy,
routeOrder++,
dataTokens,
suppressLinkGeneration,
suppressPathMatching,
conventions);
endpoints.Add(finalEndpoint);
return routeOrder;
string GetPattern(ref StringBuilder sb, IEnumerable<RoutePatternPathSegment> segments)
{
if (sb == null)
{
sb = new StringBuilder();
}
RoutePatternWriter.WriteString(sb, segments);
var rawPattern = sb.ToString();
sb.Length = 0;
return rawPattern;
}
}
private static IDictionary<string, string> ResolveActionRouteValues(ActionDescriptor action, IReadOnlyDictionary<string, object> allDefaults)
{
Dictionary<string, string> resolvedRequiredValues = null;
foreach (var kvp in action.RouteValues)
{
// Check whether there is a matching default value with a different case
// e.g. {controller=HOME}/{action} with HomeController.Index will have route values:
// - controller = HOME
// - action = Index
if (allDefaults.TryGetValue(kvp.Key, out var value) &&
value is string defaultValue &&
!string.Equals(kvp.Value, defaultValue, StringComparison.Ordinal) &&
string.Equals(kvp.Value, defaultValue, StringComparison.OrdinalIgnoreCase))
{
if (resolvedRequiredValues == null)
{
resolvedRequiredValues = new Dictionary<string, string>(action.RouteValues, StringComparer.OrdinalIgnoreCase);
}
resolvedRequiredValues[kvp.Key] = defaultValue;
}
}
return resolvedRequiredValues ?? action.RouteValues;
}
private void UpdatePathSegments(
int i,
ActionDescriptor action,
IDictionary<string, string> resolvedRequiredValues,
RoutePattern routePattern,
List<RoutePatternPathSegment> newPathSegments,
ref IDictionary<string, IList<IParameterPolicy>> allParameterPolicies)
{
List<RoutePatternPart> segmentParts = null; // Initialize only as needed
var segment = newPathSegments[i];
for (var j = 0; j < segment.Parts.Count; j++)
{
var part = segment.Parts[j];
if (part is RoutePatternParameterPart parameterPart)
{
if (resolvedRequiredValues.TryGetValue(parameterPart.Name, out var parameterRouteValue))
{
if (segmentParts == null)
{
@ -318,9 +425,6 @@ namespace Microsoft.AspNetCore.Mvc.Internal
allParameterPolicies = MvcEndpointInfo.BuildParameterPolicies(routePattern.Parameters, _parameterPolicyFactory);
}
// Replace parameter with literal value
var parameterRouteValue = action.RouteValues[parameterPart.Name];
// Route value could be null if it is a "known" route value.
// Do not use the null value to de-normalize the route pattern,
// instead leave the parameter unchanged.
@ -347,48 +451,22 @@ namespace Microsoft.AspNetCore.Mvc.Internal
}
}
}
// A parameter part was replaced so replace segment with updated parts
if (segmentParts != null)
{
newPathSegments[i] = RoutePatternFactory.Segment(segmentParts);
}
}
var endpoint = CreateEndpoint(
action,
name,
GetPattern(ref patternStringBuilder, newPathSegments),
newPathSegments,
nonInlineDefaults,
routeOrder++,
dataTokens,
suppressLinkGeneration,
suppressPathMatching,
conventions);
endpoints.Add(endpoint);
return routeOrder;
string GetPattern(ref StringBuilder sb, IEnumerable<RoutePatternPathSegment> segments)
// A parameter part was replaced so replace segment with updated parts
if (segmentParts != null)
{
if (sb == null)
{
sb = new StringBuilder();
}
RoutePatternWriter.WriteString(sb, segments);
var rawPattern = sb.ToString();
sb.Length = 0;
return rawPattern;
newPathSegments[i] = RoutePatternFactory.Segment(segmentParts);
}
}
private bool UseDefaultValuePlusRemainingSegmentsOptional(
int segmentIndex,
ActionDescriptor action,
IDictionary<string, string> resolvedRequiredValues,
IReadOnlyDictionary<string, object> allDefaults,
ref RouteValueDictionary nonInlineDefaults,
List<RoutePatternPathSegment> pathSegments)
{
// Check whether the remaining segments are all optional and one or more of them is
@ -403,22 +481,33 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var part = segment.Parts[j];
if (part.IsParameter && part is RoutePatternParameterPart parameterPart)
{
if (parameterPart.IsOptional || parameterPart.IsCatchAll)
if (allDefaults.TryGetValue(parameterPart.Name, out var v))
{
continue;
}
if (action.RouteValues.ContainsKey(parameterPart.Name))
{
if (allDefaults.TryGetValue(parameterPart.Name, out var v)
&& v is string defaultValue
&& action.RouteValues.TryGetValue(parameterPart.Name, out var routeValue)
&& string.Equals(defaultValue, routeValue, StringComparison.OrdinalIgnoreCase))
if (resolvedRequiredValues.TryGetValue(parameterPart.Name, out var routeValue))
{
if (string.Equals(v as string, routeValue, StringComparison.OrdinalIgnoreCase))
{
usedDefaultValue = true;
continue;
}
}
else
{
if (nonInlineDefaults == null)
{
nonInlineDefaults = new RouteValueDictionary();
}
nonInlineDefaults.TryAdd(parameterPart.Name, v);
usedDefaultValue = true;
continue;
}
}
if (parameterPart.IsOptional || parameterPart.IsCatchAll)
{
continue;
}
}
else if (part.IsSeparator && part is RoutePatternSeparatorPart separatorPart
&& separatorPart.Content == ".")
@ -492,6 +581,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
private RouteEndpoint CreateEndpoint(
ActionDescriptor action,
IDictionary<string, string> actionRouteValues,
string routeName,
string patternRawText,
IEnumerable<RoutePatternPathSegment> segments,
@ -513,7 +603,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
};
var defaults = new RouteValueDictionary(nonInlineDefaults);
EnsureRequiredValuesInDefaults(action.RouteValues, defaults);
EnsureRequiredValuesInDefaults(actionRouteValues, defaults, segments);
var model = new RouteEndpointModel(requestDelegate, RoutePatternFactory.Pattern(patternRawText, defaults, parameterPolicies: null, segments), order);
@ -521,7 +611,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
model.Metadata,
action,
routeName,
new RouteValueDictionary(action.RouteValues),
new RouteValueDictionary(actionRouteValues),
dataTokens,
suppressLinkGeneration,
suppressPathMatching);
@ -612,7 +702,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
}
}
// Ensure required values are a subset of defaults
// Ensure route values are a subset of defaults
// Examples:
//
// Template: {controller}/{action}/{category}/{id?}
@ -626,9 +716,12 @@ namespace Microsoft.AspNetCore.Mvc.Internal
// Required values: controller=foo, action=bar
// Final constructed pattern: foo/bar/{category}/{id?}
// Final defaults: controller=foo, action=bar, category=products
private void EnsureRequiredValuesInDefaults(IDictionary<string, string> requiredValues, RouteValueDictionary defaults)
private void EnsureRequiredValuesInDefaults(
IDictionary<string, string> routeValues,
RouteValueDictionary defaults,
IEnumerable<RoutePatternPathSegment> segments)
{
foreach (var kvp in requiredValues)
foreach (var kvp in routeValues)
{
if (kvp.Value != null)
{

View File

@ -40,6 +40,10 @@ namespace Microsoft.AspNetCore.Mvc.Internal
if (parameterPart.IsCatchAll)
{
sb.Append("*");
if (!parameterPart.EncodeSlashes)
{
sb.Append("*");
}
}
sb.Append(parameterPart.Name);
foreach (var item in parameterPart.ParameterPolicies)

View File

@ -146,22 +146,29 @@ namespace Microsoft.AspNetCore.Mvc.Internal
private static TheoryData GetSingleActionData(bool isConventionalRouting)
{
var data = new TheoryData<string, string[]>
var data = new TheoryData<string, string, string[]>
{
{"{controller}/{action}/{id?}", new[] { "TestController/TestAction/{id?}" }},
{"{controller}/{id?}", isConventionalRouting ? new string[] { } : new[] { "TestController/{id?}" }},
{"{action}/{id?}", isConventionalRouting ? new string[] { } : new[] { "TestAction/{id?}" }},
{"{Controller}/{Action}/{id?}", new[] { "TestController/TestAction/{id?}" }},
{"{CONTROLLER}/{ACTION}/{id?}", new[] { "TestController/TestAction/{id?}" }},
{"{controller}/{action=TestAction}", new[] { "TestController", "TestController/TestAction" }},
{"{controller}/{action=TestAction}/{id?}", new[] { "TestController", "TestController/TestAction/{id?}" }},
{"{controller=TestController}/{action=TestAction}/{id?}", new[] { "", "TestController", "TestController/TestAction/{id?}" }},
{"{controller}/{action}/{*catchAll}", new[] { "TestController/TestAction/{*catchAll}" }},
{"{controller}/{action=TestAction}/{*catchAll}", new[] { "TestController", "TestController/TestAction/{*catchAll}" }},
{"{controller}/{action=TestAction}/{id?}/{*catchAll}", new[] { "TestController", "TestController/TestAction/{id?}/{*catchAll}" }},
{"{controller}/{action}.{ext?}", new[] { "TestController/TestAction.{ext?}" }},
{"{controller}/{action=TestAction}.{ext?}", new[] { "TestController", "TestController/TestAction.{ext?}" }},
{"{controller:upper-case}/{action=TestAction}.{ext?}", new[] { "TESTCONTROLLER", "TESTCONTROLLER/TestAction.{ext?}" }},
{"{controller}/{action}/{id?}", null, new[] { "TestController/TestAction/{id?}" }},
{"{controller}/{id?}", null, isConventionalRouting ? new string[] { } : new[] { "TestController/{id?}" }},
{"{action}/{id?}", null, isConventionalRouting ? new string[] { } : new[] { "TestAction/{id?}" }},
{"{Controller}/{Action}/{id?}", null, new[] { "TestController/TestAction/{id?}" }},
{"{Controller}/{Action}/{id?}/{more?}", null, new[] { "TestController/TestAction/{id?}/{more?}" }},
{"{CONTROLLER}/{ACTION}/{id?}", null, new[] { "TestController/TestAction/{id?}" }},
{"{controller}/{action=TestAction}", "TestController/{action=TestAction}", new[] { "TestController", "TestController/TestAction" }},
{"{controller}/{action=TestAction}/{id?}", "TestController/{action=TestAction}/{id?}", new[] { "TestController", "TestController/TestAction/{id?}" }},
{"{controller}/{action=TESTACTION}/{id?}", "TestController/{action=TESTACTION}/{id?}", new[] { "TestController", "TestController/TESTACTION/{id?}" }},
{"{controller}/{action=TestAction}/{id?}/{more}", null, new[] { "TestController/TestAction/{id?}/{more}" }},
{"{controller=TestController}/{action=TestAction}/{id?}", "{controller=TestController}/{action=TestAction}/{id?}", new[] { "", "TestController", "TestController/TestAction/{id?}" }},
{"{controller=TestController}/{action=TestAction}/{id?}/{more?}", "{controller=TestController}/{action=TestAction}/{id?}/{more?}", new[] { "", "TestController", "TestController/TestAction/{id?}/{more?}" }},
{"{controller}/{action}/{*catchAll}", null, new[] { "TestController/TestAction/{*catchAll}" }},
{"{controller}/{action=TestAction}/{*catchAll}", "TestController/{action=TestAction}/{*catchAll}", new[] { "TestController", "TestController/TestAction/{*catchAll}" }},
{"{controller}/{action=TestAction}/{id?}/{*catchAll}", "TestController/{action=TestAction}/{id?}/{*catchAll}", new[] { "TestController", "TestController/TestAction/{id?}/{*catchAll}" }},
{"{controller}/{action=TestAction}/{id?}/{**catchAll}", "TestController/{action=TestAction}/{id?}/{**catchAll}", new[] { "TestController", "TestController/TestAction/{id?}/{**catchAll}" }},
{"{controller}/{action}.{ext?}", null, new[] { "TestController/TestAction.{ext?}" }},
{"{controller}/{action=TestAction}.{ext?}", "TestController/{action=TestAction}.{ext?}", new[] { "TestController", "TestController/TestAction.{ext?}" }},
{"{controller}/{action=TestAction}.{ext?}/{more?}", "TestController/{action=TestAction}.{ext?}/{more?}", new[] { "TestController", "TestController/TestAction.{ext?}/{more?}" }},
{"{controller}/{action=TestAction}.{ext?}/{more}", null, new[] { "TestController/TestAction.{ext?}/{more}" }},
{"{controller:upper-case}/{action:upper-case=TestAction}.{ext?}", "TESTCONTROLLER/{action:upper-case=TestAction}.{ext?}", new[] { "TESTCONTROLLER", "TESTCONTROLLER/TESTACTION.{ext?}" }},
};
return data;
@ -169,7 +176,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
[Theory]
[MemberData(nameof(GetSingleActionData_Conventional))]
public void Endpoints_Conventional_SingleAction(string endpointInfoRoute, string[] finalEndpointPatterns)
public void Endpoints_Conventional_SingleAction(string endpointInfoRoute, string suppressMatchingTemplate, string[] finalEndpointPatterns)
{
// Arrange
var actionDescriptorCollection = GetActionDescriptorCollection(
@ -178,9 +185,17 @@ namespace Microsoft.AspNetCore.Mvc.Internal
dataSource.ConventionalEndpointInfos.Add(CreateEndpointInfo(string.Empty, endpointInfoRoute));
// Act
var endpoints = dataSource.Endpoints;
var endpoints = dataSource.Endpoints.ToList();
// Assert
// Ensure there are no endpoints with duplicate Order values
Assert.DoesNotContain(endpoints.GroupBy(e => Assert.IsType<RouteEndpoint>(e).Order), g => g.Count() > 1);
endpoints = endpoints.OrderBy(e => Assert.IsType<RouteEndpoint>(e).Order).ToList();
AssertSuppressMatchingTemplate(suppressMatchingTemplate, endpoints);
var inspectors = finalEndpointPatterns
.Select(t => new Action<Endpoint>(e => Assert.Equal(t, Assert.IsType<RouteEndpoint>(e).RoutePattern.RawText)))
.ToArray();
@ -191,7 +206,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
[Theory]
[MemberData(nameof(GetSingleActionData_Attribute))]
public void Endpoints_AttributeRouting_SingleAction(string endpointInfoRoute, string[] finalEndpointPatterns)
public void Endpoints_AttributeRouting_SingleAction(string endpointInfoRoute, string suppressMatchingTemplate, string[] finalEndpointPatterns)
{
// Arrange
var actionDescriptorCollection = GetActionDescriptorCollection(
@ -200,7 +215,14 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var dataSource = CreateMvcEndpointDataSource(actionDescriptorCollection);
// Act
var endpoints = dataSource.Endpoints;
var endpoints = dataSource.Endpoints.ToList();
// Ensure there are no endpoints with duplicate Order values
Assert.DoesNotContain(endpoints.GroupBy(e => Assert.IsType<RouteEndpoint>(e).Order), g => g.Count() > 1);
endpoints = endpoints.OrderBy(e => Assert.IsType<RouteEndpoint>(e).Order).ToList();
AssertSuppressMatchingTemplate(suppressMatchingTemplate, endpoints);
// Assert
var inspectors = finalEndpointPatterns
@ -212,14 +234,14 @@ namespace Microsoft.AspNetCore.Mvc.Internal
}
[Theory]
[InlineData("{area}/{controller}/{action}/{id?}", new[] { "TestArea/TestController/TestAction/{id?}" })]
[InlineData("{controller}/{action}/{id?}", new string[] { })]
[InlineData("{area=TestArea}/{controller}/{action}/{id?}", new[] { "TestArea/TestController/TestAction/{id?}" })]
[InlineData("{area=TestArea}/{controller}/{action=TestAction}/{id?}", new[] { "TestArea/TestController", "TestArea/TestController/TestAction/{id?}" })]
[InlineData("{area=TestArea}/{controller=TestController}/{action=TestAction}/{id?}", new[] { "", "TestArea", "TestArea/TestController", "TestArea/TestController/TestAction/{id?}" })]
[InlineData("{area:exists}/{controller}/{action}/{id?}", new[] { "TestArea/TestController/TestAction/{id?}" })]
[InlineData("{area:exists:upper-case}/{controller}/{action}/{id?}", new[] { "TESTAREA/TestController/TestAction/{id?}" })]
public void Endpoints_AreaSingleAction(string endpointInfoRoute, string[] finalEndpointTemplates)
[InlineData("{area}/{controller}/{action}/{id?}", null, new[] { "TestArea/TestController/TestAction/{id?}" })]
[InlineData("{controller}/{action}/{id?}", null, new string[] { })]
[InlineData("{area=TestArea}/{controller}/{action}/{id?}", null, new[] { "TestArea/TestController/TestAction/{id?}" })]
[InlineData("{area=TestArea}/{controller}/{action=TestAction}/{id?}", "TestArea/TestController/{action=TestAction}/{id?}", new[] { "TestArea/TestController", "TestArea/TestController/TestAction/{id?}"})]
[InlineData("{area=TestArea}/{controller=TestController}/{action=TestAction}/{id?}", "{area=TestArea}/{controller=TestController}/{action=TestAction}/{id?}", new[] { "", "TestArea", "TestArea/TestController", "TestArea/TestController/TestAction/{id?}" })]
[InlineData("{area:exists}/{controller}/{action}/{id?}", null, new[] { "TestArea/TestController/TestAction/{id?}" })]
[InlineData("{area:exists:upper-case}/{controller}/{action}/{id?}", null, new[] { "TESTAREA/TestController/TestAction/{id?}" })]
public void Endpoints_AreaSingleAction(string endpointInfoRoute, string suppressMatchingTemplate, string[] finalEndpointTemplates)
{
// Arrange
var actionDescriptorCollection = GetActionDescriptorCollection(
@ -240,9 +262,17 @@ namespace Microsoft.AspNetCore.Mvc.Internal
dataSource.ConventionalEndpointInfos.Add(CreateEndpointInfo(string.Empty, endpointInfoRoute, serviceProvider: services.BuildServiceProvider()));
// Act
var endpoints = dataSource.Endpoints;
var endpoints = dataSource.Endpoints.ToList();
// Assert
// Ensure there are no endpoints with duplicate Order values
Assert.DoesNotContain(endpoints.GroupBy(e => Assert.IsType<RouteEndpoint>(e).Order), g => g.Count() > 1);
endpoints = endpoints.OrderBy(e => Assert.IsType<RouteEndpoint>(e).Order).ToList();
AssertSuppressMatchingTemplate(suppressMatchingTemplate, endpoints);
var inspectors = finalEndpointTemplates
.Select(t => new Action<Endpoint>(e => Assert.Equal(t, Assert.IsType<RouteEndpoint>(e).RoutePattern.RawText)))
.ToArray();
@ -251,6 +281,17 @@ namespace Microsoft.AspNetCore.Mvc.Internal
Assert.Collection(endpoints, inspectors);
}
private static void AssertSuppressMatchingTemplate(string suppressMatchingTemplate, List<Endpoint> endpoints)
{
if (suppressMatchingTemplate != null)
{
var suppressMatchingEndpoint = endpoints.First();
Assert.True(suppressMatchingEndpoint.Metadata.GetMetadata<ISuppressMatchingMetadata>()?.SuppressMatching);
Assert.Equal(suppressMatchingTemplate, Assert.IsType<RouteEndpoint>(suppressMatchingEndpoint).RoutePattern.RawText);
endpoints.Remove(suppressMatchingEndpoint);
}
}
[Fact]
public void Endpoints_SingleAction_ConventionalRoute_ContainsParameterWithNullRequiredRouteValue()
{
@ -304,6 +345,11 @@ namespace Microsoft.AspNetCore.Mvc.Internal
// Assert
Assert.Collection(endpoints,
(e) =>
{
Assert.Equal("TestController/{action=TestAction}", Assert.IsType<RouteEndpoint>(e).RoutePattern.RawText);
Assert.True(e.Metadata.GetMetadata<ISuppressMatchingMetadata>().SuppressMatching);
},
(e) => Assert.Equal("TestController", Assert.IsType<RouteEndpoint>(e).RoutePattern.RawText),
(e) => Assert.Equal("TestController/TestAction", Assert.IsType<RouteEndpoint>(e).RoutePattern.RawText));
}
@ -332,6 +378,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
// Assert
Assert.Collection(endpoints1,
(e) => Assert.Equal("TestController/{action=TestAction}", Assert.IsType<RouteEndpoint>(e).RoutePattern.RawText),
(e) => Assert.Equal("TestController", Assert.IsType<RouteEndpoint>(e).RoutePattern.RawText),
(e) => Assert.Equal("TestController/TestAction", Assert.IsType<RouteEndpoint>(e).RoutePattern.RawText));
Assert.Same(endpoints1, endpoints2);
@ -373,6 +420,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var endpoints = dataSource.Endpoints;
Assert.Collection(endpoints,
(e) => Assert.Equal("TestController/{action=TestAction}", Assert.IsType<RouteEndpoint>(e).RoutePattern.RawText),
(e) => Assert.Equal("TestController", Assert.IsType<RouteEndpoint>(e).RoutePattern.RawText),
(e) => Assert.Equal("TestController/TestAction", Assert.IsType<RouteEndpoint>(e).RoutePattern.RawText));
@ -720,10 +768,29 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var endpoints = dataSource.Endpoints;
// Assert
var endpoint = Assert.Single(endpoints);
var matcherEndpoint = Assert.IsType<RouteEndpoint>(endpoint);
Assert.Equal("Foo/Bar/{subscription=general}", matcherEndpoint.RoutePattern.RawText);
AssertIsSubset(expectedDefaults, matcherEndpoint.RoutePattern.Defaults);
Assert.Collection(
endpoints,
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("Foo/Bar/{subscription=general}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal(1, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, true);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("Foo/Bar", matcherEndpoint.RoutePattern.RawText);
Assert.Equal(2, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("Foo/Bar/{subscription=general}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal(3, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
});
}
[Fact]
@ -780,6 +847,464 @@ namespace Microsoft.AspNetCore.Mvc.Internal
AssertIsSubset(expectedDefaults, matcherEndpoint.RoutePattern.Defaults);
}
[Fact]
public void Endpoints_ConventionalRoutes_NonDefaultAndDefaultValuesEndingWithOptional_IncludeFullRouteAsHighPriority()
{
// Arrange
var actionDescriptorCollection = GetActionDescriptorCollection(
new { controller = "Home", action = "Index" });
var dataSource = CreateMvcEndpointDataSource(actionDescriptorCollection);
dataSource.ConventionalEndpointInfos.Add(CreateEndpointInfo(
name: string.Empty,
template: "{controller}/{action=Index}/{id?}"));
// Act
var endpoints = dataSource.Endpoints;
// Assert
Assert.Collection(
endpoints,
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("Home/{action=Index}/{id?}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal(1, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, true);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("Home", matcherEndpoint.RoutePattern.RawText);
Assert.Equal(2, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("Home/Index/{id?}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal(3, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
});
}
[Fact]
public void Endpoints_ConventionalRoutes_DefaultValuesEndingWithOptional_IncludeFullRouteAsHighPriority()
{
// Arrange
var actionDescriptorCollection = GetActionDescriptorCollection(
new { controller = "Home", action = "Index" });
var dataSource = CreateMvcEndpointDataSource(actionDescriptorCollection);
dataSource.ConventionalEndpointInfos.Add(CreateEndpointInfo(
name: string.Empty,
template: "{controller=Home}/{action=Index}/{id?}"));
// Act
var endpoints = dataSource.Endpoints;
// Assert
Assert.Collection(
endpoints,
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("{controller=Home}/{action=Index}/{id?}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal(1, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, true);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("", matcherEndpoint.RoutePattern.RawText);
Assert.Equal(2, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("Home", matcherEndpoint.RoutePattern.RawText);
Assert.Equal(3, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("Home/Index/{id?}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal(4, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
});
}
[Fact]
public void Endpoints_ConventionalRoutes_DefaultValues_Shortened()
{
// Arrange
var actionDescriptorCollection = GetActionDescriptorCollection(
new { controller = "TestController", action = "TestAction" });
var dataSource = CreateMvcEndpointDataSource(actionDescriptorCollection);
dataSource.ConventionalEndpointInfos.Add(CreateEndpointInfo(
name: string.Empty,
template: "{controller=TestController}/{action=TestAction}/{id=17}"));
// Act
var endpoints = dataSource.Endpoints;
// Assert
Assert.Collection(
endpoints,
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("{controller=TestController}/{action=TestAction}/{id=17}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("17", matcherEndpoint.RoutePattern.Defaults["id"]);
Assert.Equal(1, matcherEndpoint.Order);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("17", matcherEndpoint.RoutePattern.Defaults["id"]);
Assert.Equal(2, matcherEndpoint.Order);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TestController", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("17", matcherEndpoint.RoutePattern.Defaults["id"]);
Assert.Equal(3, matcherEndpoint.Order);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TestController/TestAction", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("17", matcherEndpoint.RoutePattern.Defaults["id"]);
Assert.Equal(4, matcherEndpoint.Order);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TestController/TestAction/{id=17}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("17", matcherEndpoint.RoutePattern.Defaults["id"]);
Assert.Equal(5, matcherEndpoint.Order);
});
}
[Fact]
public void Endpoints_ConventionalRoutes_DefaultValuesAndCatchAll_EndpointInfoDefaultsNotModified()
{
// Arrange
var actionDescriptorCollection = GetActionDescriptorCollection(
new { controller = "TestController", action = "TestAction" });
var dataSource = CreateMvcEndpointDataSource(actionDescriptorCollection);
var endpointInfo = CreateEndpointInfo(
name: string.Empty,
defaults: new RouteValueDictionary(),
template: "{controller=TestController}/{action=TestAction}/{id=17}/{**catchAll}");
dataSource.ConventionalEndpointInfos.Add(endpointInfo);
// Act
var endpoints = dataSource.Endpoints;
// Assert
Assert.Empty(endpointInfo.Defaults);
}
[Fact]
public void Endpoints_ConventionalRoutes_DefaultValuesAndCatchAll_Shortened()
{
// Arrange
var actionDescriptorCollection = GetActionDescriptorCollection(
new { controller = "TestController", action = "TestAction" });
var dataSource = CreateMvcEndpointDataSource(actionDescriptorCollection);
dataSource.ConventionalEndpointInfos.Add(CreateEndpointInfo(
name: string.Empty,
template: "{controller=TestController}/{action=TestAction}/{id=17}/{**catchAll}"));
// Act
var endpoints = dataSource.Endpoints;
// Assert
Assert.Collection(
endpoints,
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("{controller=TestController}/{action=TestAction}/{id=17}/{**catchAll}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("17", matcherEndpoint.RoutePattern.Defaults["id"]);
Assert.Equal(1, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, true);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("17", matcherEndpoint.RoutePattern.Defaults["id"]);
Assert.Equal(2, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TestController", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("17", matcherEndpoint.RoutePattern.Defaults["id"]);
Assert.Equal(3, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TestController/TestAction", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("17", matcherEndpoint.RoutePattern.Defaults["id"]);
Assert.Equal(4, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TestController/TestAction/{id=17}/{**catchAll}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("17", matcherEndpoint.RoutePattern.Defaults["id"]);
Assert.Equal(5, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
});
}
[Fact]
public void Endpoints_ConventionalRoutes_DefaultValuesAndOptional_Shortened()
{
// Arrange
var actionDescriptorCollection = GetActionDescriptorCollection(
new { controller = "TestController", action = "TestAction" });
var dataSource = CreateMvcEndpointDataSource(actionDescriptorCollection);
dataSource.ConventionalEndpointInfos.Add(CreateEndpointInfo(
name: string.Empty,
template: "{controller=TestController}/{action=TestAction}/{id=17}/{more?}"));
// Act
var endpoints = dataSource.Endpoints;
// Assert
Assert.Collection(
endpoints,
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("{controller=TestController}/{action=TestAction}/{id=17}/{more?}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("17", matcherEndpoint.RoutePattern.Defaults["id"]);
Assert.Equal(1, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, true);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("17", matcherEndpoint.RoutePattern.Defaults["id"]);
Assert.Equal(2, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TestController", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("17", matcherEndpoint.RoutePattern.Defaults["id"]);
Assert.Equal(3, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TestController/TestAction", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("17", matcherEndpoint.RoutePattern.Defaults["id"]);
Assert.Equal(4, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TestController/TestAction/{id=17}/{more?}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("17", matcherEndpoint.RoutePattern.Defaults["id"]);
Assert.Equal(5, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
});
}
[Fact]
public void Endpoints_ConventionalRoutes_OptionalExtension_IncludeFullRouteAsHighPriority()
{
// Arrange
var actionDescriptorCollection = GetActionDescriptorCollection(
new { controller = "TestController", action = "TestAction" });
var dataSource = CreateMvcEndpointDataSource(actionDescriptorCollection);
dataSource.ConventionalEndpointInfos.Add(CreateEndpointInfo(
name: string.Empty,
template: "{controller}/{action=TestAction}.{ext?}"));
// Act
var endpoints = dataSource.Endpoints;
// Assert
Assert.Collection(
endpoints,
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TestController/{action=TestAction}.{ext?}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal(1, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, true);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TestController", matcherEndpoint.RoutePattern.RawText);
Assert.Equal(2, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TestController/TestAction.{ext?}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal(3, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
});
}
[Fact]
public void Endpoints_ConventionalRoutes_MultipleOptionalAndCatchAll_IncludeFullRouteAsHighPriority()
{
// Arrange
var actionDescriptorCollection = GetActionDescriptorCollection(
new { controller = "TestController", action = "TestAction" });
var dataSource = CreateMvcEndpointDataSource(actionDescriptorCollection);
dataSource.ConventionalEndpointInfos.Add(CreateEndpointInfo(
name: string.Empty,
template: "{controller=TestController}/{action=TestAction}/{id?}/{more?}/{**catchAll}"));
// Act
var endpoints = dataSource.Endpoints;
// Assert
Assert.Collection(
endpoints,
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("{controller=TestController}/{action=TestAction}/{id?}/{more?}/{**catchAll}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal(1, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, true);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("", matcherEndpoint.RoutePattern.RawText);
Assert.Equal(2, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TestController", matcherEndpoint.RoutePattern.RawText);
Assert.Equal(3, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TestController/TestAction/{id?}/{more?}/{**catchAll}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal(4, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
});
}
[Fact]
public void Endpoints_AttributeRoutes_CatchAllWithDefault_IncludeFullRouteAsHighPriority()
{
// Arrange
var actionDescriptorCollection = GetActionDescriptorCollection(
"/TeamName/{*Name=DefaultName}/",
new { controller = "TestController", action = "TestAction" });
var dataSource = CreateMvcEndpointDataSource(actionDescriptorCollection);
// Act
var endpoints = dataSource.Endpoints;
// Assert
Assert.Collection(
endpoints,
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TeamName/{*Name=DefaultName}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal(0, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, true);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TeamName", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("DefaultName", matcherEndpoint.RoutePattern.Defaults["Name"]);
Assert.Equal(1, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TeamName/{*Name=DefaultName}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("DefaultName", matcherEndpoint.RoutePattern.Defaults["Name"]);
Assert.Equal(2, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
});
}
[Fact]
public void Endpoints_AttributeRoutes_DefaultDifferentCaseFromRouteValue_UseDefaultCase()
{
// Arrange
var actionDescriptorCollection = GetActionDescriptorCollection(
"{controller}/{action=TESTACTION}/{id?}",
new { controller = "TestController", action = "TestAction" });
var dataSource = CreateMvcEndpointDataSource(actionDescriptorCollection);
// Act
var endpoints = dataSource.Endpoints;
// Assert
Assert.Collection(
endpoints,
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TestController/{action=TESTACTION}/{id?}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("TESTACTION", matcherEndpoint.RoutePattern.Defaults["action"]);
Assert.Equal(0, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, true);
var routeValuesAddress = matcherEndpoint.Metadata.GetMetadata<IRouteValuesAddressMetadata>();
Assert.Equal("TESTACTION", routeValuesAddress.RequiredValues["action"]);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TestController", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("TESTACTION", matcherEndpoint.RoutePattern.Defaults["action"]);
Assert.Equal(1, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
var routeValuesAddress = matcherEndpoint.Metadata.GetMetadata<IRouteValuesAddressMetadata>();
Assert.Equal("TESTACTION", routeValuesAddress.RequiredValues["action"]);
},
(ep) =>
{
var matcherEndpoint = Assert.IsType<RouteEndpoint>(ep);
Assert.Equal("TestController/TESTACTION/{id?}", matcherEndpoint.RoutePattern.RawText);
Assert.Equal("TESTACTION", matcherEndpoint.RoutePattern.Defaults["action"]);
Assert.Equal(2, matcherEndpoint.Order);
AssertMatchingSuppressed(matcherEndpoint, false);
var routeValuesAddress = matcherEndpoint.Metadata.GetMetadata<IRouteValuesAddressMetadata>();
Assert.Equal("TESTACTION", routeValuesAddress.RequiredValues["action"]);
});
}
private MvcEndpointDataSource CreateMvcEndpointDataSource(
IActionDescriptorCollectionProvider actionDescriptorCollectionProvider = null,
MvcEndpointInvokerFactory mvcEndpointInvokerFactory = null)
@ -904,5 +1429,11 @@ namespace Microsoft.AspNetCore.Mvc.Internal
Assert.Equal(subsetPair.Value, fullSetPairValue);
}
}
private void AssertMatchingSuppressed(Endpoint endpoint, bool suppressed)
{
var isEndpointSuppressed = endpoint.Metadata.GetMetadata<ISuppressMatchingMetadata>()?.SuppressMatching ?? false;
Assert.Equal(suppressed, isEndpointSuppressed);
}
}
}

View File

@ -1041,6 +1041,136 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
Assert.Equal("Departments", result.RouteName);
}
[Fact]
public async Task ConventionalRoutedAction_DefaultValues_OptionalParameter_LinkToDefaultValuePath()
{
// Arrange
var url = LinkFrom("http://localhost/DefaultValuesRoute/Optional")
.To(new { });
// Act
var response = await Client.GetAsync(url);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
Assert.Equal("DefaultValues", result.Controller);
Assert.Equal("OptionalParameter", result.Action);
Assert.Equal("/DefaultValuesRoute/Optional", result.Link);
}
[Fact]
public async Task ConventionalRoutedAction_DefaultValues_OptionalParameter_LinkToFullPath()
{
// Arrange
var url = LinkFrom("http://localhost/DefaultValuesRoute/Optional")
.To(new { id = "123" });
// Act
var response = await Client.GetAsync(url);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
Assert.Equal("DefaultValues", result.Controller);
Assert.Equal("OptionalParameter", result.Action);
Assert.Equal("/DefaultValuesRoute/Optional/DEFAULTVALUES/OPTIONALPARAMETER/123", result.Link);
}
[Fact]
public async Task ConventionalRoutedAction_DefaultValues_DefaultParameter_LinkToDefaultValuePath()
{
// Arrange
var url = LinkFrom("http://localhost/DefaultValuesRoute/Default")
.To(new { });
// Act
var response = await Client.GetAsync(url);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
Assert.Equal("DefaultValues", result.Controller);
Assert.Equal("DefaultParameter", result.Action);
Assert.Equal("17", result.RouteValues["id"]);
Assert.Equal("/DefaultValuesRoute/Default", result.Link);
}
[Fact]
public async Task ConventionalRoutedAction_DefaultValues_DefaultParameterWithCatchAll_LinkToDefaultValuePath()
{
// Arrange
var url = LinkFrom("http://localhost/DefaultValuesRoute/Default")
.To(new { catchAll = "CatchAll" });
// Act
var response = await Client.GetAsync(url);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
Assert.Equal("DefaultValues", result.Controller);
Assert.Equal("DefaultParameter", result.Action);
Assert.Equal("17", result.RouteValues["id"]);
Assert.Equal("/DefaultValuesRoute/Default/DEFAULTVALUES/DEFAULTPARAMETER/17/CatchAll", result.Link);
}
[Fact]
public async Task ConventionalRoutedAction_DefaultValues_DefaultParameter_LinkToFullPath()
{
// Arrange
var url = LinkFrom("http://localhost/DefaultValuesRoute/Default")
.To(new { id = "123" });
// Act
var response = await Client.GetAsync(url);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
Assert.Equal("DefaultValues", result.Controller);
Assert.Equal("DefaultParameter", result.Action);
Assert.Equal("17", result.RouteValues["id"]);
Assert.Equal("/DefaultValuesRoute/Default/DEFAULTVALUES/DEFAULTPARAMETER/123", result.Link);
}
[Fact]
public async Task ConventionalRoutedAction_DefaultValues_DefaultParameterMatches_LinkToShortenedPath()
{
// Arrange
var url = LinkFrom("http://localhost/DefaultValuesRoute/Default/DefaultValues/DefaultParameter/123")
.To(new { id = "17" });
// Act
var response = await Client.GetAsync(url);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
Assert.Equal("DefaultValues", result.Controller);
Assert.Equal("DefaultParameter", result.Action);
Assert.Equal("123", result.RouteValues["id"]);
Assert.Equal("/DefaultValuesRoute/Default", result.Link);
}
[Fact]
public virtual async Task ConventionalRoutedAction_LinkToArea()
{

View File

@ -0,0 +1,34 @@
// 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.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
namespace RoutingWebSite
{
public class DefaultValuesController : Controller
{
private readonly TestResponseGenerator _generator;
public DefaultValuesController(TestResponseGenerator generator)
{
_generator = generator;
}
public IActionResult DefaultParameter(string id)
{
return _generator.Generate(id == null
? "/DefaultValuesRoute/DefaultValues"
: "/DefaultValuesRoute/DefaultValues/DefaultParameter/Index/" + id);
}
public IActionResult OptionalParameter(string id)
{
return _generator.Generate(id == "17"
? "/DefaultValuesRoute/DefaultValues"
: "/DefaultValuesRoute/DefaultValues/OptionalParameter/Index/" + id);
}
}
}

View File

@ -62,6 +62,18 @@ namespace RoutingWebSite
defaults: null,
constraints: new { controller = "ConventionalTransformer" });
routes.MapRoute(
"DefaultValuesRoute_OptionalParameter",
"DefaultValuesRoute/Optional/{controller=DEFAULTVALUES}/{action=OPTIONALPARAMETER}/{id?}/{**catchAll}",
defaults: null,
constraints: new { controller = "DefaultValues", action = "OptionalParameter" });
routes.MapRoute(
"DefaultValuesRoute_DefaultParameter",
"DefaultValuesRoute/Default/{controller=DEFAULTVALUES}/{action=DEFAULTPARAMETER}/{id=17}/{**catchAll}",
defaults: null,
constraints: new { controller = "DefaultValues", action = "DefaultParameter" });
routes.MapAreaRoute(
"flightRoute",
"adminRoute",

View File

@ -1,14 +1,11 @@
// 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.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
@ -48,7 +45,7 @@ namespace RoutingWebSite
new ControllerToRemove
{
ControllerType = typeof(PageRouteController),
Actions = new [] { nameof(PageRouteController.AttributeRoute) }
Actions = new[] { nameof(PageRouteController.AttributeRoute) }
});
services.TryAddEnumerable(ServiceDescriptor.Singleton<IActionDescriptorProvider>(actionDescriptorProvider));
}
@ -64,6 +61,18 @@ namespace RoutingWebSite
constraints: new { controller = "DataTokens" },
dataTokens: new { hasDataTokens = true });
routes.MapRoute(
"DefaultValuesRoute_OptionalParameter",
"DefaultValuesRoute/Optional/{controller=DEFAULTVALUES}/{action=OPTIONALPARAMETER}/{id?}/{**catchAll}",
defaults: null,
constraints: new { controller = "DefaultValues", action = "OptionalParameter" });
routes.MapRoute(
"DefaultValuesRoute_DefaultParameter",
"DefaultValuesRoute/Default/{controller=DEFAULTVALUES}/{action=DEFAULTPARAMETER}/{id=17}/{**catchAll}",
defaults: null,
constraints: new { controller = "DefaultValues", action = "DefaultParameter" });
routes.MapAreaRoute(
"flightRoute",
"adminRoute",