Add MvcEndpointDataSource and functional tests (#7886)
This commit is contained in:
parent
287a3c5e69
commit
a7406d4497
15
Mvc.sln
15
Mvc.sln
|
|
@ -172,6 +172,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RazorPagesClassLibrary", "t
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Views.TestCommon", "test\Microsoft.AspNetCore.Mvc.Views.TestCommon\Microsoft.AspNetCore.Mvc.Views.TestCommon.csproj", "{51E3E785-A9D1-4196-BAFE-A17FF4304B89}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DispatchingWebSite", "test\WebSites\DispatchingWebSite\DispatchingWebSite.csproj", "{ABB3737F-E518-4E40-8A9C-F3281D610E8F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -906,6 +908,18 @@ Global
|
|||
{51E3E785-A9D1-4196-BAFE-A17FF4304B89}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{51E3E785-A9D1-4196-BAFE-A17FF4304B89}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{51E3E785-A9D1-4196-BAFE-A17FF4304B89}.Release|x86.Build.0 = Release|Any CPU
|
||||
{ABB3737F-E518-4E40-8A9C-F3281D610E8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ABB3737F-E518-4E40-8A9C-F3281D610E8F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ABB3737F-E518-4E40-8A9C-F3281D610E8F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{ABB3737F-E518-4E40-8A9C-F3281D610E8F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{ABB3737F-E518-4E40-8A9C-F3281D610E8F}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{ABB3737F-E518-4E40-8A9C-F3281D610E8F}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{ABB3737F-E518-4E40-8A9C-F3281D610E8F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ABB3737F-E518-4E40-8A9C-F3281D610E8F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{ABB3737F-E518-4E40-8A9C-F3281D610E8F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{ABB3737F-E518-4E40-8A9C-F3281D610E8F}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{ABB3737F-E518-4E40-8A9C-F3281D610E8F}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{ABB3737F-E518-4E40-8A9C-F3281D610E8F}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -976,6 +990,7 @@ Global
|
|||
{E83D3745-9BCF-40E8-8D34-AFBA604C2439} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
||||
{17122147-ADFD-41C8-87D9-CCC582CCA8F9} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
{51E3E785-A9D1-4196-BAFE-A17FF4304B89} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
||||
{ABB3737F-E518-4E40-8A9C-F3281D610E8F} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {63D344F6-F86D-40E6-85B9-0AABBE338C4A}
|
||||
|
|
|
|||
|
|
@ -5,91 +5,91 @@
|
|||
<PropertyGroup Label="Package Versions">
|
||||
<AngleSharpPackageVersion>0.9.9</AngleSharpPackageVersion>
|
||||
<BenchmarkDotNetPackageVersion>0.10.13</BenchmarkDotNetPackageVersion>
|
||||
<InternalAspNetCoreAnalyzersPackageVersion>2.2.0-preview1-34425</InternalAspNetCoreAnalyzersPackageVersion>
|
||||
<InternalAspNetCoreAnalyzersPackageVersion>2.2.0-preview1-34462</InternalAspNetCoreAnalyzersPackageVersion>
|
||||
<InternalAspNetCoreSdkPackageVersion>2.2.0-preview1-17082</InternalAspNetCoreSdkPackageVersion>
|
||||
<MicrosoftAspNetCoreAnalyzerTestingPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreAnalyzerTestingPackageVersion>
|
||||
<MicrosoftAspNetCoreAntiforgeryPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreAntiforgeryPackageVersion>
|
||||
<MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>
|
||||
<MicrosoftAspNetCoreAuthenticationCorePackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreAuthenticationCorePackageVersion>
|
||||
<MicrosoftAspNetCoreAuthenticationPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreAuthenticationPackageVersion>
|
||||
<MicrosoftAspNetCoreAuthorizationPolicyPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreAuthorizationPolicyPackageVersion>
|
||||
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreChunkingCookieManagerSourcesPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreChunkingCookieManagerSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreCookiePolicyPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreCookiePolicyPackageVersion>
|
||||
<MicrosoftAspNetCoreCorsPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreCorsPackageVersion>
|
||||
<MicrosoftAspNetCoreDiagnosticsAbstractionsPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreDiagnosticsAbstractionsPackageVersion>
|
||||
<MicrosoftAspNetCoreDiagnosticsPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreDiagnosticsPackageVersion>
|
||||
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
|
||||
<MicrosoftAspNetCoreHostingPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreHostingPackageVersion>
|
||||
<MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>
|
||||
<MicrosoftAspNetCoreHttpExtensionsPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreHttpExtensionsPackageVersion>
|
||||
<MicrosoftAspNetCoreHttpPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreHttpPackageVersion>
|
||||
<MicrosoftAspNetCoreJsonPatchPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreJsonPatchPackageVersion>
|
||||
<MicrosoftAspNetCoreLocalizationPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreLocalizationPackageVersion>
|
||||
<MicrosoftAspNetCoreLocalizationRoutingPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreLocalizationRoutingPackageVersion>
|
||||
<MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>
|
||||
<MicrosoftAspNetCoreRangeHelperSourcesPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreRangeHelperSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreRazorDesignPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreRazorDesignPackageVersion>
|
||||
<MicrosoftAspNetCoreRazorLanguagePackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreRazorLanguagePackageVersion>
|
||||
<MicrosoftAspNetCoreRazorRuntimePackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreRazorRuntimePackageVersion>
|
||||
<MicrosoftAspNetCoreRazorTagHelpersTestingSourcesPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreRazorTagHelpersTestingSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreResponseCachingAbstractionsPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreResponseCachingAbstractionsPackageVersion>
|
||||
<MicrosoftAspNetCoreResponseCachingPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreResponseCachingPackageVersion>
|
||||
<MicrosoftAspNetCoreRoutingAbstractionsPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreRoutingAbstractionsPackageVersion>
|
||||
<MicrosoftAspNetCoreRoutingPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreRoutingPackageVersion>
|
||||
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
|
||||
<MicrosoftAspNetCoreServerKestrelPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreServerKestrelPackageVersion>
|
||||
<MicrosoftAspNetCoreSessionPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreSessionPackageVersion>
|
||||
<MicrosoftAspNetCoreStaticFilesPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreStaticFilesPackageVersion>
|
||||
<MicrosoftAspNetCoreTestHostPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreTestHostPackageVersion>
|
||||
<MicrosoftAspNetCoreTestingPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreTestingPackageVersion>
|
||||
<MicrosoftAspNetCoreWebUtilitiesPackageVersion>2.2.0-preview1-34425</MicrosoftAspNetCoreWebUtilitiesPackageVersion>
|
||||
<MicrosoftAspNetCoreAnalyzerTestingPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreAnalyzerTestingPackageVersion>
|
||||
<MicrosoftAspNetCoreAntiforgeryPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreAntiforgeryPackageVersion>
|
||||
<MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>
|
||||
<MicrosoftAspNetCoreAuthenticationCorePackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreAuthenticationCorePackageVersion>
|
||||
<MicrosoftAspNetCoreAuthenticationPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreAuthenticationPackageVersion>
|
||||
<MicrosoftAspNetCoreAuthorizationPolicyPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreAuthorizationPolicyPackageVersion>
|
||||
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreChunkingCookieManagerSourcesPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreChunkingCookieManagerSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreCookiePolicyPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreCookiePolicyPackageVersion>
|
||||
<MicrosoftAspNetCoreCorsPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreCorsPackageVersion>
|
||||
<MicrosoftAspNetCoreDiagnosticsAbstractionsPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreDiagnosticsAbstractionsPackageVersion>
|
||||
<MicrosoftAspNetCoreDiagnosticsPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreDiagnosticsPackageVersion>
|
||||
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
|
||||
<MicrosoftAspNetCoreHostingPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreHostingPackageVersion>
|
||||
<MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>
|
||||
<MicrosoftAspNetCoreHttpExtensionsPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreHttpExtensionsPackageVersion>
|
||||
<MicrosoftAspNetCoreHttpPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreHttpPackageVersion>
|
||||
<MicrosoftAspNetCoreJsonPatchPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreJsonPatchPackageVersion>
|
||||
<MicrosoftAspNetCoreLocalizationPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreLocalizationPackageVersion>
|
||||
<MicrosoftAspNetCoreLocalizationRoutingPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreLocalizationRoutingPackageVersion>
|
||||
<MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>
|
||||
<MicrosoftAspNetCoreRangeHelperSourcesPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreRangeHelperSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreRazorDesignPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreRazorDesignPackageVersion>
|
||||
<MicrosoftAspNetCoreRazorLanguagePackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreRazorLanguagePackageVersion>
|
||||
<MicrosoftAspNetCoreRazorRuntimePackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreRazorRuntimePackageVersion>
|
||||
<MicrosoftAspNetCoreRazorTagHelpersTestingSourcesPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreRazorTagHelpersTestingSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreResponseCachingAbstractionsPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreResponseCachingAbstractionsPackageVersion>
|
||||
<MicrosoftAspNetCoreResponseCachingPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreResponseCachingPackageVersion>
|
||||
<MicrosoftAspNetCoreRoutingAbstractionsPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreRoutingAbstractionsPackageVersion>
|
||||
<MicrosoftAspNetCoreRoutingPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreRoutingPackageVersion>
|
||||
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
|
||||
<MicrosoftAspNetCoreServerKestrelPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreServerKestrelPackageVersion>
|
||||
<MicrosoftAspNetCoreSessionPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreSessionPackageVersion>
|
||||
<MicrosoftAspNetCoreStaticFilesPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreStaticFilesPackageVersion>
|
||||
<MicrosoftAspNetCoreTestHostPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreTestHostPackageVersion>
|
||||
<MicrosoftAspNetCoreTestingPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreTestingPackageVersion>
|
||||
<MicrosoftAspNetCoreWebUtilitiesPackageVersion>2.2.0-preview1-34462</MicrosoftAspNetCoreWebUtilitiesPackageVersion>
|
||||
<MicrosoftAspNetWebApiClientPackageVersion>5.2.6</MicrosoftAspNetWebApiClientPackageVersion>
|
||||
<MicrosoftCodeAnalysisCSharpPackageVersion>2.8.0</MicrosoftCodeAnalysisCSharpPackageVersion>
|
||||
<MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>2.8.0</MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>
|
||||
<MicrosoftCodeAnalysisRazorPackageVersion>2.2.0-preview1-34425</MicrosoftCodeAnalysisRazorPackageVersion>
|
||||
<MicrosoftCodeAnalysisRazorPackageVersion>2.2.0-preview1-34462</MicrosoftCodeAnalysisRazorPackageVersion>
|
||||
<MicrosoftDiaSymReaderNativePackageVersion>1.7.0</MicrosoftDiaSymReaderNativePackageVersion>
|
||||
<MicrosoftExtensionsCachingMemoryPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsCachingMemoryPackageVersion>
|
||||
<MicrosoftExtensionsClosedGenericMatcherSourcesPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsClosedGenericMatcherSourcesPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationJsonPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsConfigurationJsonPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsConfigurationPackageVersion>
|
||||
<MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
||||
<MicrosoftExtensionsDependencyModelPackageVersion>2.2.0-preview1-26606-01</MicrosoftExtensionsDependencyModelPackageVersion>
|
||||
<MicrosoftExtensionsDiagnosticAdapterPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsDiagnosticAdapterPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersCompositePackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsFileProvidersCompositePackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>
|
||||
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
|
||||
<MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>
|
||||
<MicrosoftExtensionsLocalizationPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsLocalizationPackageVersion>
|
||||
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsLoggingConsolePackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsLoggingConsolePackageVersion>
|
||||
<MicrosoftExtensionsLoggingDebugPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsLoggingDebugPackageVersion>
|
||||
<MicrosoftExtensionsLoggingPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsLoggingPackageVersion>
|
||||
<MicrosoftExtensionsLoggingTestingPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsLoggingTestingPackageVersion>
|
||||
<MicrosoftExtensionsObjectMethodExecutorSourcesPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsObjectMethodExecutorSourcesPackageVersion>
|
||||
<MicrosoftExtensionsOptionsPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsOptionsPackageVersion>
|
||||
<MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion>
|
||||
<MicrosoftExtensionsPrimitivesPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsPrimitivesPackageVersion>
|
||||
<MicrosoftExtensionsPropertyActivatorSourcesPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsPropertyActivatorSourcesPackageVersion>
|
||||
<MicrosoftExtensionsPropertyHelperSourcesPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsPropertyHelperSourcesPackageVersion>
|
||||
<MicrosoftExtensionsSecurityHelperSourcesPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsSecurityHelperSourcesPackageVersion>
|
||||
<MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>
|
||||
<MicrosoftExtensionsValueStopwatchSourcesPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsValueStopwatchSourcesPackageVersion>
|
||||
<MicrosoftExtensionsWebEncodersPackageVersion>2.2.0-preview1-34425</MicrosoftExtensionsWebEncodersPackageVersion>
|
||||
<MicrosoftExtensionsCachingMemoryPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsCachingMemoryPackageVersion>
|
||||
<MicrosoftExtensionsClosedGenericMatcherSourcesPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsClosedGenericMatcherSourcesPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationJsonPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsConfigurationJsonPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsConfigurationPackageVersion>
|
||||
<MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
||||
<MicrosoftExtensionsDependencyModelPackageVersion>2.2.0-preview1-26612-04</MicrosoftExtensionsDependencyModelPackageVersion>
|
||||
<MicrosoftExtensionsDiagnosticAdapterPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsDiagnosticAdapterPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersCompositePackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsFileProvidersCompositePackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>
|
||||
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
|
||||
<MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>
|
||||
<MicrosoftExtensionsLocalizationPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsLocalizationPackageVersion>
|
||||
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsLoggingConsolePackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsLoggingConsolePackageVersion>
|
||||
<MicrosoftExtensionsLoggingDebugPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsLoggingDebugPackageVersion>
|
||||
<MicrosoftExtensionsLoggingPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsLoggingPackageVersion>
|
||||
<MicrosoftExtensionsLoggingTestingPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsLoggingTestingPackageVersion>
|
||||
<MicrosoftExtensionsObjectMethodExecutorSourcesPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsObjectMethodExecutorSourcesPackageVersion>
|
||||
<MicrosoftExtensionsOptionsPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsOptionsPackageVersion>
|
||||
<MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion>
|
||||
<MicrosoftExtensionsPrimitivesPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsPrimitivesPackageVersion>
|
||||
<MicrosoftExtensionsPropertyActivatorSourcesPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsPropertyActivatorSourcesPackageVersion>
|
||||
<MicrosoftExtensionsPropertyHelperSourcesPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsPropertyHelperSourcesPackageVersion>
|
||||
<MicrosoftExtensionsSecurityHelperSourcesPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsSecurityHelperSourcesPackageVersion>
|
||||
<MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>
|
||||
<MicrosoftExtensionsValueStopwatchSourcesPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsValueStopwatchSourcesPackageVersion>
|
||||
<MicrosoftExtensionsWebEncodersPackageVersion>2.2.0-preview1-34462</MicrosoftExtensionsWebEncodersPackageVersion>
|
||||
<MicrosoftNETCoreApp20PackageVersion>2.0.0</MicrosoftNETCoreApp20PackageVersion>
|
||||
<MicrosoftNETCoreApp21PackageVersion>2.1.0</MicrosoftNETCoreApp21PackageVersion>
|
||||
<MicrosoftNETCoreApp22PackageVersion>2.2.0-preview1-26606-01</MicrosoftNETCoreApp22PackageVersion>
|
||||
<MicrosoftNetHttpHeadersPackageVersion>2.2.0-preview1-34425</MicrosoftNetHttpHeadersPackageVersion>
|
||||
<MicrosoftNETSdkRazorPackageVersion>2.2.0-preview1-34425</MicrosoftNETSdkRazorPackageVersion>
|
||||
<MicrosoftNETCoreApp22PackageVersion>2.2.0-preview1-26612-04</MicrosoftNETCoreApp22PackageVersion>
|
||||
<MicrosoftNetHttpHeadersPackageVersion>2.2.0-preview1-34462</MicrosoftNetHttpHeadersPackageVersion>
|
||||
<MicrosoftNETSdkRazorPackageVersion>2.2.0-preview1-34462</MicrosoftNETSdkRazorPackageVersion>
|
||||
<MicrosoftNETTestSdkPackageVersion>15.6.1</MicrosoftNETTestSdkPackageVersion>
|
||||
<MoqPackageVersion>4.7.49</MoqPackageVersion>
|
||||
<NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion>
|
||||
<NewtonsoftJsonBsonPackageVersion>1.0.1</NewtonsoftJsonBsonPackageVersion>
|
||||
<SystemComponentModelAnnotationsPackageVersion>4.6.0-preview1-26605-01</SystemComponentModelAnnotationsPackageVersion>
|
||||
<SystemDiagnosticsDiagnosticSourcePackageVersion>4.6.0-preview1-26605-01</SystemDiagnosticsDiagnosticSourcePackageVersion>
|
||||
<SystemThreadingTasksExtensionsPackageVersion>4.6.0-preview1-26605-01</SystemThreadingTasksExtensionsPackageVersion>
|
||||
<SystemComponentModelAnnotationsPackageVersion>4.6.0-preview1-26611-02</SystemComponentModelAnnotationsPackageVersion>
|
||||
<SystemDiagnosticsDiagnosticSourcePackageVersion>4.6.0-preview1-26611-02</SystemDiagnosticsDiagnosticSourcePackageVersion>
|
||||
<SystemThreadingTasksExtensionsPackageVersion>4.6.0-preview1-26611-02</SystemThreadingTasksExtensionsPackageVersion>
|
||||
<XunitAnalyzersPackageVersion>0.8.0</XunitAnalyzersPackageVersion>
|
||||
<XunitPackageVersion>2.3.1</XunitPackageVersion>
|
||||
<XunitRunnerVisualStudioPackageVersion>2.4.0-beta.1.build3945</XunitRunnerVisualStudioPackageVersion>
|
||||
|
|
|
|||
|
|
@ -260,6 +260,13 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
services.TryAddSingleton<MvcRouteHandler>(); // Only one per app
|
||||
services.TryAddTransient<MvcAttributeRouteHandler>(); // Many per app
|
||||
|
||||
//
|
||||
// Dispatching
|
||||
//
|
||||
services.TryAddEnumerable(
|
||||
ServiceDescriptor.Singleton<EndpointDataSource, MvcEndpointDataSource>());
|
||||
services.TryAddSingleton<MvcEndpointInvokerFactory>();
|
||||
|
||||
//
|
||||
// Middleware pipeline filter related
|
||||
//
|
||||
|
|
|
|||
|
|
@ -0,0 +1,139 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Routing.EndpointConstraints;
|
||||
using Microsoft.AspNetCore.Routing.Matchers;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Internal
|
||||
{
|
||||
internal class MvcEndpointDataSource : EndpointDataSource
|
||||
{
|
||||
private readonly IActionDescriptorCollectionProvider _actions;
|
||||
private readonly MvcEndpointInvokerFactory _invokerFactory;
|
||||
private readonly IActionDescriptorChangeProvider[] _actionDescriptorChangeProviders;
|
||||
private readonly List<Endpoint> _endpoints;
|
||||
|
||||
private IChangeToken _changeToken;
|
||||
|
||||
public MvcEndpointDataSource(
|
||||
IActionDescriptorCollectionProvider actions,
|
||||
MvcEndpointInvokerFactory invokerFactory,
|
||||
IEnumerable<IActionDescriptorChangeProvider> actionDescriptorChangeProviders)
|
||||
{
|
||||
if (actions == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(actions));
|
||||
}
|
||||
|
||||
if (invokerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(invokerFactory));
|
||||
}
|
||||
|
||||
if (actionDescriptorChangeProviders == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(actionDescriptorChangeProviders));
|
||||
}
|
||||
|
||||
_actions = actions;
|
||||
_invokerFactory = invokerFactory;
|
||||
_actionDescriptorChangeProviders = actionDescriptorChangeProviders.ToArray();
|
||||
|
||||
_endpoints = new List<Endpoint>();
|
||||
|
||||
InitializeEndpoints();
|
||||
}
|
||||
|
||||
private void InitializeEndpoints()
|
||||
{
|
||||
// note: this code has haxxx. This will only work in some constrained scenarios
|
||||
foreach (var action in _actions.ActionDescriptors.Items)
|
||||
{
|
||||
if (action.AttributeRouteInfo == null)
|
||||
{
|
||||
// Action does not have an attribute route
|
||||
continue;
|
||||
}
|
||||
|
||||
RequestDelegate invokerDelegate = (context) =>
|
||||
{
|
||||
var values = context.Features.Get<IEndpointFeature>().Values;
|
||||
var routeData = new RouteData();
|
||||
foreach (var kvp in values)
|
||||
{
|
||||
routeData.Values.Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
|
||||
var actionContext = new ActionContext(context, routeData, action);
|
||||
|
||||
var invoker = _invokerFactory.CreateInvoker(actionContext);
|
||||
return invoker.InvokeAsync();
|
||||
};
|
||||
|
||||
var metadata = new List<object>();
|
||||
|
||||
// Add filter descriptors to endpoint metadata
|
||||
metadata.AddRange(action.FilterDescriptors.OrderBy(f => f, FilterDescriptorOrderComparer.Comparer).Select(f => f.Filter));
|
||||
|
||||
if (action.ActionConstraints != null && action.ActionConstraints.Count > 0)
|
||||
{
|
||||
foreach (var actionConstraint in action.ActionConstraints)
|
||||
{
|
||||
if (actionConstraint is HttpMethodActionConstraint httpMethodActionConstraint)
|
||||
{
|
||||
metadata.Add(new HttpMethodEndpointConstraint(httpMethodActionConstraint.HttpMethods));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var metadataCollection = new EndpointMetadataCollection(metadata);
|
||||
|
||||
_endpoints.Add(new MatcherEndpoint(
|
||||
next => invokerDelegate,
|
||||
action.AttributeRouteInfo.Template,
|
||||
action.RouteValues,
|
||||
action.AttributeRouteInfo.Order,
|
||||
metadataCollection,
|
||||
action.DisplayName));
|
||||
}
|
||||
}
|
||||
|
||||
private IChangeToken GetCompositeChangeToken()
|
||||
{
|
||||
if (_actionDescriptorChangeProviders.Length == 1)
|
||||
{
|
||||
return _actionDescriptorChangeProviders[0].GetChangeToken();
|
||||
}
|
||||
|
||||
var changeTokens = new IChangeToken[_actionDescriptorChangeProviders.Length];
|
||||
for (var i = 0; i < _actionDescriptorChangeProviders.Length; i++)
|
||||
{
|
||||
changeTokens[i] = _actionDescriptorChangeProviders[i].GetChangeToken();
|
||||
}
|
||||
|
||||
return new CompositeChangeToken(changeTokens);
|
||||
}
|
||||
|
||||
public override IChangeToken ChangeToken
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_changeToken == null)
|
||||
{
|
||||
_changeToken = GetCompositeChangeToken();
|
||||
}
|
||||
|
||||
return _changeToken;
|
||||
}
|
||||
}
|
||||
|
||||
public override IReadOnlyList<Endpoint> Endpoints => _endpoints;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Internal
|
||||
{
|
||||
internal sealed class MvcEndpointInvokerFactory : IActionInvokerFactory
|
||||
{
|
||||
private readonly IActionInvokerFactory _invokerFactory;
|
||||
private readonly IActionContextAccessor _actionContextAccessor;
|
||||
|
||||
public MvcEndpointInvokerFactory(
|
||||
IActionInvokerFactory invokerFactory)
|
||||
: this(invokerFactory, actionContextAccessor: null)
|
||||
{
|
||||
}
|
||||
|
||||
public MvcEndpointInvokerFactory(
|
||||
IActionInvokerFactory invokerFactory,
|
||||
IActionContextAccessor actionContextAccessor)
|
||||
{
|
||||
_invokerFactory = invokerFactory;
|
||||
|
||||
// The IActionContextAccessor is optional. We want to avoid the overhead of using CallContext
|
||||
// if possible.
|
||||
_actionContextAccessor = actionContextAccessor;
|
||||
}
|
||||
|
||||
public IActionInvoker CreateInvoker(ActionContext actionContext)
|
||||
{
|
||||
if (_actionContextAccessor != null)
|
||||
{
|
||||
_actionContextAccessor.ActionContext = actionContext;
|
||||
}
|
||||
|
||||
return _invokerFactory.CreateInvoker(actionContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -306,6 +306,13 @@ namespace Microsoft.AspNetCore.Mvc
|
|||
typeof(ApiBehaviorApplicationModelProvider),
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(EndpointDataSource),
|
||||
new Type[]
|
||||
{
|
||||
typeof(MvcEndpointDataSource),
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,170 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.Routing;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Routing.Matchers;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Core.Test.Internal
|
||||
{
|
||||
public class MvcEndpointDataSourceTests
|
||||
{
|
||||
[Fact]
|
||||
public void Endpoints_AccessParameters_InitializedFromProvider()
|
||||
{
|
||||
// Arrange
|
||||
var routeValue = "Value";
|
||||
var routeValues = new Dictionary<string, string>
|
||||
{
|
||||
["Name"] = routeValue
|
||||
};
|
||||
var displayName = "DisplayName!";
|
||||
var order = 1;
|
||||
var template = "/Template!";
|
||||
var filterDescriptor = new FilterDescriptor(new ControllerActionFilter(), 1);
|
||||
|
||||
var mockDescriptorProvider = new Mock<IActionDescriptorCollectionProvider>();
|
||||
mockDescriptorProvider.Setup(m => m.ActionDescriptors).Returns(new ActionDescriptorCollection(new List<ActionDescriptor>
|
||||
{
|
||||
new ActionDescriptor
|
||||
{
|
||||
RouteValues = routeValues,
|
||||
DisplayName = displayName,
|
||||
AttributeRouteInfo = new AttributeRouteInfo
|
||||
{
|
||||
Order = order,
|
||||
Template = template
|
||||
},
|
||||
FilterDescriptors = new List<FilterDescriptor>
|
||||
{
|
||||
filterDescriptor
|
||||
}
|
||||
}
|
||||
}, 0));
|
||||
|
||||
// Act
|
||||
var dataSource = new MvcEndpointDataSource(
|
||||
mockDescriptorProvider.Object,
|
||||
new MvcEndpointInvokerFactory(new ActionInvokerFactory(Array.Empty<IActionInvokerProvider>())),
|
||||
Array.Empty<IActionDescriptorChangeProvider>());
|
||||
|
||||
// Assert
|
||||
var endpoint = Assert.Single(dataSource.Endpoints);
|
||||
var matcherEndpoint = Assert.IsType<MatcherEndpoint>(endpoint);
|
||||
|
||||
object endpointValue = matcherEndpoint.Values["Name"];
|
||||
Assert.Equal(routeValue, endpointValue);
|
||||
|
||||
Assert.Equal(displayName, matcherEndpoint.DisplayName);
|
||||
Assert.Equal(order, matcherEndpoint.Order);
|
||||
Assert.Equal(template, matcherEndpoint.Template);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Endpoints_InvokeReturnedEndpoint_ActionInvokerProviderCalled()
|
||||
{
|
||||
// Arrange
|
||||
var featureCollection = new FeatureCollection();
|
||||
featureCollection.Set<IEndpointFeature>(new EndpointFeature
|
||||
{
|
||||
Values = new RouteValueDictionary()
|
||||
});
|
||||
|
||||
var httpContextMock = new Mock<HttpContext>();
|
||||
httpContextMock.Setup(m => m.Features).Returns(featureCollection);
|
||||
|
||||
var mockDescriptorProviderMock = new Mock<IActionDescriptorCollectionProvider>();
|
||||
mockDescriptorProviderMock.Setup(m => m.ActionDescriptors).Returns(new ActionDescriptorCollection(new List<ActionDescriptor>
|
||||
{
|
||||
new ActionDescriptor
|
||||
{
|
||||
AttributeRouteInfo = new AttributeRouteInfo
|
||||
{
|
||||
Template = string.Empty
|
||||
},
|
||||
FilterDescriptors = new List<FilterDescriptor>()
|
||||
}
|
||||
}, 0));
|
||||
|
||||
var actionInvokerCalled = false;
|
||||
var actionInvokerMock = new Mock<IActionInvoker>();
|
||||
actionInvokerMock.Setup(m => m.InvokeAsync()).Returns(() =>
|
||||
{
|
||||
actionInvokerCalled = true;
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
|
||||
var actionInvokerProviderMock = new Mock<IActionInvokerFactory>();
|
||||
actionInvokerProviderMock.Setup(m => m.CreateInvoker(It.IsAny<ActionContext>())).Returns(actionInvokerMock.Object);
|
||||
|
||||
// Act
|
||||
var dataSource = new MvcEndpointDataSource(
|
||||
mockDescriptorProviderMock.Object,
|
||||
new MvcEndpointInvokerFactory(actionInvokerProviderMock.Object),
|
||||
Array.Empty<IActionDescriptorChangeProvider>());
|
||||
|
||||
// Assert
|
||||
var endpoint = Assert.Single(dataSource.Endpoints);
|
||||
var matcherEndpoint = Assert.IsType<MatcherEndpoint>(endpoint);
|
||||
|
||||
var invokerDelegate = matcherEndpoint.Invoker((next) => Task.CompletedTask);
|
||||
|
||||
invokerDelegate(httpContextMock.Object);
|
||||
|
||||
Assert.True(actionInvokerCalled);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ChangeToken_MultipleChangeTokenProviders_ComposedResult()
|
||||
{
|
||||
// Arrange
|
||||
var featureCollection = new FeatureCollection();
|
||||
featureCollection.Set<IEndpointFeature>(new EndpointFeature
|
||||
{
|
||||
Values = new RouteValueDictionary()
|
||||
});
|
||||
|
||||
var httpContextMock = new Mock<HttpContext>();
|
||||
httpContextMock.Setup(m => m.Features).Returns(featureCollection);
|
||||
|
||||
var mockDescriptorProviderMock = new Mock<IActionDescriptorCollectionProvider>();
|
||||
mockDescriptorProviderMock.Setup(m => m.ActionDescriptors).Returns(new ActionDescriptorCollection(new List<ActionDescriptor>(), 0));
|
||||
|
||||
var actionInvokerMock = new Mock<IActionInvoker>();
|
||||
|
||||
var actionInvokerProviderMock = new Mock<IActionInvokerFactory>();
|
||||
actionInvokerProviderMock.Setup(m => m.CreateInvoker(It.IsAny<ActionContext>())).Returns(actionInvokerMock.Object);
|
||||
|
||||
var changeTokenMock = new Mock<IChangeToken>();
|
||||
|
||||
var changeProvider1Mock = new Mock<IActionDescriptorChangeProvider>();
|
||||
changeProvider1Mock.Setup(m => m.GetChangeToken()).Returns(changeTokenMock.Object);
|
||||
var changeProvider2Mock = new Mock<IActionDescriptorChangeProvider>();
|
||||
changeProvider2Mock.Setup(m => m.GetChangeToken()).Returns(changeTokenMock.Object);
|
||||
|
||||
var dataSource = new MvcEndpointDataSource(
|
||||
mockDescriptorProviderMock.Object,
|
||||
new MvcEndpointInvokerFactory(actionInvokerProviderMock.Object),
|
||||
new[] { changeProvider1Mock.Object, changeProvider2Mock.Object });
|
||||
|
||||
// Act
|
||||
var changeToken = dataSource.ChangeToken;
|
||||
|
||||
// Assert
|
||||
var compositeChangeToken = Assert.IsType<CompositeChangeToken>(changeToken);
|
||||
Assert.Equal(2, compositeChangeToken.ChangeTokens.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -31,6 +31,7 @@
|
|||
<ProjectReference Include="..\WebSites\BasicWebSite\BasicWebSite.csproj" />
|
||||
<ProjectReference Include="..\WebSites\ControllersFromServicesWebSite\ControllersFromServicesWebSite.csproj" />
|
||||
<ProjectReference Include="..\WebSites\CorsWebSite\CorsWebSite.csproj" />
|
||||
<ProjectReference Include="..\WebSites\DispatchingWebSite\DispatchingWebSite.csproj" />
|
||||
<ProjectReference Include="..\WebSites\ErrorPageMiddlewareWebSite\ErrorPageMiddlewareWebSite.csproj" />
|
||||
<ProjectReference Include="..\WebSites\FilesWebSite\FilesWebSite.csproj" />
|
||||
<ProjectReference Include="..\WebSites\FormatterWebSite\FormatterWebSite.csproj" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace DispatchingWebSite.Admin
|
||||
{
|
||||
[Area("Admin")]
|
||||
[Route("[area]/Users")]
|
||||
public class UserManagementController : Controller
|
||||
{
|
||||
private readonly TestResponseGenerator _generator;
|
||||
|
||||
public UserManagementController(TestResponseGenerator generator)
|
||||
{
|
||||
_generator = generator;
|
||||
}
|
||||
|
||||
[HttpGet("All")]
|
||||
public IActionResult ListUsers()
|
||||
{
|
||||
return _generator.Generate("Admin/Users/All");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace DispatchingWebSite.Areas.Order
|
||||
{
|
||||
[Area("Order")]
|
||||
[Route("Order/[action]", Name = "[area]_[action]")]
|
||||
public class OrderController : Controller
|
||||
{
|
||||
private readonly TestResponseGenerator _generator;
|
||||
|
||||
public OrderController(TestResponseGenerator generator)
|
||||
{
|
||||
_generator = generator;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult GetOrder()
|
||||
{
|
||||
return _generator.Generate("/Order/GetOrder");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// 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.Mvc;
|
||||
|
||||
namespace DispatchingWebSite
|
||||
{
|
||||
// This controller is reachable via traditional routing.
|
||||
[Area("Travel")]
|
||||
public class FlightController
|
||||
{
|
||||
private readonly TestResponseGenerator _generator;
|
||||
|
||||
public FlightController(TestResponseGenerator generator)
|
||||
{
|
||||
_generator = generator;
|
||||
}
|
||||
|
||||
public IActionResult Index()
|
||||
{
|
||||
return _generator.Generate("/Travel/Flight", "/Travel/Flight/Index");
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult BuyTickets()
|
||||
{
|
||||
return _generator.Generate("/Travel/Flight/BuyTickets");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// 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.Mvc;
|
||||
|
||||
namespace DispatchingWebSite.Travel
|
||||
{
|
||||
[Area("Travel")]
|
||||
public class HomeController : Controller
|
||||
{
|
||||
private readonly TestResponseGenerator _generator;
|
||||
|
||||
public HomeController(TestResponseGenerator generator)
|
||||
{
|
||||
_generator = generator;
|
||||
}
|
||||
|
||||
public IActionResult Index()
|
||||
{
|
||||
return _generator.Generate("/Travel", "/Travel/Home", "/Travel/Home/Index");
|
||||
}
|
||||
|
||||
[HttpGet("ContosoCorp/AboutTravel")]
|
||||
public IActionResult About()
|
||||
{
|
||||
return _generator.Generate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// 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.Mvc;
|
||||
|
||||
namespace DispatchingWebSite
|
||||
{
|
||||
[Area("Travel")]
|
||||
[Route("ContosoCorp/Trains")]
|
||||
public class RailController
|
||||
{
|
||||
private readonly TestResponseGenerator _generator;
|
||||
|
||||
public RailController(TestResponseGenerator generator)
|
||||
{
|
||||
_generator = generator;
|
||||
}
|
||||
|
||||
public IActionResult Index()
|
||||
{
|
||||
return _generator.Generate("/ContosoCorp/Trains");
|
||||
}
|
||||
|
||||
[HttpGet("CheckSchedule")]
|
||||
public IActionResult Schedule()
|
||||
{
|
||||
return _generator.Generate("/ContosoCorp/Trains/Schedule");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
// 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.Mvc;
|
||||
|
||||
namespace DispatchingWebSite.Controllers
|
||||
{
|
||||
public class BanksController : Controller
|
||||
{
|
||||
private readonly TestResponseGenerator _generator;
|
||||
|
||||
public BanksController(TestResponseGenerator generator)
|
||||
{
|
||||
_generator = generator;
|
||||
}
|
||||
|
||||
[HttpGet("Banks/[action]/{id}")]
|
||||
[HttpGet("Bank/[action]/{id}")]
|
||||
public ActionResult Get(int id)
|
||||
{
|
||||
return _generator.Generate(
|
||||
Url.Action(),
|
||||
Url.RouteUrl(new { }));
|
||||
}
|
||||
|
||||
[AcceptVerbs("PUT", Route = "Bank")]
|
||||
[HttpPatch("Bank")]
|
||||
[AcceptVerbs("PUT", Route = "Bank/Update")]
|
||||
[HttpPatch("Bank/Update")]
|
||||
public ActionResult UpdateBank()
|
||||
{
|
||||
return _generator.Generate(
|
||||
Url.Action(),
|
||||
Url.RouteUrl(new { }));
|
||||
}
|
||||
|
||||
[AcceptVerbs("PUT", "POST")]
|
||||
[Route("Bank/Deposit")]
|
||||
[Route("Bank/Deposit/{amount}")]
|
||||
public ActionResult Deposit()
|
||||
{
|
||||
return _generator.Generate("/Bank/Deposit", "/Bank/Deposit/5");
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("Bank/Withdraw/{id}")]
|
||||
public ActionResult Withdraw(int id)
|
||||
{
|
||||
return _generator.Generate("/Bank/Withdraw/5");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// 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.Mvc;
|
||||
|
||||
namespace DispatchingWebSite.Controllers
|
||||
{
|
||||
// This controller contains actions mapped with a single controller-level route.
|
||||
[Route("Blog/[action]/{postId?}")]
|
||||
public class BlogController
|
||||
{
|
||||
private readonly TestResponseGenerator _generator;
|
||||
|
||||
public BlogController(TestResponseGenerator generator)
|
||||
{
|
||||
_generator = generator;
|
||||
}
|
||||
|
||||
public IActionResult ShowPosts()
|
||||
{
|
||||
return _generator.Generate("/Blog/ShowPosts");
|
||||
}
|
||||
|
||||
public IActionResult Edit(int postId)
|
||||
{
|
||||
return _generator.Generate("/Blog/Edit/" + postId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
// 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.Mvc;
|
||||
|
||||
namespace DispatchingWebSite.Controllers
|
||||
{
|
||||
// A controller can define a route for all of the actions
|
||||
// in it and give it a name for link generation purposes.
|
||||
[Route("api/Company/{id}", Name = "Company")]
|
||||
public class CompanyController : Controller
|
||||
{
|
||||
private readonly TestResponseGenerator _generator;
|
||||
|
||||
public CompanyController(TestResponseGenerator generator)
|
||||
{
|
||||
_generator = generator;
|
||||
}
|
||||
|
||||
// An action with the same template will inherit the name
|
||||
// from the controller.
|
||||
[HttpGet]
|
||||
public ActionResult Get(int id)
|
||||
{
|
||||
return _generator.Generate(Url.RouteUrl("Company", new { id = id }));
|
||||
}
|
||||
|
||||
// Multiple actions can have the same named route as long
|
||||
// as for a given Name, all the actions have the same template.
|
||||
// That is, there can't be two link generation entries with same
|
||||
// name and different templates.
|
||||
[HttpPut]
|
||||
public ActionResult Put(int id)
|
||||
{
|
||||
return _generator.Generate(Url.RouteUrl("Company", new { id = id }));
|
||||
}
|
||||
|
||||
// Two actions can have the same template and each of them can have
|
||||
// a different route name. That is, a given template can have multiple
|
||||
// names associated with it.
|
||||
[HttpDelete(Name = "RemoveCompany")]
|
||||
public ActionResult Delete(int id)
|
||||
{
|
||||
return _generator.Generate(Url.RouteUrl("RemoveCompany", new { id = id }));
|
||||
}
|
||||
|
||||
// An action that defines a non empty template doesn't inherit the name
|
||||
// from the route on the controller .
|
||||
[HttpGet("Employees")]
|
||||
public ActionResult GetEmployees(int id)
|
||||
{
|
||||
return _generator.Generate(Url.RouteUrl(new { id = id }));
|
||||
}
|
||||
|
||||
// An action that defines a non empty template doesn't inherit the name
|
||||
// from the controller but can perfectly define its own name.
|
||||
[HttpGet("Departments", Name = "Departments")]
|
||||
public ActionResult GetDepartments(int id)
|
||||
{
|
||||
return _generator.Generate(Url.RouteUrl("Departments", new { id = id }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
// 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.Mvc;
|
||||
|
||||
namespace DispatchingWebSite.Controllers
|
||||
{
|
||||
// This controller combines routes on the controller with routes on actions in a REST + navigation property
|
||||
// style.
|
||||
[Route("api/Employee")]
|
||||
public class EmployeeController : Controller
|
||||
{
|
||||
private readonly TestResponseGenerator _generator;
|
||||
|
||||
public EmployeeController(TestResponseGenerator generator)
|
||||
{
|
||||
_generator = generator;
|
||||
}
|
||||
|
||||
public IActionResult List()
|
||||
{
|
||||
return _generator.Generate("/api/Employee");
|
||||
}
|
||||
|
||||
[AcceptVerbs("PUT", "PATCH")]
|
||||
public IActionResult UpdateEmployee()
|
||||
{
|
||||
return _generator.Generate("/api/Employee");
|
||||
}
|
||||
|
||||
[AcceptVerbs("PUT", "PATCH", Route = "Manager")]
|
||||
public IActionResult UpdateManager()
|
||||
{
|
||||
return _generator.Generate("/api/Employee/Manager");
|
||||
}
|
||||
|
||||
[HttpMerge("{id}")]
|
||||
public IActionResult MergeEmployee(int id)
|
||||
{
|
||||
return _generator.Generate("/api/Employee/" + id);
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
public IActionResult Get(int id)
|
||||
{
|
||||
return _generator.Generate("/api/Employee/" + id);
|
||||
}
|
||||
|
||||
[HttpGet("{id}/Administrator")]
|
||||
public IActionResult GetAdministrator(int id)
|
||||
{
|
||||
return _generator.Generate("/api/Employee/" + id + "/Administrator");
|
||||
}
|
||||
|
||||
[HttpGet("~/Manager/{id}")]
|
||||
public IActionResult GetManager(int id)
|
||||
{
|
||||
return _generator.Generate("/Manager/" + id);
|
||||
}
|
||||
|
||||
[HttpDelete("{id}/Administrator")]
|
||||
public IActionResult DeleteAdministrator(int id)
|
||||
{
|
||||
return _generator.Generate("/api/Employee/" + id + "/Administrator");
|
||||
}
|
||||
|
||||
[Route("{id}/Salary")]
|
||||
public IActionResult Salary(int id)
|
||||
{
|
||||
return _generator.Generate("/api/Employee/" + id + "/Salary");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// 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.Mvc;
|
||||
|
||||
namespace DispatchingWebSite.Controllers
|
||||
{
|
||||
[Route("Friends")]
|
||||
public class FriendsController : Controller
|
||||
{
|
||||
private readonly TestResponseGenerator _generator;
|
||||
|
||||
public FriendsController(TestResponseGenerator generator)
|
||||
{
|
||||
_generator = generator;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[HttpGet("{id}")]
|
||||
public IActionResult Get([FromRoute]string id)
|
||||
{
|
||||
return _generator.Generate(id == null ? "/Friends" : $"/Friends/{id}");
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
public IActionResult Delete()
|
||||
{
|
||||
return _generator.Generate("/Friends");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// 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.Mvc;
|
||||
|
||||
namespace DispatchingWebSite.Controllers
|
||||
{
|
||||
// This controller is reachable via traditional routing.
|
||||
public class HomeController : Controller
|
||||
{
|
||||
private readonly TestResponseGenerator _generator;
|
||||
|
||||
public HomeController(TestResponseGenerator generator)
|
||||
{
|
||||
_generator = generator;
|
||||
}
|
||||
|
||||
public IActionResult Index()
|
||||
{
|
||||
return _generator.Generate("/", "/Home", "/Home/Index");
|
||||
}
|
||||
|
||||
public IActionResult About()
|
||||
{
|
||||
// There are no urls that reach this action - it's hidden by an attribute route.
|
||||
return _generator.Generate();
|
||||
}
|
||||
|
||||
public IActionResult Contact()
|
||||
{
|
||||
return _generator.Generate("/Home/Contact");
|
||||
}
|
||||
|
||||
public IActionResult OptionalPath(string path = "default")
|
||||
{
|
||||
return _generator.Generate("/Home/OptionalPath/" + path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
// 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.Mvc;
|
||||
|
||||
namespace DispatchingWebSite.Controllers
|
||||
{
|
||||
[Route("api/v1/Maps", Name = "v1", Order = 1)]
|
||||
[Route("api/v2/Maps")]
|
||||
public class MapsController : Controller
|
||||
{
|
||||
private readonly TestResponseGenerator _generator;
|
||||
|
||||
public MapsController(TestResponseGenerator generator)
|
||||
{
|
||||
_generator = generator;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public ActionResult Get()
|
||||
{
|
||||
// Multiple attribute routes with name and order.
|
||||
// We will always generate v2 routes except when
|
||||
// we explicitly use "v1" to generate a v1 route.
|
||||
return _generator.Generate(
|
||||
Url.Action(),
|
||||
Url.RouteUrl("v1"),
|
||||
Url.RouteUrl(new { }));
|
||||
}
|
||||
|
||||
[HttpPost("/api/v2/Maps")]
|
||||
public ActionResult Post()
|
||||
{
|
||||
return _generator.Generate(
|
||||
Url.Action(),
|
||||
Url.RouteUrl(new { }));
|
||||
}
|
||||
|
||||
[HttpPut("{id}")]
|
||||
[HttpPatch("PartialUpdate/{id}")]
|
||||
public ActionResult Update(int id)
|
||||
{
|
||||
// We will generate "/api/v2/Maps/PartialUpdate/{id}"
|
||||
// in both cases, v1 routes will be discarded due to their
|
||||
// Order and for v2 routes PartialUpdate has higher precedence.
|
||||
// api/v1/Maps/{id} and api/v2/Maps/{id} will only match on PUT.
|
||||
// api/v1/Maps/PartialUpdate/{id} and api/v2/Maps/PartialUpdate/{id} will only match on PATCH.
|
||||
return _generator.Generate(
|
||||
Url.Action(),
|
||||
Url.RouteUrl(new { }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace DispatchingWebSite.Controllers
|
||||
{
|
||||
[Route("Order/[action]/{orderId?}", Name = "Order_[action]")]
|
||||
public class OrderController : Controller
|
||||
{
|
||||
private readonly TestResponseGenerator _generator;
|
||||
|
||||
public OrderController(TestResponseGenerator generator)
|
||||
{
|
||||
_generator = generator;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Add(int orderId)
|
||||
{
|
||||
return _generator.Generate("/Order/Add/1");
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Add()
|
||||
{
|
||||
return _generator.Generate("/Order/Add");
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
public IActionResult Edit(int orderId)
|
||||
{
|
||||
return _generator.Generate("/Order/Edit/1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace DispatchingWebSite.Controllers
|
||||
{
|
||||
// This controller contains only actions with individual attribute routes.
|
||||
public class StoreController : Controller
|
||||
{
|
||||
private readonly TestResponseGenerator _generator;
|
||||
|
||||
public StoreController(TestResponseGenerator generator)
|
||||
{
|
||||
_generator = generator;
|
||||
}
|
||||
|
||||
[HttpGet("Store/Shop/Products")]
|
||||
public IActionResult ListProducts()
|
||||
{
|
||||
return _generator.Generate("/Store/Shop/Products");
|
||||
}
|
||||
|
||||
// Intentionally designed to conflict with HomeController#About.
|
||||
[HttpGet("Home/About")]
|
||||
public IActionResult About()
|
||||
{
|
||||
return _generator.Generate("/Home/About");
|
||||
}
|
||||
|
||||
[Route("Store/Shop/Orders")]
|
||||
public IActionResult Orders()
|
||||
{
|
||||
return _generator.Generate("/Store/Shop/Orders");
|
||||
}
|
||||
|
||||
[HttpGet("Store/Shop/Orders")]
|
||||
public IActionResult GetOrders()
|
||||
{
|
||||
return _generator.Generate("/Store/Shop/Orders");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace DispatchingWebSite.Controllers
|
||||
{
|
||||
[Route("/Teams", Order = 1)]
|
||||
public class TeamController : Controller
|
||||
{
|
||||
private readonly TestResponseGenerator _generator;
|
||||
|
||||
public TeamController(TestResponseGenerator generator)
|
||||
{
|
||||
_generator = generator;
|
||||
}
|
||||
|
||||
[HttpGet("/Team/{teamId}", Order = 2)]
|
||||
public ActionResult GetTeam(int teamId)
|
||||
{
|
||||
return _generator.Generate("/Team/" + teamId);
|
||||
}
|
||||
|
||||
[HttpGet("/Team/{teamId}")]
|
||||
public ActionResult GetOrganization(int teamId)
|
||||
{
|
||||
return _generator.Generate("/Team/" + teamId);
|
||||
}
|
||||
|
||||
[HttpGet("")]
|
||||
public ActionResult GetTeams()
|
||||
{
|
||||
return _generator.Generate("/Teams");
|
||||
}
|
||||
|
||||
[HttpGet("", Order = 0)]
|
||||
public ActionResult GetOrganizations()
|
||||
{
|
||||
return _generator.Generate("/Teams");
|
||||
}
|
||||
|
||||
[HttpGet("/Club/{clubId?}")]
|
||||
public ActionResult GetClub()
|
||||
{
|
||||
return Content(Url.Action(), "text/plain");
|
||||
}
|
||||
|
||||
[HttpGet("/Organization/{clubId?}", Order = 1)]
|
||||
public ActionResult GetClub(int clubId)
|
||||
{
|
||||
return Content(Url.Action(), "text/plain");
|
||||
}
|
||||
|
||||
[HttpGet("AllTeams")]
|
||||
public ActionResult GetAllTeams()
|
||||
{
|
||||
return Content(Url.Action(), "text/plain");
|
||||
}
|
||||
|
||||
[HttpGet("AllOrganizations", Order = 0)]
|
||||
public ActionResult GetAllTeams(int notRelevant)
|
||||
{
|
||||
return Content(Url.Action(), "text/plain");
|
||||
}
|
||||
|
||||
[HttpGet("/TeamName/{*Name=DefaultName}/")]
|
||||
public ActionResult GetTeam(string name)
|
||||
{
|
||||
return _generator.Generate("/TeamName/" + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>$(StandardTestWebsiteTfms)</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Mvc\Microsoft.AspNetCore.Mvc.csproj" />
|
||||
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="$(MicrosoftAspNetCoreServerIISIntegrationPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(MicrosoftAspNetCoreStaticFilesPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsolePackageVersion)" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -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;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Mvc.Routing;
|
||||
|
||||
namespace DispatchingWebSite
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
|
||||
public class HttpMergeAttribute : Attribute, IActionHttpMethodProvider, IRouteTemplateProvider
|
||||
{
|
||||
private static readonly IEnumerable<string> _supportedMethods = new[] { "MERGE" };
|
||||
|
||||
public HttpMergeAttribute(string template)
|
||||
{
|
||||
Template = template;
|
||||
}
|
||||
|
||||
public IEnumerable<string> HttpMethods
|
||||
{
|
||||
get { return _supportedMethods; }
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Template { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public int? Order { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
// 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 Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Routing.Matchers;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace DispatchingWebSite
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
// Set up application services
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddDispatcher();
|
||||
|
||||
services.AddMvc();
|
||||
|
||||
services.AddScoped<TestResponseGenerator>();
|
||||
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseDispatcher();
|
||||
|
||||
//app.UseMvc(routes =>
|
||||
//{
|
||||
// routes.MapAreaRoute(
|
||||
// "flightRoute",
|
||||
// "adminRoute",
|
||||
// "{area:exists}/{controller}/{action}",
|
||||
// new { controller = "Home", action = "Index" },
|
||||
// new { area = "Travel" });
|
||||
|
||||
// routes.MapRoute(
|
||||
// "ActionAsMethod",
|
||||
// "{controller}/{action}",
|
||||
// defaults: new { controller = "Home", action = "Index" });
|
||||
|
||||
// routes.MapRoute(
|
||||
// "RouteWithOptionalSegment",
|
||||
// "{controller}/{action}/{path?}");
|
||||
//});
|
||||
|
||||
app.UseEndpoint();
|
||||
}
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var host = CreateWebHostBuilder(args)
|
||||
.ConfigureLogging((hostingContext, logging) =>
|
||||
{
|
||||
logging.AddConsole();
|
||||
})
|
||||
.Build();
|
||||
|
||||
host.Run();
|
||||
}
|
||||
|
||||
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
|
||||
new WebHostBuilder()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseStartup<Startup>()
|
||||
.UseKestrel()
|
||||
.UseIISIntegration();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
using Microsoft.AspNetCore.Mvc.Routing;
|
||||
|
||||
namespace DispatchingWebSite
|
||||
{
|
||||
// Generates a response based on the expected URL and action context
|
||||
public class TestResponseGenerator
|
||||
{
|
||||
private readonly ActionContext _actionContext;
|
||||
private readonly IUrlHelperFactory _urlHelperFactory;
|
||||
|
||||
public TestResponseGenerator(IActionContextAccessor contextAccessor, IUrlHelperFactory urlHelperFactory)
|
||||
{
|
||||
_urlHelperFactory = urlHelperFactory;
|
||||
|
||||
_actionContext = contextAccessor.ActionContext;
|
||||
if (_actionContext == null)
|
||||
{
|
||||
throw new InvalidOperationException("ActionContext should not be null here.");
|
||||
}
|
||||
}
|
||||
|
||||
public JsonResult Generate(params string[] expectedUrls)
|
||||
{
|
||||
var link = (string)null;
|
||||
var query = _actionContext.HttpContext.Request.Query;
|
||||
if (query.ContainsKey("link"))
|
||||
{
|
||||
var values = query
|
||||
.Where(kvp => kvp.Key != "link" && kvp.Key != "link_action" && kvp.Key != "link_controller")
|
||||
.ToDictionary(kvp => kvp.Key.Substring("link_".Length), kvp => (object)kvp.Value[0]);
|
||||
|
||||
var urlHelper = _urlHelperFactory.GetUrlHelper(_actionContext);
|
||||
link = urlHelper.Action(query["link_action"], query["link_controller"], values);
|
||||
}
|
||||
|
||||
var attributeRoutingInfo = _actionContext.ActionDescriptor.AttributeRouteInfo;
|
||||
|
||||
return new JsonResult(new
|
||||
{
|
||||
expectedUrls = expectedUrls,
|
||||
actualUrl = _actionContext.HttpContext.Request.Path.Value,
|
||||
routeName = attributeRoutingInfo == null ? null : attributeRoutingInfo.Name,
|
||||
routeValues = new Dictionary<string, object>(_actionContext.RouteData.Values),
|
||||
|
||||
action = ((ControllerActionDescriptor) _actionContext.ActionDescriptor).ActionName,
|
||||
controller = ((ControllerActionDescriptor)_actionContext.ActionDescriptor).ControllerName,
|
||||
|
||||
link,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
DispatchingWebSite
|
||||
===
|
||||
|
||||
This web site illustrates how to use conventional and attribute dispatching.
|
||||
Loading…
Reference in New Issue