Merge branch 'master' into merge/release/2.2-to-master

This commit is contained in:
Doug Bunting 2018-10-30 21:08:15 -07:00 committed by GitHub
commit 579341c8d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 670 additions and 151 deletions

View File

@ -2,7 +2,7 @@ init:
- git config --global core.autocrlf true - git config --global core.autocrlf true
branches: branches:
only: only:
- dev - master
- /^release\/.*$/ - /^release\/.*$/
- /^(.*\/)?ci-.*$/ - /^(.*\/)?ci-.*$/
build_script: build_script:

View File

@ -12,7 +12,7 @@ os:
osx_image: xcode8.2 osx_image: xcode8.2
branches: branches:
only: only:
- dev - master
- /^release\/.*$/ - /^release\/.*$/
- /^(.*\/)?ci-.*$/ - /^(.*\/)?ci-.*$/
before_install: before_install:

View File

@ -7,7 +7,7 @@ resources:
- repository: buildtools - repository: buildtools
type: git type: git
name: aspnet-BuildTools name: aspnet-BuildTools
ref: refs/heads/release/2.2 ref: refs/heads/master
phases: phases:
- template: .vsts-pipelines/templates/project-ci.yml@buildtools - template: .vsts-pipelines/templates/project-ci.yml@buildtools

View File

@ -9,7 +9,7 @@ resources:
type: github type: github
endpoint: DotNet-Bot GitHub Connection endpoint: DotNet-Bot GitHub Connection
name: aspnet/BuildTools name: aspnet/BuildTools
ref: refs/heads/release/2.2 ref: refs/heads/master
phases: phases:
- template: .vsts-pipelines/templates/project-ci.yml@buildtools - template: .vsts-pipelines/templates/project-ci.yml@buildtools

View File

@ -3,7 +3,7 @@ ASP.NET Core MVC
**Note: For ASP.NET MVC 5.x, Web API 2.x, and Web Pages 3.x (not ASP.NET Core), see https://github.com/aspnet/AspNetWebStack** **Note: For ASP.NET MVC 5.x, Web API 2.x, and Web Pages 3.x (not ASP.NET Core), see https://github.com/aspnet/AspNetWebStack**
Travis: [![Travis](https://travis-ci.org/aspnet/Mvc.svg?branch=release/2.2)](https://travis-ci.org/aspnet/Mvc) Travis: [![Travis](https://travis-ci.org/aspnet/Mvc.svg?branch=master)](https://travis-ci.org/aspnet/Mvc)
ASP.NET Core MVC gives you a powerful, patterns-based way to build dynamic websites that enables a clean separation of concerns and gives you full control over markup for enjoyable, agile development. ASP.NET Core MVC includes many features that enable fast, TDD-friendly development for creating sophisticated applications that use the latest web standards. ASP.NET Core MVC gives you a powerful, patterns-based way to build dynamic websites that enables a clean separation of concerns and gives you full control over markup for enjoyable, agile development. ASP.NET Core MVC includes many features that enable fast, TDD-friendly development for creating sophisticated applications that use the latest web standards.

View File

@ -7,7 +7,7 @@
"PresetHeaders": "Json", "PresetHeaders": "Json",
"ReadyStateText": "Application started.", "ReadyStateText": "Application started.",
"Source": { "Source": {
"BranchOrCommit": "release/2.2", "BranchOrCommit": "dev",
"Project": "benchmarkapps/BasicApi/BasicApi.csproj", "Project": "benchmarkapps/BasicApi/BasicApi.csproj",
"Repository": "https://github.com/aspnet/mvc.git" "Repository": "https://github.com/aspnet/mvc.git"
} }
@ -19,20 +19,20 @@
}, },
"BasicApi.GetUsingQueryString": { "BasicApi.GetUsingQueryString": {
"ClientProperties": { "ClientProperties": {
"Scripts": "https://raw.githubusercontent.com/aspnet/Mvc/release/2.2/benchmarkapps/BasicApi/getWithToken.lua" "Scripts": "https://raw.githubusercontent.com/aspnet/Mvc/dev/benchmarkapps/BasicApi/getWithToken.lua"
}, },
"Path": "/pet/findByStatus", "Path": "/pet/findByStatus",
"Query": "?status=available" "Query": "?status=available"
}, },
"BasicApi.GetUsingRouteValue": { "BasicApi.GetUsingRouteValue": {
"ClientProperties": { "ClientProperties": {
"Scripts": "https://raw.githubusercontent.com/aspnet/Mvc/release/2.2/benchmarkapps/BasicApi/getWithToken.lua" "Scripts": "https://raw.githubusercontent.com/aspnet/Mvc/dev/benchmarkapps/BasicApi/getWithToken.lua"
}, },
"Path": "/pet/-1" "Path": "/pet/-1"
}, },
"BasicApi.GetUsingRouteValueWithoutAuthorization": { "BasicApi.GetUsingRouteValueWithoutAuthorization": {
"ClientProperties": { "ClientProperties": {
"Scripts": "https://raw.githubusercontent.com/aspnet/Mvc/release/2.2/benchmarkapps/BasicApi/getWithToken.lua" "Scripts": "https://raw.githubusercontent.com/aspnet/Mvc/dev/benchmarkapps/BasicApi/getWithToken.lua"
}, },
"Path": "/pet/anonymous/-1" "Path": "/pet/anonymous/-1"
}, },
@ -41,7 +41,7 @@
}, },
"BasicApi.Post": { "BasicApi.Post": {
"ClientProperties": { "ClientProperties": {
"Scripts": "https://raw.githubusercontent.com/aspnet/Mvc/release/2.2/benchmarkapps/BasicApi/postJsonWithToken.lua" "Scripts": "https://raw.githubusercontent.com/aspnet/Mvc/dev/benchmarkapps/BasicApi/postJsonWithToken.lua"
}, },
"Path": "/pet" "Path": "/pet"
}, },

View File

@ -7,7 +7,7 @@
"PresetHeaders": "Html", "PresetHeaders": "Html",
"ReadyStateText": "Application started.", "ReadyStateText": "Application started.",
"Source": { "Source": {
"BranchOrCommit": "release/2.2", "BranchOrCommit": "dev",
"Project": "benchmarkapps/BasicViews/BasicViews.csproj", "Project": "benchmarkapps/BasicViews/BasicViews.csproj",
"Repository": "https://github.com/aspnet/mvc.git" "Repository": "https://github.com/aspnet/mvc.git"
} }
@ -20,19 +20,19 @@
}, },
"BasicViews.Post": { "BasicViews.Post": {
"ClientProperties": { "ClientProperties": {
"Scripts": "https://raw.githubusercontent.com/aspnet/Mvc/release/2.2/benchmarkapps/BasicViews/postWithToken.lua" "Scripts": "https://raw.githubusercontent.com/aspnet/Mvc/dev/benchmarkapps/BasicViews/postWithToken.lua"
}, },
"Path": "/Home/Index" "Path": "/Home/Index"
}, },
"BasicViews.PostIgnoringToken": { "BasicViews.PostIgnoringToken": {
"ClientProperties": { "ClientProperties": {
"Scripts": "https://raw.githubusercontent.com/aspnet/Mvc/release/2.2/benchmarkapps/BasicViews/postWithToken.lua" "Scripts": "https://raw.githubusercontent.com/aspnet/Mvc/dev/benchmarkapps/BasicViews/postWithToken.lua"
}, },
"Path": "/Home/IndexWithoutToken" "Path": "/Home/IndexWithoutToken"
}, },
"BasicViews.PostWithoutToken": { "BasicViews.PostWithoutToken": {
"ClientProperties": { "ClientProperties": {
"Scripts": "https://raw.githubusercontent.com/aspnet/Mvc/release/2.2/benchmarkapps/BasicViews/post.lua" "Scripts": "https://raw.githubusercontent.com/aspnet/Mvc/dev/benchmarkapps/BasicViews/post.lua"
}, },
"Path": "/Home/IndexWithoutToken" "Path": "/Home/IndexWithoutToken"
} }

View File

@ -16,97 +16,97 @@
<BenchmarksOnlyMySqlConnectorPackageVersion>0.43.0</BenchmarksOnlyMySqlConnectorPackageVersion> <BenchmarksOnlyMySqlConnectorPackageVersion>0.43.0</BenchmarksOnlyMySqlConnectorPackageVersion>
<BenchmarksOnlyNpgsqlEntityFrameworkCorePostgreSQLPackageVersion>2.1.1.1</BenchmarksOnlyNpgsqlEntityFrameworkCorePostgreSQLPackageVersion> <BenchmarksOnlyNpgsqlEntityFrameworkCorePostgreSQLPackageVersion>2.1.1.1</BenchmarksOnlyNpgsqlEntityFrameworkCorePostgreSQLPackageVersion>
<BenchmarksOnlyPomeloEntityFrameworkCoreMySqlPackageVersion>2.1.1</BenchmarksOnlyPomeloEntityFrameworkCoreMySqlPackageVersion> <BenchmarksOnlyPomeloEntityFrameworkCoreMySqlPackageVersion>2.1.1</BenchmarksOnlyPomeloEntityFrameworkCoreMySqlPackageVersion>
<InternalAspNetCoreAnalyzersPackageVersion>2.2.0-rtm-35519</InternalAspNetCoreAnalyzersPackageVersion> <InternalAspNetCoreAnalyzersPackageVersion>3.0.0-alpha1-10654</InternalAspNetCoreAnalyzersPackageVersion>
<MicrosoftAspNetCoreAllPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreAllPackageVersion> <MicrosoftAspNetCoreAllPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreAllPackageVersion>
<MicrosoftAspNetCoreAnalyzerTestingPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreAnalyzerTestingPackageVersion> <MicrosoftAspNetCoreAnalyzerTestingPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreAnalyzerTestingPackageVersion>
<MicrosoftAspNetCoreAntiforgeryPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreAntiforgeryPackageVersion> <MicrosoftAspNetCoreAntiforgeryPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreAntiforgeryPackageVersion>
<MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreAuthenticationCookiesPackageVersion> <MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>
<MicrosoftAspNetCoreAuthenticationCorePackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreAuthenticationCorePackageVersion> <MicrosoftAspNetCoreAuthenticationCorePackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreAuthenticationCorePackageVersion>
<MicrosoftAspNetCoreAuthenticationJwtBearerPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreAuthenticationJwtBearerPackageVersion> <MicrosoftAspNetCoreAuthenticationJwtBearerPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreAuthenticationJwtBearerPackageVersion>
<MicrosoftAspNetCoreAuthenticationPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreAuthenticationPackageVersion> <MicrosoftAspNetCoreAuthenticationPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreAuthenticationPackageVersion>
<MicrosoftAspNetCoreAuthorizationPolicyPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreAuthorizationPolicyPackageVersion> <MicrosoftAspNetCoreAuthorizationPolicyPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreAuthorizationPolicyPackageVersion>
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion> <MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
<MicrosoftAspNetCoreChunkingCookieManagerSourcesPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreChunkingCookieManagerSourcesPackageVersion> <MicrosoftAspNetCoreChunkingCookieManagerSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreChunkingCookieManagerSourcesPackageVersion>
<MicrosoftAspNetCoreCookiePolicyPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreCookiePolicyPackageVersion> <MicrosoftAspNetCoreCookiePolicyPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreCookiePolicyPackageVersion>
<MicrosoftAspNetCoreCorsPackageVersion>2.2.0-a-rtm-fix-wildcard-16567</MicrosoftAspNetCoreCorsPackageVersion> <MicrosoftAspNetCoreCorsPackageVersion>3.0.0-a-alpha1-w-m-16569</MicrosoftAspNetCoreCorsPackageVersion>
<MicrosoftAspNetCoreDiagnosticsAbstractionsPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreDiagnosticsAbstractionsPackageVersion> <MicrosoftAspNetCoreDiagnosticsAbstractionsPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreDiagnosticsAbstractionsPackageVersion>
<MicrosoftAspNetCoreDiagnosticsPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreDiagnosticsPackageVersion> <MicrosoftAspNetCoreDiagnosticsPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreDiagnosticsPackageVersion>
<MicrosoftAspNetCoreHostingAbstractions20PackageVersion>2.0.0</MicrosoftAspNetCoreHostingAbstractions20PackageVersion> <MicrosoftAspNetCoreHostingAbstractions20PackageVersion>2.0.0</MicrosoftAspNetCoreHostingAbstractions20PackageVersion>
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreHostingAbstractionsPackageVersion> <MicrosoftAspNetCoreHostingAbstractionsPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
<MicrosoftAspNetCoreHostingPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreHostingPackageVersion> <MicrosoftAspNetCoreHostingPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreHostingPackageVersion>
<MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreHtmlAbstractionsPackageVersion> <MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>
<MicrosoftAspNetCoreHttpExtensionsPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreHttpExtensionsPackageVersion> <MicrosoftAspNetCoreHttpExtensionsPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreHttpExtensionsPackageVersion>
<MicrosoftAspNetCoreHttpPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreHttpPackageVersion> <MicrosoftAspNetCoreHttpPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreHttpPackageVersion>
<MicrosoftAspNetCoreJsonPatchPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreJsonPatchPackageVersion> <MicrosoftAspNetCoreJsonPatchPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreJsonPatchPackageVersion>
<MicrosoftAspNetCoreLocalizationPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreLocalizationPackageVersion> <MicrosoftAspNetCoreLocalizationPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreLocalizationPackageVersion>
<MicrosoftAspNetCoreLocalizationRoutingPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreLocalizationRoutingPackageVersion> <MicrosoftAspNetCoreLocalizationRoutingPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreLocalizationRoutingPackageVersion>
<MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion> <MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>
<MicrosoftAspNetCoreRangeHelperSourcesPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreRangeHelperSourcesPackageVersion> <MicrosoftAspNetCoreRangeHelperSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreRangeHelperSourcesPackageVersion>
<MicrosoftAspNetCoreRazorDesignPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreRazorDesignPackageVersion> <MicrosoftAspNetCoreRazorDesignPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreRazorDesignPackageVersion>
<MicrosoftAspNetCoreRazorLanguagePackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreRazorLanguagePackageVersion> <MicrosoftAspNetCoreRazorLanguagePackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreRazorLanguagePackageVersion>
<MicrosoftAspNetCoreRazorRuntimePackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreRazorRuntimePackageVersion> <MicrosoftAspNetCoreRazorRuntimePackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreRazorRuntimePackageVersion>
<MicrosoftAspNetCoreRazorTagHelpersTestingSourcesPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreRazorTagHelpersTestingSourcesPackageVersion> <MicrosoftAspNetCoreRazorTagHelpersTestingSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreRazorTagHelpersTestingSourcesPackageVersion>
<MicrosoftAspNetCoreResponseCachingAbstractionsPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreResponseCachingAbstractionsPackageVersion> <MicrosoftAspNetCoreResponseCachingAbstractionsPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreResponseCachingAbstractionsPackageVersion>
<MicrosoftAspNetCoreResponseCachingPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreResponseCachingPackageVersion> <MicrosoftAspNetCoreResponseCachingPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreResponseCachingPackageVersion>
<MicrosoftAspNetCoreRoutingAbstractionsPackageVersion>2.2.0-a-rtm-allow-required-parameters-17081</MicrosoftAspNetCoreRoutingAbstractionsPackageVersion> <MicrosoftAspNetCoreRoutingAbstractionsPackageVersion>3.0.0-a-alpha1-master-builder-17095</MicrosoftAspNetCoreRoutingAbstractionsPackageVersion>
<MicrosoftAspNetCoreRoutingPackageVersion>2.2.0-a-rtm-allow-required-parameters-17081</MicrosoftAspNetCoreRoutingPackageVersion> <MicrosoftAspNetCoreRoutingPackageVersion>3.0.0-a-alpha1-master-builder-17095</MicrosoftAspNetCoreRoutingPackageVersion>
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreServerIISIntegrationPackageVersion> <MicrosoftAspNetCoreServerIISIntegrationPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
<MicrosoftAspNetCoreServerKestrelPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreServerKestrelPackageVersion> <MicrosoftAspNetCoreServerKestrelPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreServerKestrelPackageVersion>
<MicrosoftAspNetCoreSessionPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreSessionPackageVersion> <MicrosoftAspNetCoreSessionPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreSessionPackageVersion>
<MicrosoftAspNetCoreStaticFilesPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreStaticFilesPackageVersion> <MicrosoftAspNetCoreStaticFilesPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreStaticFilesPackageVersion>
<MicrosoftAspNetCoreTestHostPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreTestHostPackageVersion> <MicrosoftAspNetCoreTestHostPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreTestHostPackageVersion>
<MicrosoftAspNetCoreTestingPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreTestingPackageVersion> <MicrosoftAspNetCoreTestingPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreTestingPackageVersion>
<MicrosoftAspNetCoreWebUtilitiesPackageVersion>2.2.0-rtm-35519</MicrosoftAspNetCoreWebUtilitiesPackageVersion> <MicrosoftAspNetCoreWebUtilitiesPackageVersion>3.0.0-alpha1-10654</MicrosoftAspNetCoreWebUtilitiesPackageVersion>
<MicrosoftAspNetWebApiClientPackageVersion>5.2.6</MicrosoftAspNetWebApiClientPackageVersion> <MicrosoftAspNetWebApiClientPackageVersion>5.2.6</MicrosoftAspNetWebApiClientPackageVersion>
<MicrosoftBuildUtilitiesCorePackageVersion>15.6.82</MicrosoftBuildUtilitiesCorePackageVersion> <MicrosoftBuildUtilitiesCorePackageVersion>15.8.166</MicrosoftBuildUtilitiesCorePackageVersion>
<MicrosoftCodeAnalysisCSharpPackageVersion>2.8.0</MicrosoftCodeAnalysisCSharpPackageVersion> <MicrosoftCodeAnalysisCSharpPackageVersion>2.8.0</MicrosoftCodeAnalysisCSharpPackageVersion>
<MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>2.8.0</MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion> <MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>2.8.0</MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>
<MicrosoftCodeAnalysisRazorPackageVersion>2.2.0-rtm-35519</MicrosoftCodeAnalysisRazorPackageVersion> <MicrosoftCodeAnalysisRazorPackageVersion>3.0.0-alpha1-10654</MicrosoftCodeAnalysisRazorPackageVersion>
<MicrosoftDiaSymReaderNativePackageVersion>1.7.0</MicrosoftDiaSymReaderNativePackageVersion> <MicrosoftDiaSymReaderNativePackageVersion>1.7.0</MicrosoftDiaSymReaderNativePackageVersion>
<MicrosoftExtensionsCachingMemoryPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsCachingMemoryPackageVersion> <MicrosoftExtensionsCachingMemoryPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsCachingMemoryPackageVersion>
<MicrosoftExtensionsClosedGenericMatcherSourcesPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsClosedGenericMatcherSourcesPackageVersion> <MicrosoftExtensionsClosedGenericMatcherSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsClosedGenericMatcherSourcesPackageVersion>
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsConfigurationCommandLinePackageVersion> <MicrosoftExtensionsConfigurationCommandLinePackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
<MicrosoftExtensionsConfigurationJsonPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsConfigurationJsonPackageVersion> <MicrosoftExtensionsConfigurationJsonPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsConfigurationJsonPackageVersion>
<MicrosoftExtensionsConfigurationPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsConfigurationPackageVersion> <MicrosoftExtensionsConfigurationPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsConfigurationPackageVersion>
<MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion> <MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>
<MicrosoftExtensionsDependencyInjectionPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsDependencyInjectionPackageVersion> <MicrosoftExtensionsDependencyInjectionPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsDependencyInjectionPackageVersion>
<MicrosoftExtensionsDependencyModelPackageVersion>2.1.0</MicrosoftExtensionsDependencyModelPackageVersion> <MicrosoftExtensionsDependencyModelPackageVersion>3.0.0-preview1-26907-05</MicrosoftExtensionsDependencyModelPackageVersion>
<MicrosoftExtensionsDiagnosticAdapterPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsDiagnosticAdapterPackageVersion> <MicrosoftExtensionsDiagnosticAdapterPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsDiagnosticAdapterPackageVersion>
<MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion> <MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
<MicrosoftExtensionsFileProvidersCompositePackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsFileProvidersCompositePackageVersion> <MicrosoftExtensionsFileProvidersCompositePackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsFileProvidersCompositePackageVersion>
<MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsFileProvidersEmbeddedPackageVersion> <MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsFileSystemGlobbingPackageVersion> <MicrosoftExtensionsFileSystemGlobbingPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
<MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion> <MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>
<MicrosoftExtensionsLocalizationPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsLocalizationPackageVersion> <MicrosoftExtensionsLocalizationPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsLocalizationPackageVersion>
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsLoggingAbstractionsPackageVersion> <MicrosoftExtensionsLoggingAbstractionsPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
<MicrosoftExtensionsLoggingConsolePackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsLoggingConsolePackageVersion> <MicrosoftExtensionsLoggingConsolePackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsLoggingConsolePackageVersion>
<MicrosoftExtensionsLoggingDebugPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsLoggingDebugPackageVersion> <MicrosoftExtensionsLoggingDebugPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsLoggingDebugPackageVersion>
<MicrosoftExtensionsLoggingPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsLoggingPackageVersion> <MicrosoftExtensionsLoggingPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsLoggingPackageVersion>
<MicrosoftExtensionsLoggingTestingPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsLoggingTestingPackageVersion> <MicrosoftExtensionsLoggingTestingPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsLoggingTestingPackageVersion>
<MicrosoftExtensionsObjectMethodExecutorSourcesPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsObjectMethodExecutorSourcesPackageVersion> <MicrosoftExtensionsObjectMethodExecutorSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsObjectMethodExecutorSourcesPackageVersion>
<MicrosoftExtensionsOptionsPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsOptionsPackageVersion> <MicrosoftExtensionsOptionsPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsOptionsPackageVersion>
<MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion> <MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion>
<MicrosoftExtensionsPrimitivesPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsPrimitivesPackageVersion> <MicrosoftExtensionsPrimitivesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsPrimitivesPackageVersion>
<MicrosoftExtensionsPropertyActivatorSourcesPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsPropertyActivatorSourcesPackageVersion> <MicrosoftExtensionsPropertyActivatorSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsPropertyActivatorSourcesPackageVersion>
<MicrosoftExtensionsPropertyHelperSourcesPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsPropertyHelperSourcesPackageVersion> <MicrosoftExtensionsPropertyHelperSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsPropertyHelperSourcesPackageVersion>
<MicrosoftExtensionsSecurityHelperSourcesPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsSecurityHelperSourcesPackageVersion> <MicrosoftExtensionsSecurityHelperSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsSecurityHelperSourcesPackageVersion>
<MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsTypeNameHelperSourcesPackageVersion> <MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>
<MicrosoftExtensionsValueStopwatchSourcesPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsValueStopwatchSourcesPackageVersion> <MicrosoftExtensionsValueStopwatchSourcesPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsValueStopwatchSourcesPackageVersion>
<MicrosoftExtensionsWebEncodersPackageVersion>2.2.0-rtm-35519</MicrosoftExtensionsWebEncodersPackageVersion> <MicrosoftExtensionsWebEncodersPackageVersion>3.0.0-alpha1-10654</MicrosoftExtensionsWebEncodersPackageVersion>
<MicrosoftNETCoreApp20PackageVersion>2.0.9</MicrosoftNETCoreApp20PackageVersion> <MicrosoftNETCoreApp20PackageVersion>2.0.9</MicrosoftNETCoreApp20PackageVersion>
<MicrosoftNETCoreApp21PackageVersion>2.1.3</MicrosoftNETCoreApp21PackageVersion> <MicrosoftNETCoreApp21PackageVersion>2.1.3</MicrosoftNETCoreApp21PackageVersion>
<MicrosoftNETCoreApp22PackageVersion>2.2.0-preview3-27014-02</MicrosoftNETCoreApp22PackageVersion> <MicrosoftNETCoreApp22PackageVersion>2.2.0-preview3-27014-02</MicrosoftNETCoreApp22PackageVersion>
<MicrosoftNetHttpHeadersPackageVersion>2.2.0-rtm-35519</MicrosoftNetHttpHeadersPackageVersion> <MicrosoftNetHttpHeadersPackageVersion>3.0.0-alpha1-10654</MicrosoftNetHttpHeadersPackageVersion>
<MicrosoftNETSdkRazorPackageVersion>2.2.0-rtm-35519</MicrosoftNETSdkRazorPackageVersion> <MicrosoftNETSdkRazorPackageVersion>3.0.0-alpha1-10654</MicrosoftNETSdkRazorPackageVersion>
<MicrosoftNETTestSdkPackageVersion>15.6.1</MicrosoftNETTestSdkPackageVersion> <MicrosoftNETTestSdkPackageVersion>15.6.1</MicrosoftNETTestSdkPackageVersion>
<MoqPackageVersion>4.10.0</MoqPackageVersion> <MoqPackageVersion>4.10.0</MoqPackageVersion>
<NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion> <NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion>
<NewtonsoftJsonBsonPackageVersion>1.0.1</NewtonsoftJsonBsonPackageVersion> <NewtonsoftJsonBsonPackageVersion>1.0.1</NewtonsoftJsonBsonPackageVersion>
<NewtonsoftJsonPackageVersion>11.0.2</NewtonsoftJsonPackageVersion> <NewtonsoftJsonPackageVersion>11.0.2</NewtonsoftJsonPackageVersion>
<SystemComponentModelAnnotationsPackageVersion>4.5.0</SystemComponentModelAnnotationsPackageVersion> <SystemComponentModelAnnotationsPackageVersion>4.6.0-preview1-26907-04</SystemComponentModelAnnotationsPackageVersion>
<SystemDiagnosticsDiagnosticSourcePackageVersion>4.5.0</SystemDiagnosticsDiagnosticSourcePackageVersion> <SystemDiagnosticsDiagnosticSourcePackageVersion>4.6.0-preview1-26907-04</SystemDiagnosticsDiagnosticSourcePackageVersion>
<SystemNetHttpPackageVersion>4.3.2</SystemNetHttpPackageVersion> <SystemNetHttpPackageVersion>4.3.2</SystemNetHttpPackageVersion>
<SystemThreadingTasksExtensionsPackageVersion>4.5.1</SystemThreadingTasksExtensionsPackageVersion> <SystemThreadingTasksExtensionsPackageVersion>4.6.0-preview1-26907-04</SystemThreadingTasksExtensionsPackageVersion>
<XunitAnalyzersPackageVersion>0.10.0</XunitAnalyzersPackageVersion> <XunitAnalyzersPackageVersion>0.10.0</XunitAnalyzersPackageVersion>
<XunitPackageVersion>2.3.1</XunitPackageVersion> <XunitPackageVersion>2.3.1</XunitPackageVersion>
<XunitRunnerVisualStudioPackageVersion>2.4.0</XunitRunnerVisualStudioPackageVersion> <XunitRunnerVisualStudioPackageVersion>2.4.0</XunitRunnerVisualStudioPackageVersion>

View File

@ -3,6 +3,7 @@
<PropertyGroup> <PropertyGroup>
<EnableBenchmarkValidation>true</EnableBenchmarkValidation> <EnableBenchmarkValidation>true</EnableBenchmarkValidation>
<VSTestVerboseOutput Condition="'$(CI)' == 'true'">true</VSTestVerboseOutput>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@ -14,7 +15,6 @@
<PropertyGroup> <PropertyGroup>
<!-- These properties are use by the automation that updates dependencies.props --> <!-- These properties are use by the automation that updates dependencies.props -->
<LineupPackageId>Internal.AspNetCore.Universe.Lineup</LineupPackageId> <LineupPackageId>Internal.AspNetCore.Universe.Lineup</LineupPackageId>
<LineupPackageVersion>2.2.0-*</LineupPackageVersion>
<LineupPackageRestoreSource>https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json</LineupPackageRestoreSource> <LineupPackageRestoreSource>https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json</LineupPackageRestoreSource>
</PropertyGroup> </PropertyGroup>

View File

@ -3,6 +3,6 @@
"version": "2.2.100-preview2-009404" "version": "2.2.100-preview2-009404"
}, },
"msbuild-sdks": { "msbuild-sdks": {
"Internal.AspNetCore.Sdk": "2.2.0-preview2-20181003.2" "Internal.AspNetCore.Sdk": "3.0.0-alpha1-20181011.11"
} }
} }

View File

@ -1,2 +1,2 @@
version:2.2.0-preview2-20181003.2 version:3.0.0-alpha1-20181011.11
commithash:41935e62d7853060283c801f49992e2c73a95927 commithash:f57aa8ddda0abdd74ada55853587bedb4f364065

View File

@ -1,4 +1,4 @@
{ {
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/release/2.2/tools/korebuild.schema.json", "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/master/tools/korebuild.schema.json",
"channel": "release/2.2" "channel": "master"
} }

View File

@ -0,0 +1,21 @@
// 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 MvcSandbox.AuthorizationMiddleware;
namespace Microsoft.AspNetCore.Builder
{
public static class AuthorizationAppBuilderExtensions
{
public static IApplicationBuilder UseAuthorization(this IApplicationBuilder app)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}
return app.UseMiddleware<AuthorizationMiddleware>();
}
}
}

View File

@ -0,0 +1,16 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Routing;
namespace MvcSandbox.AuthorizationMiddleware
{
public static class AuthorizationEndpointConventionBuilder
{
public static T RequireAuthorization<T>(this T builder, params string[] roles) where T : IEndpointConventionBuilder
{
builder.Apply(model => model.Metadata.Add(new AuthorizeMetadataAttribute(roles)));
return builder;
}
}
}

View File

@ -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 System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Primitives;
namespace MvcSandbox.AuthorizationMiddleware
{
public class AuthorizationMiddleware
{
private readonly RequestDelegate _next;
public AuthorizationMiddleware(RequestDelegate next)
{
if (next == null)
{
throw new ArgumentNullException(nameof(next));
}
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
var endpoint = httpContext.Features.Get<IEndpointFeature>()?.Endpoint;
var metadata = endpoint?.Metadata?.GetMetadata<AuthorizeMetadataAttribute>();
// Only run authorization if endpoint has metadata
if (metadata != null)
{
// Check if role querystring value is a valid role
if (!httpContext.Request.Query.TryGetValue("role", out var role) ||
!metadata.Roles.Contains(role.ToString(), StringComparer.OrdinalIgnoreCase))
{
httpContext.Response.StatusCode = 401;
httpContext.Response.ContentType = "text/plain";
await httpContext.Response.WriteAsync($"Unauthorized access to '{endpoint.DisplayName}'.");
return;
}
}
await _next(httpContext);
}
}
}

View File

@ -0,0 +1,20 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MvcSandbox.AuthorizationMiddleware
{
public class AuthorizeMetadataAttribute : Attribute
{
public AuthorizeMetadataAttribute(string[] roles)
{
Roles = roles;
}
public string[] Roles { get; }
}
}

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using MvcSandbox.AuthorizationMiddleware;
namespace MvcSandbox.Controllers namespace MvcSandbox.Controllers
{ {

View File

@ -0,0 +1,16 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Mvc;
namespace MvcSandbox.Controllers
{
[Route("[controller]/[action]")]
public class LoginController : Controller
{
public IActionResult Index()
{
return View();
}
}
}

View File

@ -0,0 +1,28 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
namespace Microsoft.AspNetCore.Builder
{
public static class HealthChecksEndpointRouteBuilderExtensions
{
private static readonly Random _random = new Random();
public static IEndpointConventionBuilder MapHealthChecks(this IEndpointRouteBuilder builder, string pattern)
{
return builder.MapGet(
pattern,
async httpContext =>
{
await httpContext.Response.WriteAsync(_random.Next() % 2 == 0 ? "Up!" : "Down!");
});
}
}
}

View File

@ -1,11 +1,18 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // 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.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using MvcSandbox.AuthorizationMiddleware;
namespace MvcSandbox namespace MvcSandbox
{ {
@ -20,14 +27,46 @@ namespace MvcSandbox
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app) public void Configure(IApplicationBuilder app)
{ {
app.UseDeveloperExceptionPage(); app.UseEndpointRouting(builder =>
app.UseStaticFiles();
app.UseMvc(routes =>
{ {
routes.MapRoute( builder.MapGet(
requestDelegate: WriteEndpoints,
pattern: "/endpoints",
displayName: "Home");
builder.MapMvcRoute(
name: "default", name: "default",
template: "{controller=Home}/{action=Index}/{id?}"); template: "{controller=Home}/{action=Index}/{id?}");
builder.MapMvcControllers();
builder.MapRazorPages();
builder.MapHealthChecks("/healthz");
}); });
app.UseDeveloperExceptionPage();
app.UseStaticFiles();
app.UseAuthorization();
app.UseEndpoint();
}
private static Task WriteEndpoints(HttpContext httpContext)
{
var dataSource = httpContext.RequestServices.GetRequiredService<CompositeEndpointDataSource>();
var sb = new StringBuilder();
sb.AppendLine("Endpoints:");
foreach (var endpoint in dataSource.Endpoints.OfType<RouteEndpoint>().OrderBy(e => e.RoutePattern.RawText, StringComparer.OrdinalIgnoreCase))
{
sb.AppendLine($"- {endpoint.RoutePattern.RawText} '{endpoint.DisplayName}'");
}
var response = httpContext.Response;
response.StatusCode = 200;
response.ContentType = "text/plain";
return response.WriteAsync(sb.ToString());
} }
public static void Main(string[] args) public static void Main(string[] args)

View File

@ -0,0 +1,24 @@
// 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.Routing;
namespace Microsoft.AspNetCore.Builder
{
internal class DefaultEndpointConventionBuilder : IEndpointConventionBuilder
{
public DefaultEndpointConventionBuilder()
{
Conventions = new List<Action<EndpointModel>>();
}
public List<Action<EndpointModel>> Conventions { get; }
public void Apply(Action<EndpointModel> convention)
{
Conventions.Add(convention);
}
}
}

View File

@ -90,9 +90,7 @@ namespace Microsoft.AspNetCore.Builder
if (options.Value.EnableEndpointRouting) if (options.Value.EnableEndpointRouting)
{ {
var mvcEndpointDataSource = app.ApplicationServices var mvcEndpointDataSource = app.ApplicationServices
.GetRequiredService<IEnumerable<EndpointDataSource>>() .GetRequiredService<MvcEndpointDataSource>();
.OfType<MvcEndpointDataSource>()
.First();
var parameterPolicyFactory = app.ApplicationServices var parameterPolicyFactory = app.ApplicationServices
.GetRequiredService<ParameterPolicyFactory>(); .GetRequiredService<ParameterPolicyFactory>();
@ -122,11 +120,21 @@ namespace Microsoft.AspNetCore.Builder
} }
} }
// Include all controllers with attribute routing and Razor pages
var defaultEndpointConventionBuilder = new DefaultEndpointConventionBuilder();
mvcEndpointDataSource.AttributeRoutingConventionResolvers.Add((actionDescriptor) =>
{
return defaultEndpointConventionBuilder;
});
if (!app.Properties.TryGetValue(EndpointRoutingRegisteredKey, out _)) if (!app.Properties.TryGetValue(EndpointRoutingRegisteredKey, out _))
{ {
// Matching middleware has not been registered yet // Matching middleware has not been registered yet
// For back-compat register middleware so an endpoint is matched and then immediately used // For back-compat register middleware so an endpoint is matched and then immediately used
app.UseEndpointRouting(); app.UseEndpointRouting(routerBuilder =>
{
routerBuilder.DataSources.Add(mvcEndpointDataSource);
});
} }
return app.UseEndpoint(); return app.UseEndpoint();

View File

@ -9,7 +9,7 @@ using Microsoft.AspNetCore.Routing.Patterns;
namespace Microsoft.AspNetCore.Builder namespace Microsoft.AspNetCore.Builder
{ {
internal class MvcEndpointInfo internal class MvcEndpointInfo : DefaultEndpointConventionBuilder
{ {
public MvcEndpointInfo( public MvcEndpointInfo(
string name, string name,
@ -43,6 +43,7 @@ namespace Microsoft.AspNetCore.Builder
public string Name { get; } public string Name { get; }
public string Pattern { get; } public string Pattern { get; }
public Type ControllerType { get; set; }
// Non-inline defaults // Non-inline defaults
public RouteValueDictionary Defaults { get; } public RouteValueDictionary Defaults { get; }

View File

@ -0,0 +1,148 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Builder
{
public static class MvcEndpointRouteBuilderExtensions
{
public static IEndpointConventionBuilder MapMvcControllers(
this IEndpointRouteBuilder routeBuilder)
{
return MapMvcControllers<ControllerBase>(routeBuilder);
}
public static IEndpointConventionBuilder MapMvcControllers<TController>(
this IEndpointRouteBuilder routeBuilder) where TController : ControllerBase
{
var mvcEndpointDataSource = routeBuilder.DataSources.OfType<MvcEndpointDataSource>().FirstOrDefault();
if (mvcEndpointDataSource == null)
{
mvcEndpointDataSource = routeBuilder.ServiceProvider.GetRequiredService<MvcEndpointDataSource>();
routeBuilder.DataSources.Add(mvcEndpointDataSource);
}
var conventionBuilder = new DefaultEndpointConventionBuilder();
mvcEndpointDataSource.AttributeRoutingConventionResolvers.Add(actionDescriptor =>
{
if (actionDescriptor is ControllerActionDescriptor controllerActionDescriptor &&
typeof(TController).IsAssignableFrom(controllerActionDescriptor.ControllerTypeInfo))
{
return conventionBuilder;
}
return null;
});
return conventionBuilder;
}
public static IEndpointConventionBuilder MapMvcRoute(
this IEndpointRouteBuilder routeBuilder,
string name,
string template)
{
return MapMvcRoute<ControllerBase>(routeBuilder, name, template, defaults: null);
}
public static IEndpointConventionBuilder MapMvcRoute(
this IEndpointRouteBuilder routeBuilder,
string name,
string template,
object defaults)
{
return MapMvcRoute<ControllerBase>(routeBuilder, name, template, defaults, constraints: null);
}
public static IEndpointConventionBuilder MapMvcRoute(
this IEndpointRouteBuilder routeBuilder,
string name,
string template,
object defaults,
object constraints)
{
return MapMvcRoute<ControllerBase>(routeBuilder, name, template, defaults, constraints, dataTokens: null);
}
public static IEndpointConventionBuilder MapMvcRoute(
this IEndpointRouteBuilder routeBuilder,
string name,
string template,
object defaults,
object constraints,
object dataTokens)
{
return MapMvcRoute<ControllerBase>(routeBuilder, name, template, defaults, constraints, dataTokens);
}
public static IEndpointConventionBuilder MapMvcRoute<TController>(
this IEndpointRouteBuilder routeBuilder,
string name,
string template) where TController : ControllerBase
{
return MapMvcRoute<TController>(routeBuilder, name, template, defaults: null);
}
public static IEndpointConventionBuilder MapMvcRoute<TController>(
this IEndpointRouteBuilder routeBuilder,
string name,
string template,
object defaults) where TController : ControllerBase
{
return MapMvcRoute<TController>(routeBuilder, name, template, defaults, constraints: null);
}
public static IEndpointConventionBuilder MapMvcRoute<TController>(
this IEndpointRouteBuilder routeBuilder,
string name,
string template,
object defaults,
object constraints) where TController : ControllerBase
{
return MapMvcRoute<TController>(routeBuilder, name, template, defaults, constraints, dataTokens: null);
}
public static IEndpointConventionBuilder MapMvcRoute<TController>(
this IEndpointRouteBuilder routeBuilder,
string name,
string template,
object defaults,
object constraints,
object dataTokens) where TController : ControllerBase
{
var mvcEndpointDataSource = routeBuilder.DataSources.OfType<MvcEndpointDataSource>().FirstOrDefault();
if (mvcEndpointDataSource == null)
{
mvcEndpointDataSource = routeBuilder.ServiceProvider.GetRequiredService<MvcEndpointDataSource>();
routeBuilder.DataSources.Add(mvcEndpointDataSource);
}
var endpointInfo = new MvcEndpointInfo(
name,
template,
new RouteValueDictionary(defaults),
new RouteValueDictionary(constraints),
new RouteValueDictionary(dataTokens),
routeBuilder.ServiceProvider.GetRequiredService<ParameterPolicyFactory>());
endpointInfo.ControllerType = typeof(TController);
mvcEndpointDataSource.ConventionalEndpointInfos.Add(endpointInfo);
return endpointInfo;
}
}
}

View File

@ -270,8 +270,7 @@ namespace Microsoft.Extensions.DependencyInjection
// //
// Endpoint Routing / Endpoints // Endpoint Routing / Endpoints
// //
services.TryAddEnumerable( services.TryAddSingleton<MvcEndpointDataSource>();
ServiceDescriptor.Singleton<EndpointDataSource, MvcEndpointDataSource>());
services.TryAddSingleton<MvcEndpointInvokerFactory>(); services.TryAddSingleton<MvcEndpointInvokerFactory>();
// //

View File

@ -10,6 +10,7 @@ using System.Threading;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Routing; using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing;
@ -57,6 +58,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
_parameterPolicyFactory = parameterPolicyFactory; _parameterPolicyFactory = parameterPolicyFactory;
ConventionalEndpointInfos = new List<MvcEndpointInfo>(); ConventionalEndpointInfos = new List<MvcEndpointInfo>();
AttributeRoutingConventionResolvers = new List<Func<ActionDescriptor, DefaultEndpointConventionBuilder>>();
// IMPORTANT: this needs to be the last thing we do in the constructor. Change notifications can happen immediately! // IMPORTANT: this needs to be the last thing we do in the constructor. Change notifications can happen immediately!
// //
@ -72,6 +74,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal
public List<MvcEndpointInfo> ConventionalEndpointInfos { get; } public List<MvcEndpointInfo> ConventionalEndpointInfos { get; }
public List<Func<ActionDescriptor, DefaultEndpointConventionBuilder>> AttributeRoutingConventionResolvers { get; }
public override IReadOnlyList<Endpoint> Endpoints public override IReadOnlyList<Endpoint> Endpoints
{ {
get get
@ -134,6 +138,16 @@ namespace Microsoft.AspNetCore.Mvc.Internal
// - Home/Login // - Home/Login
foreach (var endpointInfo in ConventionalEndpointInfos) foreach (var endpointInfo in ConventionalEndpointInfos)
{ {
if (endpointInfo.ControllerType != null &&
endpointInfo.ControllerType != typeof(ControllerBase))
{
if (!ValidateControllerConstraint(action, endpointInfo))
{
// Action descriptor does not belong to a controller of the specified type
continue;
}
}
// An 'endpointInfo' is applicable if: // An 'endpointInfo' is applicable if:
// 1. it has a parameter (or default value) for 'required' non-null route value // 1. it has a parameter (or default value) for 'required' non-null route value
// 2. it does not have a parameter (or default value) for 'required' null route value // 2. it does not have a parameter (or default value) for 'required' null route value
@ -164,11 +178,20 @@ namespace Microsoft.AspNetCore.Mvc.Internal
endpointInfo.DataTokens, endpointInfo.DataTokens,
endpointInfo.ParameterPolicies, endpointInfo.ParameterPolicies,
suppressLinkGeneration: false, suppressLinkGeneration: false,
suppressPathMatching: false); suppressPathMatching: false,
endpointInfo.Conventions);
} }
} }
else else
{ {
var conventionBuilder = ResolveActionConventionBuilder(action);
if (conventionBuilder == null)
{
// No convention builder for this action
// Do not create an endpoint for it
continue;
}
var attributeRoutePattern = RoutePatternFactory.Parse(action.AttributeRouteInfo.Template); var attributeRoutePattern = RoutePatternFactory.Parse(action.AttributeRouteInfo.Template);
CreateEndpoints( CreateEndpoints(
@ -183,7 +206,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal
dataTokens: null, dataTokens: null,
allParameterPolicies: null, allParameterPolicies: null,
action.AttributeRouteInfo.SuppressLinkGeneration, action.AttributeRouteInfo.SuppressLinkGeneration,
action.AttributeRouteInfo.SuppressPathMatching); action.AttributeRouteInfo.SuppressPathMatching,
conventionBuilder.Conventions);
} }
} }
@ -205,6 +229,30 @@ namespace Microsoft.AspNetCore.Mvc.Internal
} }
} }
private DefaultEndpointConventionBuilder ResolveActionConventionBuilder(ActionDescriptor action)
{
foreach (var filter in AttributeRoutingConventionResolvers)
{
var conventionBuilder = filter(action);
if (conventionBuilder != null)
{
return conventionBuilder;
}
}
return null;
}
private static bool ValidateControllerConstraint(ActionDescriptor action, MvcEndpointInfo endpointInfo)
{
if (action is ControllerActionDescriptor controllerActionDescriptor)
{
return endpointInfo.ControllerType.IsAssignableFrom(controllerActionDescriptor.ControllerTypeInfo);
}
return false;
}
// CreateEndpoints processes the route pattern, replacing area/controller/action parameters with endpoint values // CreateEndpoints processes the route pattern, replacing area/controller/action parameters with endpoint values
// Because of default values it is possible for a route pattern to resolve to multiple endpoints // Because of default values it is possible for a route pattern to resolve to multiple endpoints
private int CreateEndpoints( private int CreateEndpoints(
@ -219,7 +267,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal
RouteValueDictionary dataTokens, RouteValueDictionary dataTokens,
IDictionary<string, IList<IParameterPolicy>> allParameterPolicies, IDictionary<string, IList<IParameterPolicy>> allParameterPolicies,
bool suppressLinkGeneration, bool suppressLinkGeneration,
bool suppressPathMatching) bool suppressPathMatching,
List<Action<EndpointModel>> conventions)
{ {
var newPathSegments = routePattern.PathSegments.ToList(); var newPathSegments = routePattern.PathSegments.ToList();
var hasLinkGenerationEndpoint = false; var hasLinkGenerationEndpoint = false;
@ -264,7 +313,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal
routeOrder++, routeOrder++,
dataTokens, dataTokens,
suppressLinkGeneration, suppressLinkGeneration,
true); true,
conventions);
endpoints.Add(ep); endpoints.Add(ep);
hasLinkGenerationEndpoint = true; hasLinkGenerationEndpoint = true;
@ -282,7 +332,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal
routeOrder++, routeOrder++,
dataTokens, dataTokens,
suppressLinkGeneration, suppressLinkGeneration,
suppressPathMatching); suppressPathMatching,
conventions);
endpoints.Add(subEndpoint); endpoints.Add(subEndpoint);
} }
@ -299,7 +350,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal
routeOrder++, routeOrder++,
dataTokens, dataTokens,
suppressLinkGeneration, suppressLinkGeneration,
suppressPathMatching); suppressPathMatching,
conventions);
endpoints.Add(finalEndpoint); endpoints.Add(finalEndpoint);
return routeOrder; return routeOrder;
@ -406,6 +458,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
{ {
newPathSegments[i] = RoutePatternFactory.Segment(segmentParts); newPathSegments[i] = RoutePatternFactory.Segment(segmentParts);
} }
} }
private bool UseDefaultValuePlusRemainingSegmentsOptional( private bool UseDefaultValuePlusRemainingSegmentsOptional(
@ -536,7 +589,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal
int order, int order,
RouteValueDictionary dataTokens, RouteValueDictionary dataTokens,
bool suppressLinkGeneration, bool suppressLinkGeneration,
bool suppressPathMatching) bool suppressPathMatching,
List<Action<EndpointModel>> conventions)
{ {
RequestDelegate requestDelegate = (context) => RequestDelegate requestDelegate = (context) =>
{ {
@ -551,7 +605,10 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var defaults = new RouteValueDictionary(nonInlineDefaults); var defaults = new RouteValueDictionary(nonInlineDefaults);
EnsureRequiredValuesInDefaults(actionRouteValues, defaults, segments); EnsureRequiredValuesInDefaults(actionRouteValues, defaults, segments);
var metadataCollection = BuildEndpointMetadata( var model = new RouteEndpointModel(requestDelegate, RoutePatternFactory.Pattern(patternRawText, defaults, parameterPolicies: null, segments), order);
AddEndpointMetadata(
model.Metadata,
action, action,
routeName, routeName,
new RouteValueDictionary(actionRouteValues), new RouteValueDictionary(actionRouteValues),
@ -559,17 +616,23 @@ namespace Microsoft.AspNetCore.Mvc.Internal
suppressLinkGeneration, suppressLinkGeneration,
suppressPathMatching); suppressPathMatching);
var endpoint = new RouteEndpoint( model.DisplayName = action.DisplayName;
requestDelegate,
RoutePatternFactory.Pattern(patternRawText, defaults, parameterPolicies: null, segments),
order,
metadataCollection,
action.DisplayName);
return endpoint; // REVIEW: When should conventions be run
// Metadata should have lower precedence that data source metadata
if (conventions != null)
{
foreach (var convention in conventions)
{
convention(model);
}
}
return (RouteEndpoint)model.Build();
} }
private static EndpointMetadataCollection BuildEndpointMetadata( private static void AddEndpointMetadata(
IList<object> metadata,
ActionDescriptor action, ActionDescriptor action,
string routeName, string routeName,
RouteValueDictionary requiredValues, RouteValueDictionary requiredValues,
@ -577,14 +640,15 @@ namespace Microsoft.AspNetCore.Mvc.Internal
bool suppressLinkGeneration, bool suppressLinkGeneration,
bool suppressPathMatching) bool suppressPathMatching)
{ {
var metadata = new List<object>();
// Add action metadata first so it has a low precedence // Add action metadata first so it has a low precedence
if (action.EndpointMetadata != null) if (action.EndpointMetadata != null)
{ {
metadata.AddRange(action.EndpointMetadata); foreach (var d in action.EndpointMetadata)
{
metadata.Add(d);
}
} }
metadata.Add(action); metadata.Add(action);
if (dataTokens != null) if (dataTokens != null)
@ -597,8 +661,10 @@ namespace Microsoft.AspNetCore.Mvc.Internal
// Add filter descriptors to endpoint metadata // Add filter descriptors to endpoint metadata
if (action.FilterDescriptors != null && action.FilterDescriptors.Count > 0) if (action.FilterDescriptors != null && action.FilterDescriptors.Count > 0)
{ {
metadata.AddRange(action.FilterDescriptors.OrderBy(f => f, FilterDescriptorOrderComparer.Comparer) foreach (var filter in action.FilterDescriptors.OrderBy(f => f, FilterDescriptorOrderComparer.Comparer).Select(f => f.Filter))
.Select(f => f.Filter)); {
metadata.Add(filter);
}
} }
if (action.ActionConstraints != null && action.ActionConstraints.Count > 0) if (action.ActionConstraints != null && action.ActionConstraints.Count > 0)
@ -637,9 +703,6 @@ namespace Microsoft.AspNetCore.Mvc.Internal
{ {
metadata.Add(new SuppressMatchingMetadata()); metadata.Add(new SuppressMatchingMetadata());
} }
var metadataCollection = new EndpointMetadataCollection(metadata);
return metadataCollection;
} }
// Ensure route values are a subset of defaults // Ensure route values are a subset of defaults

View File

@ -0,0 +1,47 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Builder
{
public static class RazorPagesEndpointRouteBuilderExtensions
{
public static IEndpointConventionBuilder MapRazorPages(
this IEndpointRouteBuilder routeBuilder,
string basePath = null)
{
var mvcEndpointDataSource = routeBuilder.DataSources.OfType<MvcEndpointDataSource>().FirstOrDefault();
if (mvcEndpointDataSource == null)
{
mvcEndpointDataSource = routeBuilder.ServiceProvider.GetRequiredService<MvcEndpointDataSource>();
routeBuilder.DataSources.Add(mvcEndpointDataSource);
}
var conventionBuilder = new DefaultEndpointConventionBuilder();
mvcEndpointDataSource.AttributeRoutingConventionResolvers.Add(actionDescriptor =>
{
if (actionDescriptor is PageActionDescriptor pageActionDescriptor)
{
// TODO: Filter pages by path
return conventionBuilder;
}
return null;
});
return conventionBuilder;
}
}
}

View File

@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Builder.Internal;
using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Moq; using Moq;
using Xunit; using Xunit;
@ -56,12 +57,10 @@ namespace Microsoft.AspNetCore.Mvc.Core.Builder
template: "{controller=Home}/{action=Index}/{id?}"); template: "{controller=Home}/{action=Index}/{id?}");
}); });
var mvcEndpointDataSource = appBuilder.ApplicationServices var routeOptions = appBuilder.ApplicationServices
.GetRequiredService<IEnumerable<EndpointDataSource>>() .GetRequiredService<IOptions<RouteOptions>>();
.OfType<MvcEndpointDataSource>()
.First();
Assert.Empty(mvcEndpointDataSource.ConventionalEndpointInfos); Assert.Empty(routeOptions.Value.EndpointDataSources);
} }
[Fact] [Fact]
@ -83,10 +82,10 @@ namespace Microsoft.AspNetCore.Mvc.Core.Builder
template: "{controller=Home}/{action=Index}/{id?}"); template: "{controller=Home}/{action=Index}/{id?}");
}); });
var mvcEndpointDataSource = appBuilder.ApplicationServices var routeOptions = appBuilder.ApplicationServices
.GetRequiredService<IEnumerable<EndpointDataSource>>() .GetRequiredService<IOptions<RouteOptions>>();
.OfType<MvcEndpointDataSource>()
.First(); var mvcEndpointDataSource = (MvcEndpointDataSource)Assert.Single(routeOptions.Value.EndpointDataSources, ds => ds is MvcEndpointDataSource);
var endpointInfo = Assert.Single(mvcEndpointDataSource.ConventionalEndpointInfos); var endpointInfo = Assert.Single(mvcEndpointDataSource.ConventionalEndpointInfos);
Assert.Equal("default", endpointInfo.Name); Assert.Equal("default", endpointInfo.Name);

View File

@ -315,13 +315,6 @@ namespace Microsoft.AspNetCore.Mvc
typeof(ApiBehaviorApplicationModelProvider), typeof(ApiBehaviorApplicationModelProvider),
} }
}, },
{
typeof(EndpointDataSource),
new Type[]
{
typeof(MvcEndpointDataSource),
}
},
{ {
typeof(IStartupFilter), typeof(IStartupFilter),
new Type[] new Type[]

View File

@ -1359,6 +1359,12 @@ namespace Microsoft.AspNetCore.Mvc.Internal
mvcEndpointInvokerFactory ?? new MvcEndpointInvokerFactory(new ActionInvokerFactory(Array.Empty<IActionInvokerProvider>())), mvcEndpointInvokerFactory ?? new MvcEndpointInvokerFactory(new ActionInvokerFactory(Array.Empty<IActionInvokerProvider>())),
serviceProvider.GetRequiredService<ParameterPolicyFactory>()); serviceProvider.GetRequiredService<ParameterPolicyFactory>());
var defaultEndpointConventionBuilder = new DefaultEndpointConventionBuilder();
dataSource.AttributeRoutingConventionResolvers.Add((actionDescriptor) =>
{
return defaultEndpointConventionBuilder;
});
return dataSource; return dataSource;
} }

View File

@ -1457,6 +1457,24 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
Assert.Equal(actionName, result.Action); Assert.Equal(actionName, result.Action);
} }
[Fact]
public async Task RazorPage_WithLinks_GeneratesLinksCorrectly()
{
// Arrange & Act
var response = await Client.GetAsync("http://localhost/PageWithLinks");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var document = await response.GetHtmlDocumentAsync();
var editLink = document.RequiredQuerySelector("#editlink");
Assert.Equal("/Edit/10", editLink.GetAttribute("href"));
var contactLink = document.RequiredQuerySelector("#contactlink");
Assert.Equal("/Home/Contact", contactLink.GetAttribute("href"));
}
[Fact] [Fact]
public async Task CanRunMiddlewareAfterRouting() public async Task CanRunMiddlewareAfterRouting()
{ {

View File

@ -353,6 +353,7 @@ namespace Microsoft.AspNetCore.Mvc
new Type[] new Type[]
{ {
typeof(MvcCoreRouteOptionsSetup), typeof(MvcCoreRouteOptionsSetup),
typeof(MvcCoreRouteOptionsSetup),
} }
}, },
{ {

View File

@ -0,0 +1,3 @@
@page "{id}"
Hello from Edit page

View File

@ -0,0 +1,8 @@
@page
@addTagHelper "*, Microsoft.AspNetCore.Mvc.TagHelpers"
@{
}
<a id="editlink" asp-page="/Edit" asp-route-id="10">Edit</a>
<br />
<a id="contactlink" asp-action="Contact" asp-controller="Home">Contact</a>

View File

@ -1,7 +1,7 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<VersionPrefix>2.2.0</VersionPrefix> <VersionPrefix>3.0.0</VersionPrefix>
<VersionSuffix>rtm</VersionSuffix> <VersionSuffix>alpha1</VersionSuffix>
<BuildNumber Condition="'$(BuildNumber)' == ''">t000</BuildNumber> <BuildNumber Condition="'$(BuildNumber)' == ''">t000</BuildNumber>
<FeatureBranchVersionPrefix Condition="'$(FeatureBranchVersionPrefix)' == ''">a-</FeatureBranchVersionPrefix> <FeatureBranchVersionPrefix Condition="'$(FeatureBranchVersionPrefix)' == ''">a-</FeatureBranchVersionPrefix>
@ -9,5 +9,13 @@
<PackageVersion Condition="'$(IsFinalBuild)' == 'true' AND '$(VersionSuffix)' != 'rtm' ">$(VersionPrefix)-$(VersionSuffix)-final</PackageVersion> <PackageVersion Condition="'$(IsFinalBuild)' == 'true' AND '$(VersionSuffix)' != 'rtm' ">$(VersionPrefix)-$(VersionSuffix)-final</PackageVersion>
<VersionSuffix Condition="'$(VersionSuffix)' != '' And '$(FeatureBranchVersionSuffix)' != ''">$(FeatureBranchVersionPrefix)$(VersionSuffix)-$([System.Text.RegularExpressions.Regex]::Replace('$(FeatureBranchVersionSuffix)', '[^\w-]', '-'))</VersionSuffix> <VersionSuffix Condition="'$(VersionSuffix)' != '' And '$(FeatureBranchVersionSuffix)' != ''">$(FeatureBranchVersionPrefix)$(VersionSuffix)-$([System.Text.RegularExpressions.Regex]::Replace('$(FeatureBranchVersionSuffix)', '[^\w-]', '-'))</VersionSuffix>
<VersionSuffix Condition="'$(VersionSuffix)' != '' And '$(BuildNumber)' != ''">$(VersionSuffix)-$(BuildNumber)</VersionSuffix> <VersionSuffix Condition="'$(VersionSuffix)' != '' And '$(BuildNumber)' != ''">$(VersionSuffix)-$(BuildNumber)</VersionSuffix>
<ExperimentalVersionPrefix>0.3.0</ExperimentalVersionPrefix>
<ExperimentalVersionSuffix>alpha1</ExperimentalVersionSuffix>
<ExperimentalPackageVersion Condition="'$(IsFinalBuild)' == 'true' AND '$(ExperimentalVersionSuffix)' == 'rtm' ">$(ExperimentalVersionPrefix)</ExperimentalPackageVersion>
<ExperimentalPackageVersion Condition="'$(IsFinalBuild)' == 'true' AND '$(ExperimentalVersionSuffix)' != 'rtm' ">$(ExperimentalVersionPrefix)-$(ExperimentalVersionSuffix)-final</ExperimentalPackageVersion>
<ExperimentalVersionSuffix Condition="'$(ExperimentalVersionSuffix)' != '' And '$(FeatureBranchVersionSuffix)' != ''">$(FeatureBranchVersionPrefix)$(ExperimentalVersionSuffix)-$([System.Text.RegularExpressions.Regex]::Replace('$(FeatureBranchVersionSuffix)', '[^\w-]', '-'))</ExperimentalVersionSuffix>
<ExperimentalVersionSuffix Condition="'$(ExperimentalVersionSuffix)' != '' And '$(BuildNumber)' != ''">$(ExperimentalVersionSuffix)-$(BuildNumber)</ExperimentalVersionSuffix>
</PropertyGroup> </PropertyGroup>
</Project> </Project>