diff --git a/.azure/pipelines/blazor-daily-tests.yml b/.azure/pipelines/blazor-daily-tests.yml
new file mode 100644
index 000000000000..77ac645ff504
--- /dev/null
+++ b/.azure/pipelines/blazor-daily-tests.yml
@@ -0,0 +1,67 @@
+# Uses Scheduled Triggers, which aren't supported in YAML yet.
+# https://docs.microsoft.com/en-us/azure/devops/pipelines/build/triggers?view=vsts&tabs=yaml#scheduled
+
+# Daily Tests for Blazor
+# These use Sauce Labs resources, hence they run daily rather than per-commit.
+
+# We just need one Windows machine because all it does is trigger SauceLabs.
+variables:
+ - ${{ if ne(variables['System.TeamProject'], 'public') }}:
+ - group: DotNet-MSRC-Storage
+ - group: AzureDevOps-Artifact-Feeds-Pats
+ - name: SAUCE_CONNECT_DOWNLOAD_ON_INSTALL
+ value: true
+ - name: E2ETESTS_SauceTest
+ value: true
+ - name: E2ETESTS_Sauce__TunnelIdentifier
+ value: 'blazor-e2e-sc-proxy-tunnel'
+ - name: E2ETESTS_Sauce__HostName
+ value: 'sauce.local'
+
+jobs:
+- template: jobs/default-build.yml
+ parameters:
+ buildDirectory: src/Components
+ isTestingJob: true
+ agentOs: Windows
+ jobName: BlazorDailyTests
+ jobDisplayName: "Blazor Daily Tests"
+ afterBuild:
+
+ # macOS/Safari
+ - script: 'dotnet test --no-build --configuration Release --filter "StandaloneAppTest"'
+ workingDirectory: 'src/Components/test/E2ETest'
+ displayName: 'Run Blazor tests - macOS/Safari'
+ condition: succeededOrFailed()
+ env:
+ # Secrets need to be explicitly mapped to env variables.
+ E2ETESTS_Sauce__Username: '$(asplab-sauce-labs-username)'
+ E2ETESTS_Sauce__AccessKey: '$(asplab-sauce-labs-access-key)'
+ # Set platform/browser configuration.
+ E2ETESTS_Sauce__TestName: 'Blazor Daily Tests - macOS/Safari'
+ E2ETESTS_Sauce__PlatformName: 'macOS 10.14'
+ E2ETESTS_Sauce__BrowserName: 'Safari'
+ # Need to explicitly set version here because some older versions don't support timeouts in Safari.
+ E2ETESTS_Sauce__SeleniumVersion: '3.4.0'
+
+ # Android/Chrome
+ - script: 'dotnet test --no-build --configuration Release --filter "StandaloneAppTest"'
+ workingDirectory: 'src/Components/test/E2ETest'
+ displayName: 'Run Blazor tests - Android/Chrome'
+ condition: succeededOrFailed()
+ env:
+ # Secrets need to be explicitly mapped to env variables.
+ E2ETESTS_Sauce__Username: '$(asplab-sauce-labs-username)'
+ E2ETESTS_Sauce__AccessKey: '$(asplab-sauce-labs-access-key)'
+ # Set platform/browser configuration.
+ E2ETESTS_Sauce__TestName: 'Blazor Daily Tests - Android/Chrome'
+ E2ETESTS_Sauce__PlatformName: 'Android'
+ E2ETESTS_Sauce__PlatformVersion: '10.0'
+ E2ETESTS_Sauce__BrowserName: 'Chrome'
+ E2ETESTS_Sauce__DeviceName: 'Android GoogleAPI Emulator'
+ E2ETESTS_Sauce__DeviceOrientation: 'portrait'
+ E2ETESTS_Sauce__AppiumVersion: '1.9.1'
+ artifacts:
+ - name: Windows_Logs
+ path: artifacts/log/
+ publishOnError: true
\ No newline at end of file
diff --git a/.azure/pipelines/ci.yml b/.azure/pipelines/ci.yml
index d3d8637c4108..1dabcb870e7d 100644
--- a/.azure/pipelines/ci.yml
+++ b/.azure/pipelines/ci.yml
@@ -525,6 +525,40 @@ stages:
parameters:
inputName: Linux_musl_x64
+ # Build Linux Musl ARM
+ - template: jobs/default-build.yml
+ parameters:
+ jobName: Linux_musl_arm_build
+ jobDisplayName: "Build: Linux Musl ARM"
+ agentOs: Linux
+ useHostedUbuntu: false
+ container: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-cross-arm-alpine-20200827125937-14441ae
+ buildScript: ./build.sh
+ buildArgs:
+ --arch arm
+ --os-name linux-musl
+ --pack
+ --all
+ --no-build-nodejs
+ --no-build-java
+ -p:OnlyPackPlatformSpecificPackages=true
+ -p:AssetManifestFileName=aspnetcore-Linux_musl_arm.xml
+ $(_BuildArgs)
+ $(_PublishArgs)
+ $(_InternalRuntimeDownloadArgs)
+ installNodeJs: false
+ installJdk: false
+ artifacts:
+ - name: Linux_musl_arm_Logs
+ path: artifacts/log/
+ publishOnError: true
+ includeForks: true
+ - name: Linux_musl_arm_Packages
+ path: artifacts/packages/
+ - template: jobs/codesign-xplat.yml
+ parameters:
+ inputName: Linux_musl_arm
+
# Build Linux Musl ARM64
- template: jobs/default-build.yml
parameters:
diff --git a/.editorconfig b/.editorconfig
index b210dcdbf67f..bfb8b47a5063 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -42,3 +42,8 @@ end_of_line = lf
[*.{razor,cshtml}]
charset = utf-8-bom
+
+[*.cs]
+dotnet_diagnostic.CA1304.severity = error
+dotnet_diagnostic.CA1305.severity = error
+dotnet_diagnostic.CA1310.severity = error
diff --git a/.github/ISSUE_TEMPLATE/razor_tooling.md b/.github/ISSUE_TEMPLATE/razor_tooling.md
index 1441431a6695..8b5971cc9e73 100644
--- a/.github/ISSUE_TEMPLATE/razor_tooling.md
+++ b/.github/ISSUE_TEMPLATE/razor_tooling.md
@@ -34,26 +34,13 @@ We will close this issue if:
Please collect the data below before reporting your issue to aid us in diagnosing the root cause.
-#### Activity log
+#### Activity log (only needed if VS crashes)
[Here](https://docs.microsoft.com/en-us/visualstudio/extensibility/how-to-use-the-activity-log?view=vs-2019#to-examine-the-activity-log) are the instructions on how to generate/acquire one. Note that GitHub does not generally allow .xml files to be uploaded with issues.
-#### Razor Language Server Client log
-
-
-Razor Language Server Client Log Output
-
-Paste log output here
-
-
-
-#### HTML Language Server Client log
-
-
-HTML Language Server Client Log Output
-
-Paste log output here
-
-
+#### Language Server logs
+1. Run Visual Studio with the [/Log](https://docs.microsoft.com/en-us/visualstudio/ide/reference/log-devenv-exe?view=vs-2019) command line switch
+2. Reproduce the issue
+3. Provide the logs located at `%Temp%\VisualStudio\LSP`
### Further technical details
- VS version (Help => About Microsoft Visual Studio, i.e. 16.8.0 Preview 1 30313.27...). If in Codespaces there will be two versions (server and client), please provide both.
diff --git a/.github/workflows/runtime-sync.yml b/.github/workflows/runtime-sync.yml
index 03e7e8f9d6ba..0b70c9551c96 100644
--- a/.github/workflows/runtime-sync.yml
+++ b/.github/workflows/runtime-sync.yml
@@ -21,14 +21,14 @@ jobs:
# Test this script using changes in a fork
repository: 'dotnet/aspnetcore'
path: aspnetcore
- ref: release/5.0
+ ref: master
- name: Checkout runtime
uses: actions/checkout@v2.0.0
with:
# Test this script using changes in a fork
repository: 'dotnet/runtime'
path: runtime
- ref: release/5.0
+ ref: master
- name: Copy
shell: cmd
working-directory: .\runtime\src\libraries\Common\src\System\Net\Http\aspnetcore\
@@ -67,6 +67,6 @@ jobs:
title: 'Sync shared code from runtime'
body: 'This PR was automatically generated to sync shared code changes from runtime. Fixes #18943'
labels: area-servers
- base: release/5.0
+ base: master
branch: github-action/sync-runtime
branch-suffix: timestamp
diff --git a/AspNetCore.sln b/AspNetCore.sln
index ceb029889f9e..1796f77d8dab 100644
--- a/AspNetCore.sln
+++ b/AspNetCore.sln
@@ -1503,7 +1503,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.App.Un
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Localization", "Localization", "{3D34C81F-2CB5-459E-87E9-0CC04757A2A0}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GlobalizationWasmApp", "src\Components\test\testassets\GlobalizationWasmApp\GlobalizationWasmApp.csproj", "{04CFE286-6D32-41EF-8887-4B5F8086A365}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GlobalizationWasmApp", "src\Components\test\testassets\GlobalizationWasmApp\GlobalizationWasmApp.csproj", "{04CFE286-6D32-41EF-8887-4B5F8086A365}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Localization.Abstractions", "src\Localization\Abstractions\src\Microsoft.Extensions.Localization.Abstractions.csproj", "{FEF97646-9BC9-4D1B-A939-784D915C18A4}"
EndProject
@@ -1519,6 +1519,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Loggin
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Logging.AzureAppServices.Tests", "src\Logging.AzureAppServices\test\Microsoft.Extensions.Logging.AzureAppServices.Tests.csproj", "{43E3B132-2486-44A3-92C6-39E39724FAFD}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testassets", "testassets", "{7B739F28-21DE-435D-9EA6-579064932350}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RoutingWebSite", "src\Http\Routing\test\testassets\RoutingWebSite\RoutingWebSite.csproj", "{F502ED22-EB37-4EF8-BFA0-3EFB3E2BE20C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RoutingSandbox", "src\Http\Routing\test\testassets\RoutingSandbox\RoutingSandbox.csproj", "{0EBEE047-CBAD-4A69-8095-E3961B863446}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "src\Http\Routing\test\testassets\Benchmarks\Benchmarks.csproj", "{B4F76DF0-1638-42DA-B46A-30DC16AECEAB}"
+EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SiteExtensions", "SiteExtensions", "{DFC4F588-B4B4-484B-AB93-B36721374AD3}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LoggingAggregate", "LoggingAggregate", "{48FF1D87-5066-4294-B802-2D1B478C6EB6}"
@@ -1539,6 +1547,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sdk", "Sdk", "{E83B0BCC-A8E
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HostingStartup", "src\SiteExtensions\Sdk\HostingStartup\HostingStartup.csproj", "{5D6F99C5-D292-4459-B8BD-8E4AD42E1B21}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IgnitorSample", "src\Components\Samples\IgnitorSample\IgnitorSample.csproj", "{CAFD1885-B87B-4A7A-8BE6-86B0C238C2B1}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SignalR.Tests.Utils", "src\SignalR\common\testassets\Tests.Utils\Microsoft.AspNetCore.SignalR.Tests.Utils.csproj", "{C1CDD339-B51B-42BE-99F2-F39A4EC0D404}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testassets", "testassets", "{BB3D6EDD-AE71-4D25-B61B-7EBF7A1BA1D1}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -7199,18 +7213,6 @@ Global
{BAD47859-95DF-4C8F-9AF7-C48B68F478A1}.Release|x64.Build.0 = Release|Any CPU
{BAD47859-95DF-4C8F-9AF7-C48B68F478A1}.Release|x86.ActiveCfg = Release|Any CPU
{BAD47859-95DF-4C8F-9AF7-C48B68F478A1}.Release|x86.Build.0 = Release|Any CPU
- {04CFE286-6D32-41EF-8887-4B5F8086A365}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {04CFE286-6D32-41EF-8887-4B5F8086A365}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {04CFE286-6D32-41EF-8887-4B5F8086A365}.Debug|x64.ActiveCfg = Debug|Any CPU
- {04CFE286-6D32-41EF-8887-4B5F8086A365}.Debug|x64.Build.0 = Debug|Any CPU
- {04CFE286-6D32-41EF-8887-4B5F8086A365}.Debug|x86.ActiveCfg = Debug|Any CPU
- {04CFE286-6D32-41EF-8887-4B5F8086A365}.Debug|x86.Build.0 = Debug|Any CPU
- {04CFE286-6D32-41EF-8887-4B5F8086A365}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {04CFE286-6D32-41EF-8887-4B5F8086A365}.Release|Any CPU.Build.0 = Release|Any CPU
- {04CFE286-6D32-41EF-8887-4B5F8086A365}.Release|x64.ActiveCfg = Release|Any CPU
- {04CFE286-6D32-41EF-8887-4B5F8086A365}.Release|x64.Build.0 = Release|Any CPU
- {04CFE286-6D32-41EF-8887-4B5F8086A365}.Release|x86.ActiveCfg = Release|Any CPU
- {04CFE286-6D32-41EF-8887-4B5F8086A365}.Release|x86.Build.0 = Release|Any CPU
{010A9638-F20E-4FE6-A186-85732BFC9CB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{010A9638-F20E-4FE6-A186-85732BFC9CB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{010A9638-F20E-4FE6-A186-85732BFC9CB0}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -7223,6 +7225,18 @@ Global
{010A9638-F20E-4FE6-A186-85732BFC9CB0}.Release|x64.Build.0 = Release|Any CPU
{010A9638-F20E-4FE6-A186-85732BFC9CB0}.Release|x86.ActiveCfg = Release|Any CPU
{010A9638-F20E-4FE6-A186-85732BFC9CB0}.Release|x86.Build.0 = Release|Any CPU
+ {04CFE286-6D32-41EF-8887-4B5F8086A365}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {04CFE286-6D32-41EF-8887-4B5F8086A365}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {04CFE286-6D32-41EF-8887-4B5F8086A365}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {04CFE286-6D32-41EF-8887-4B5F8086A365}.Debug|x64.Build.0 = Debug|Any CPU
+ {04CFE286-6D32-41EF-8887-4B5F8086A365}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {04CFE286-6D32-41EF-8887-4B5F8086A365}.Debug|x86.Build.0 = Debug|Any CPU
+ {04CFE286-6D32-41EF-8887-4B5F8086A365}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {04CFE286-6D32-41EF-8887-4B5F8086A365}.Release|Any CPU.Build.0 = Release|Any CPU
+ {04CFE286-6D32-41EF-8887-4B5F8086A365}.Release|x64.ActiveCfg = Release|Any CPU
+ {04CFE286-6D32-41EF-8887-4B5F8086A365}.Release|x64.Build.0 = Release|Any CPU
+ {04CFE286-6D32-41EF-8887-4B5F8086A365}.Release|x86.ActiveCfg = Release|Any CPU
+ {04CFE286-6D32-41EF-8887-4B5F8086A365}.Release|x86.Build.0 = Release|Any CPU
{FEF97646-9BC9-4D1B-A939-784D915C18A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FEF97646-9BC9-4D1B-A939-784D915C18A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FEF97646-9BC9-4D1B-A939-784D915C18A4}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -7295,6 +7309,42 @@ Global
{43E3B132-2486-44A3-92C6-39E39724FAFD}.Release|x64.Build.0 = Release|Any CPU
{43E3B132-2486-44A3-92C6-39E39724FAFD}.Release|x86.ActiveCfg = Release|Any CPU
{43E3B132-2486-44A3-92C6-39E39724FAFD}.Release|x86.Build.0 = Release|Any CPU
+ {F502ED22-EB37-4EF8-BFA0-3EFB3E2BE20C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F502ED22-EB37-4EF8-BFA0-3EFB3E2BE20C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F502ED22-EB37-4EF8-BFA0-3EFB3E2BE20C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F502ED22-EB37-4EF8-BFA0-3EFB3E2BE20C}.Debug|x64.Build.0 = Debug|Any CPU
+ {F502ED22-EB37-4EF8-BFA0-3EFB3E2BE20C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F502ED22-EB37-4EF8-BFA0-3EFB3E2BE20C}.Debug|x86.Build.0 = Debug|Any CPU
+ {F502ED22-EB37-4EF8-BFA0-3EFB3E2BE20C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F502ED22-EB37-4EF8-BFA0-3EFB3E2BE20C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F502ED22-EB37-4EF8-BFA0-3EFB3E2BE20C}.Release|x64.ActiveCfg = Release|Any CPU
+ {F502ED22-EB37-4EF8-BFA0-3EFB3E2BE20C}.Release|x64.Build.0 = Release|Any CPU
+ {F502ED22-EB37-4EF8-BFA0-3EFB3E2BE20C}.Release|x86.ActiveCfg = Release|Any CPU
+ {F502ED22-EB37-4EF8-BFA0-3EFB3E2BE20C}.Release|x86.Build.0 = Release|Any CPU
+ {0EBEE047-CBAD-4A69-8095-E3961B863446}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0EBEE047-CBAD-4A69-8095-E3961B863446}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0EBEE047-CBAD-4A69-8095-E3961B863446}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0EBEE047-CBAD-4A69-8095-E3961B863446}.Debug|x64.Build.0 = Debug|Any CPU
+ {0EBEE047-CBAD-4A69-8095-E3961B863446}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0EBEE047-CBAD-4A69-8095-E3961B863446}.Debug|x86.Build.0 = Debug|Any CPU
+ {0EBEE047-CBAD-4A69-8095-E3961B863446}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0EBEE047-CBAD-4A69-8095-E3961B863446}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0EBEE047-CBAD-4A69-8095-E3961B863446}.Release|x64.ActiveCfg = Release|Any CPU
+ {0EBEE047-CBAD-4A69-8095-E3961B863446}.Release|x64.Build.0 = Release|Any CPU
+ {0EBEE047-CBAD-4A69-8095-E3961B863446}.Release|x86.ActiveCfg = Release|Any CPU
+ {0EBEE047-CBAD-4A69-8095-E3961B863446}.Release|x86.Build.0 = Release|Any CPU
+ {B4F76DF0-1638-42DA-B46A-30DC16AECEAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B4F76DF0-1638-42DA-B46A-30DC16AECEAB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B4F76DF0-1638-42DA-B46A-30DC16AECEAB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B4F76DF0-1638-42DA-B46A-30DC16AECEAB}.Debug|x64.Build.0 = Debug|Any CPU
+ {B4F76DF0-1638-42DA-B46A-30DC16AECEAB}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B4F76DF0-1638-42DA-B46A-30DC16AECEAB}.Debug|x86.Build.0 = Debug|Any CPU
+ {B4F76DF0-1638-42DA-B46A-30DC16AECEAB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B4F76DF0-1638-42DA-B46A-30DC16AECEAB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B4F76DF0-1638-42DA-B46A-30DC16AECEAB}.Release|x64.ActiveCfg = Release|Any CPU
+ {B4F76DF0-1638-42DA-B46A-30DC16AECEAB}.Release|x64.Build.0 = Release|Any CPU
+ {B4F76DF0-1638-42DA-B46A-30DC16AECEAB}.Release|x86.ActiveCfg = Release|Any CPU
+ {B4F76DF0-1638-42DA-B46A-30DC16AECEAB}.Release|x86.Build.0 = Release|Any CPU
{563A3FFA-32DA-4ADA-891C-E00897BD919E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{563A3FFA-32DA-4ADA-891C-E00897BD919E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{563A3FFA-32DA-4ADA-891C-E00897BD919E}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -7367,6 +7417,30 @@ Global
{5D6F99C5-D292-4459-B8BD-8E4AD42E1B21}.Release|x64.Build.0 = Release|Any CPU
{5D6F99C5-D292-4459-B8BD-8E4AD42E1B21}.Release|x86.ActiveCfg = Release|Any CPU
{5D6F99C5-D292-4459-B8BD-8E4AD42E1B21}.Release|x86.Build.0 = Release|Any CPU
+ {CAFD1885-B87B-4A7A-8BE6-86B0C238C2B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CAFD1885-B87B-4A7A-8BE6-86B0C238C2B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CAFD1885-B87B-4A7A-8BE6-86B0C238C2B1}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {CAFD1885-B87B-4A7A-8BE6-86B0C238C2B1}.Debug|x64.Build.0 = Debug|Any CPU
+ {CAFD1885-B87B-4A7A-8BE6-86B0C238C2B1}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {CAFD1885-B87B-4A7A-8BE6-86B0C238C2B1}.Debug|x86.Build.0 = Debug|Any CPU
+ {CAFD1885-B87B-4A7A-8BE6-86B0C238C2B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CAFD1885-B87B-4A7A-8BE6-86B0C238C2B1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CAFD1885-B87B-4A7A-8BE6-86B0C238C2B1}.Release|x64.ActiveCfg = Release|Any CPU
+ {CAFD1885-B87B-4A7A-8BE6-86B0C238C2B1}.Release|x64.Build.0 = Release|Any CPU
+ {CAFD1885-B87B-4A7A-8BE6-86B0C238C2B1}.Release|x86.ActiveCfg = Release|Any CPU
+ {CAFD1885-B87B-4A7A-8BE6-86B0C238C2B1}.Release|x86.Build.0 = Release|Any CPU
+ {C1CDD339-B51B-42BE-99F2-F39A4EC0D404}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C1CDD339-B51B-42BE-99F2-F39A4EC0D404}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C1CDD339-B51B-42BE-99F2-F39A4EC0D404}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C1CDD339-B51B-42BE-99F2-F39A4EC0D404}.Debug|x64.Build.0 = Debug|Any CPU
+ {C1CDD339-B51B-42BE-99F2-F39A4EC0D404}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C1CDD339-B51B-42BE-99F2-F39A4EC0D404}.Debug|x86.Build.0 = Debug|Any CPU
+ {C1CDD339-B51B-42BE-99F2-F39A4EC0D404}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C1CDD339-B51B-42BE-99F2-F39A4EC0D404}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C1CDD339-B51B-42BE-99F2-F39A4EC0D404}.Release|x64.ActiveCfg = Release|Any CPU
+ {C1CDD339-B51B-42BE-99F2-F39A4EC0D404}.Release|x64.Build.0 = Release|Any CPU
+ {C1CDD339-B51B-42BE-99F2-F39A4EC0D404}.Release|x86.ActiveCfg = Release|Any CPU
+ {C1CDD339-B51B-42BE-99F2-F39A4EC0D404}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -8117,10 +8191,10 @@ Global
{37329855-01B8-4B03-9765-1A941B06E43C} = {8C15FD04-7F90-43FC-B488-023432FE3CE1}
{D3246226-BC1A-47F1-8E3E-C3380A8F13FB} = {8C15FD04-7F90-43FC-B488-023432FE3CE1}
{B06ADD57-E855-4D8C-85DC-B323509AE540} = {898F7E0B-1671-42CB-9DFB-689AFF212ED3}
- {04CFE286-6D32-41EF-8887-4B5F8086A365} = {6126DCE4-9692-4EE2-B240-C65743572995}
{BAD47859-95DF-4C8F-9AF7-C48B68F478A1} = {A4C26078-B6D8-4FD8-87A6-7C15A3482038}
{010A9638-F20E-4FE6-A186-85732BFC9CB0} = {A4C26078-B6D8-4FD8-87A6-7C15A3482038}
{3D34C81F-2CB5-459E-87E9-0CC04757A2A0} = {017429CC-C5FB-48B4-9C46-034E29EE2F06}
+ {04CFE286-6D32-41EF-8887-4B5F8086A365} = {6126DCE4-9692-4EE2-B240-C65743572995}
{FEF97646-9BC9-4D1B-A939-784D915C18A4} = {3D34C81F-2CB5-459E-87E9-0CC04757A2A0}
{839CE175-E0D9-43B9-9FA8-F32C47E7F56B} = {3D34C81F-2CB5-459E-87E9-0CC04757A2A0}
{50BF2926-7435-4F4B-88A9-3D0EDEB67FC8} = {3D34C81F-2CB5-459E-87E9-0CC04757A2A0}
@@ -8128,6 +8202,10 @@ Global
{3EAB9890-2C01-444C-ACA0-D77B29CDE08B} = {017429CC-C5FB-48B4-9C46-034E29EE2F06}
{3E29454A-C4DC-44B7-AF0A-A782AD2E73BC} = {3EAB9890-2C01-444C-ACA0-D77B29CDE08B}
{43E3B132-2486-44A3-92C6-39E39724FAFD} = {3EAB9890-2C01-444C-ACA0-D77B29CDE08B}
+ {7B739F28-21DE-435D-9EA6-579064932350} = {17DD5861-0635-46D0-84BA-6B163150AA4F}
+ {F502ED22-EB37-4EF8-BFA0-3EFB3E2BE20C} = {7B739F28-21DE-435D-9EA6-579064932350}
+ {0EBEE047-CBAD-4A69-8095-E3961B863446} = {7B739F28-21DE-435D-9EA6-579064932350}
+ {B4F76DF0-1638-42DA-B46A-30DC16AECEAB} = {7B739F28-21DE-435D-9EA6-579064932350}
{DFC4F588-B4B4-484B-AB93-B36721374AD3} = {017429CC-C5FB-48B4-9C46-034E29EE2F06}
{48FF1D87-5066-4294-B802-2D1B478C6EB6} = {DFC4F588-B4B4-484B-AB93-B36721374AD3}
{563A3FFA-32DA-4ADA-891C-E00897BD919E} = {48FF1D87-5066-4294-B802-2D1B478C6EB6}
@@ -8138,6 +8216,9 @@ Global
{545751D5-71FC-4889-A3A0-BBD731DBA18A} = {56B45580-B089-424E-A847-A6115D591950}
{E83B0BCC-A8E0-4FBD-BE51-9A533C9CB972} = {DFC4F588-B4B4-484B-AB93-B36721374AD3}
{5D6F99C5-D292-4459-B8BD-8E4AD42E1B21} = {E83B0BCC-A8E0-4FBD-BE51-9A533C9CB972}
+ {CAFD1885-B87B-4A7A-8BE6-86B0C238C2B1} = {5FE1FBC1-8CE3-4355-9866-44FE1307C5F1}
+ {C1CDD339-B51B-42BE-99F2-F39A4EC0D404} = {BB3D6EDD-AE71-4D25-B61B-7EBF7A1BA1D1}
+ {BB3D6EDD-AE71-4D25-B61B-7EBF7A1BA1D1} = {1A304CA0-7795-4684-88E5-E66402966927}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3E8720B3-DBDD-498C-B383-2CC32A054E8F}
diff --git a/Directory.Build.props b/Directory.Build.props
index 258a01d38823..4abbbfb80dc7 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -87,12 +87,6 @@
$(MSBuildProjectDirectory)true
-
-
- net5.0net461
@@ -153,6 +147,7 @@
win-arm64;
osx-x64;
linux-musl-x64;
+ linux-musl-arm;
linux-musl-arm64;
linux-x64;
linux-arm;
diff --git a/NuGet.config b/NuGet.config
index fdffb168b5f2..89fa2053af93 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -10,6 +10,8 @@
+
+
diff --git a/dockerbuild.sh b/dockerbuild.sh
index ff24d88a9a4a..13366cc6faf9 100755
--- a/dockerbuild.sh
+++ b/dockerbuild.sh
@@ -136,6 +136,7 @@ docker run \
-e BUILD_BUILDID \
-e SYSTEM_TEAMPROJECT \
-e BUILD_BUILDNUMBER \
+ -e BUILD_REPOSITORY_NAME \
-e BUILD_REPOSITORY_URI \
-e BUILD_REPOSITORY_NAME \
-e BUILD_SOURCEVERSION \
diff --git a/docs/BuildFromSource.md b/docs/BuildFromSource.md
index 95858315fc09..886a012b3a79 100644
--- a/docs/BuildFromSource.md
+++ b/docs/BuildFromSource.md
@@ -1,154 +1,197 @@
# Build ASP.NET Core from Source
-Building ASP.NET Core from source allows you to tweak and customize ASP.NET Core, and to contribute your improvements back to the project.
+This document outlines how to build the source in the aspnetcore repo locally for development purposes.
-See for known issues and to track ongoing work.
+For more info on issues related to build infrastructure and ongoing work, see .
-## Clone the source code
+## Step 0: Getting started
-ASP.NET Core uses git submodules to include the source from a few other projects.
+This tutorial assumes that you are familiar with:
-For a new copy of the project, run:
+- Git
+- Command line fundamentals in your operating system of choice
+
+## Step 1: Clone the source code
+
+ASP.NET Core uses git submodules to include the source from a few other projects. In order to pull the sources of the these submodules when cloning the repo, be sure to pass the `--recursive` flag to the `git clone` command.
```ps1
git clone --recursive https://github.com/dotnet/aspnetcore
```
-To update an existing copy, run:
+If you've already cloned the aspnetcore repo without fetching subdmoule sources, you can fetch them after cloning by running the following command.
```ps1
git submodule update --init --recursive
```
-## Install pre-requisites
+> :bulb: Some ISPs have been know to use web filtering software that has caused issues with git repository cloning, if you experience issues cloning this repo please review .
-### Windows
+## Step 2: Install pre-requisites
-Building ASP.NET Core on Windows requires:
+Developing in the aspnetcore repo requires some additional tools to build the source code and run integration tests.
-* Windows 10, version 1803 or newer
-* At least 10 GB of disk space and a good internet connection (our build scripts download a lot of tools and dependencies)
-* Visual Studio 2019.
- * To install the exact required components, run [eng/scripts/InstallVisualStudio.ps1](/eng/scripts/InstallVisualStudio.ps1).
+### On Windows
- ```ps1
- PS> ./eng/scripts/InstallVisualStudio.ps1
- ```
+Building ASP.NET Core on Windows (10, version 1803 or newer) requires that you have the following tooling installed.
- However, any Visual Studio 2019 instance that meets the requirements should be fine. See [global.json](/global.json)
- and [eng/scripts/vs.json](/eng/scripts/vs.json) for those requirements. By default, the script will install Visual Studio Enterprise Edition, however you can use a different edition by passing the `-Edition` flag.
-* Git.
-* NodeJS. LTS version of 10.14.2 or newer .
-* Install yarn globally (`npm install -g yarn`)
-* Java Development Kit 11 or newer. Either:
- * OpenJDK
- * Oracle's JDK
- * To install a version of the JDK that will only be used by this repo, run [eng/scripts/InstallJdk.ps1](/eng/scripts/InstallJdk.ps1)
+> :bulb: Be sure you have least 10 GB of disk space and a good Internet connection. The build scripts will download several tools and dependencies onto your machine.
+
+#### [Visual Studio 2019](https://visualstudio.com)
- ```ps1
- PS> ./eng/scripts/InstallJdk.ps1
- ```
+Visual Studio 2019 (16.8) is required to build the repo locally. If you don't have visual studio installed you can run [eng/scripts/InstallVisualStudio.ps1](/eng/scripts/InstallVisualStudio.ps1) to install the exact required dependencies.
+
+> :bulb: By default, the script will install Visual Studio Enterprise Edition, however you can use a different edition by passing the `-Edition` flag.
+> :bulb: To install Visual Studio from the preview channel, you can use the `-Channel` flag to set the channel (`-Channel Preview`).
+> :bulb: Even if you have installed Visual Studio, we still recommend using this script to install again to avoid errors due to missing components.
+
+```ps1
+PS> ./eng/scripts/InstallVisualStudio.ps1 [-Edition {Enterprise|Community|Professional}] [-Channel {Release|Preview}]
+```
- However, the build should find any JDK 11 or newer installation on the machine.
- * Set the `JAVA_HOME` environment variable with the path of the java installation directory if your installation did not do that automatically. (Gradle needs this for execution.)
- * This will be `RepoRoot/.tools/jdk/win-x64/` if you used the `InstallJdk.ps1` script
- * This will be `C:/Program FIles/Java/jdk/` if you installed the JDK globally
-* Chrome - Selenium-based tests require a version of Chrome to be installed. Download and install it from
+> :bulb: To execute the setup script or other PowerShell scripts in the repo, you may need to update the execution policy on your machine.
+> You can do so by running the `Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser` command
+> in PowerShell. For more information on execution policies, you can read the [execution policy docs](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy).
-### macOS/Linux
+The [global.json](/global.json) file specifies the minimum requirements needed to build using `msbuild`. The [eng/scripts/vs.json](/eng/scripts/vs.json) file provides a description of the components needed to build within VS. If you plan on developing in Visual Studio, you will need to have these components installed.
-Building ASP.NET Core on macOS or Linux requires:
+> :bulb: The `IntallVisualStudio.ps1` script mentioned above reads from the `vs.json` file to determine what components to install.
-* If using macOS, you need macOS Sierra or newer.
-* If using Linux, you need a machine with all .NET Core Linux prerequisites:
-* At least 10 GB of disk space and a good internet connection (our build scripts download a lot of tools and dependencies)
-* curl or Wget
-* Git
-* NodeJS. LTS version of 10.14.2 or newer
-* Java Development Kit 11 or newer. Either:
+#### [Git](https://git-scm.org)
+
+If you're reading this, you probably already have Git installed to support cloning the repo as outlined in Step 1.
+
+#### [NodeJS](https://nodejs.org)
+
+Building the repo requires version 10.14.2 or newer of Node. You can find installation executables for Node at https://nodejs.org.
+
+#### [Yarn](https://yarnpkg.com/)
+
+NodeJS installes the Node package manager (npm) by default. This repo depends on yarn, an alternate package manager for the Node ecosystem. You can install Yarn from the command line using the following command.
+
+```ps1
+npm install -g yarn
+```
+
+#### Java Development Kit in Windows*
+
+This repo contains some Java source code that depends on an install of the JDK v11 or newer. The JDK can be installed from either:
* OpenJDK
* Oracle's JDK
-**NOTE** some ISPs have been know to use web filtering software that has caused issues with git repository cloning, if you experience issues cloning this repo please review
+Alternatively, you can run [eng/scripts/InstallJdk.ps1](/eng/scripts/InstallJdk.ps1) to install a version of the JDK that will only be used in this repo.
-## Building in Visual Studio
+```ps1
+PS> ./eng/scripts/InstallJdk.ps1
+```
-Before opening our .sln/.slnf files in Visual Studio or VS Code, you need to perform the following actions.
+The build should find any JDK 11 or newer installation on the machine as long as the `JAVA_HOME` environment variable is set. Typically, your installation will do this automatically. However, if it is not set you can set the environment variable manually:
+ * Set `JAVA_HOME` to `RepoRoot/.tools/jdk/win-x64/` if you used the `InstallJdk.ps1` script.
+ * Set `JAVA_HOME` to `C:/Program Files/Java/jdk/` if you installed the JDK globally.
-1. Executing the following on command-line:
+#### Chrome
- ```ps1
- .\restore.cmd
- ```
+This repo contains a Selenium-based tests require a version of Chrome to be installed. Download and install it from .
- This will download the required tools and build the entire repository once. At that point, you should be able
- to open the .sln file or one of the project specific .slnf files to work on the projects you care about.
+#### Wix (Optional)
- > :bulb: Pro tip: you will also want to run this command after pulling large sets of changes. On the master
- > branch, we regularly update the versions of .NET Core SDK required to build the repo.
- > You will need to restart Visual Studio every time we update the .NET Core SDK.
- > To allow executing the setup script, you may need to update the execution policy on your machine.
- You can do so by running the `Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser` command
- in PowerShell. For more information on execution policies, you can read the [execution policy docs](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy).
+If you plan on working with the Windows installers defined in [src/Installers/Windows](../src/Installers/Windows), you will need to install the Wix toolkit from https://wixtoolset.org/releases/.
-2. Use the `startvs.cmd` script to open Visual Studio .sln/.slnf files. This script first sets the required
-environment variables.
+### On macOS/Linux
-### Solution files
+You can also build ASP.NET Core on macOS or Linux. macOS Sierra or newer is required if you're building on macOS. If you're building on Linux, your machine will need to meet the [.NET Core Linux preequisities](https://docs.microsoft.com/en-us/dotnet/core/linux-prerequisites).
-We have a single .sln file for all of ASP.NET Core, but most people don't work with it directly because Visual Studio
-doesn't currently handle projects of this scale very well.
+> :bulb: Be sure you have least 10 GB of disk space and a good Internet connection. The build scripts will download several tools and dependencies onto your machine.
-Instead, we have many Solution Filter (.slnf) files which include a sub-set of projects. See the Visual Studio
-documentation [here](https://docs.microsoft.com/en-us/visualstudio/ide/filtered-solutions?view=vs-2019) for more
-information about Solution Filters.
+#### curl/wget
-These principles guide how we create and manage .slnf files:
+`curl` and `wget` are command line tools that can be used to download files from an HTTP server. Either utility will need to be installed in order to complete the setup. Typically, these will be included on your machine by default.
-1. Solution files are not used by CI or command line build scripts. They are meant for use by developers only.
-2. Solution files group together projects which are frequently edited at the same time.
-3. Can't find a solution that has the projects you care about? Feel free to make a PR to add a new .slnf file.
+If netier utility is installed, you can install curl (https://curl.haxx.se) or wget (https://www.gnu.org/software/wget).
-### Common error: CS0006
+##### Git
-Opening solution filters and building may produce an error code CS0006 with a message such
+If you've made it this far, you've already got `Git` installed. Sit back, relax, and move on to the next requirement.
-> Error CS0006 Metadata file 'C:\src\aspnet\AspNetCore\artifacts\bin\Microsoft.AspNetCore.Metadata\Debug\netstandard2.0\Microsoft.AspNetCore.Metadata.dll' could not be found
+#### [NodeJS](https://nodejs.org)
-The cause of this problem is that the solution filter you are using does not include the project that produces this .dll. This most often occurs after we have added new projects to the repo, but failed to update our .sln/slnf files to include the new project. In some cases, it is sometimes the intended behavior of the .slnf which has been crafted to only include a subset of projects.
+Building the repo requires version 10.14.2 or newer of Node. You can find installation executables for Node at https://nodejs.org.
-#### You can fix this in one of three ways
+#### [Yarn](https://yarnpkg.com/)
-1. Build the project on command line. In most cases, running `build.cmd` on command line solves this problem.
-2. If the project is missing from the .sln file entirely, you can use `dotnet sln add` to add it, or else right click on the solution/folder in Visual Studio and choose Add->Existing Project, and adding it.
-3. If it is present in the .sln, but not the .slnf, you can update the solution filter to include the missing project. You can either do this one by right-clicking on project in Visual Studio and choosing to load it's direct dependencies, and then saving. Alternatively, you can hand edit the .slnf file - it's a fairly simple json format.
+NodeJS installs the Node package manager (npm) by default. This repo depends on yarn, an alternate package manager for the Node ecosystem. You can install Yarn from the command line using the following command.
-### Common error: Unable to locate the .NET Core SDK
+```bash
+$ npm install -g yarn
+```
-Executing `.\restore.cmd` or `.\build.cmd` may produce these errors:
+#### Java Development Kit
-> error : Unable to locate the .NET Core SDK. Check that it is installed and that the version specified in global.json (if any) matches the installed version.
-> error MSB4236: The SDK 'Microsoft.NET.Sdk' specified could not be found.
+This repo contains some Java source code that depends on an install of the JDK v11 or newer. The JDK can be installed from either:
+ * OpenJDK
+ * Oracle's JDK
-In most cases, this is because the option _Use previews of the .NET Core SDK_ in VS2019 is not checked. Start Visual Studio, go to _Tools > Options_ and check _Use previews of the .NET Core SDK_ under _Environment > Preview Features_.
+Similar to [the instructions above for Windows](#java-development-kit-in-windows), be sure that the the `JAVA_HOME` environment variable is set to the location of your Java installation.
-### Common error: HTTP Error 500.33 - ANCM Request Handler Load Failure
+## Step 3: Build the repo
-The [ASP.NET Core Module](https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/aspnet-core-module) (ANCM) for IIS is not supported when running projects in this repository.
+Before opening our .sln/.slnf files in Visual Studio or VS Code, you will need to build the repo locally.
-After using `startvs.cmd` to open a solution in Visual Studio, the Kestrel web host option must be used (name of the project) and not IIS Express.
+### In Visual Studio
-Example of running the `MvcSandbox` project:
+To set up your project for development on Visual Studio, you'll need to execute the following command.
-`.\startvs.cmd .\src\Mvc\Mvc.sln`
+```ps1
+PS1> .\restore.cmd
+```
-![Web host options in Visual Studio](./vs-iis-express-aspnet-core-mvc-sandbox.jpg)
+> :bulb: If you happen to be working on macOS or Linux, you can use the `restore.sh` command.
+
+This will download the required tools and restore all projects inside the repository. At that point, you should be able
+to open the .sln file or one of the project specific .slnf files to work on the projects you care about.
+
+ > :bulb: Pro tip: you will also want to run this command after pulling large sets of changes. On the master
+ > branch, we regularly update the versions of .NET Core SDK required to build the repo.
+ > You will need to restart Visual Studio every time we update the .NET Core SDK.
+
+Typically, you want to focus on a single project within the monorepo. For example,
+if you want to work on Blazor WebAssembly, you'll need to launch the solution file for that project by changing into the `src/Components`
+directory and executing `startvs.cmd` in that directory like so:
+
+```ps1
+PS1> cd src\Components
+PS1> .\startvs.cmd
+```
+
+After opening the solution in Visual Studio, you can build/rebuild using the controls in Visual Studio.
+
+> :exclamation: VS for Mac does not currently support opening .slnf files so you must use VS Code when developing on macOS.
+
+#### A brief interlude on solution files
+
+We have a single .sln file for all of ASP.NET Core, but most people don't work with it directly because Visual Studio
+doesn't currently handle projects of this scale very well.
+
+Instead, we have many Solution Filter (.slnf) files which include a sub-set of projects. See the Visual Studio
+documentation [here](https://docs.microsoft.com/en-us/visualstudio/ide/filtered-solutions?view=vs-2019) for more
+information about Solution Filters.
+
+These principles guide how we create and manage .slnf files:
+
+1. Solution files are not used by CI or command line build scripts. They are meant for use by developers only.
+2. Solution files group together projects which are frequently edited at the same time.
+3. Can't find a solution that has the projects you care about? Feel free to make a PR to add a new .slnf file.
-## Building with Visual Studio Code
+### In Visual Studio Code
+
+Before opening the project in Visual Studio Code, you will need to make sure that you have built the project.
+You can find more info on this in the "Building on command-line" section below.
Using Visual Studio Code with this repo requires setting environment variables on command line first.
Use these command to launch VS Code with the right settings.
+> :bulb: Note that you'll need to launch Visual Studio Code from the command line in order to ensure that it picks up the environment variables. To learn more about the Visual Studio Code CLI, you can check out [the docs page](https://code.visualstudio.com/docs/editor/command-line).
+
On Windows (requires PowerShell):
```ps1
@@ -165,14 +208,14 @@ source activate.sh
code .
```
-Note that if you are using the "Remote-WSL" extension in VSCode, the environment is not supplied
-to the process in WSL. You can workaround this by explicitly setting the environment variables
-in `~/.vscode-server/server-env-setup`.
-See https://code.visualstudio.com/docs/remote/wsl#_advanced-environment-setup-script for details.
+> :bulb: Note that if you are using the "Remote-WSL" extension in VSCode, the environment is not supplied
+> to the process in WSL. You can workaround this by explicitly setting the environment variables
+> in `~/.vscode-server/server-env-setup`.
+> See https://code.visualstudio.com/docs/remote/wsl#_advanced-environment-setup-script for details.
## Building on command-line
-You can also build the entire project on command line with the `build.cmd`/`.sh` scripts.
+When developing in VS Code, you'll need to use the `build.cmd` or `build.sh` scripts in order to build the project. You can learn more about the command line options available, check out [the section below](using-dotnet-on-command-line-in-this-repo).
On Windows:
@@ -188,10 +231,16 @@ On macOS/Linux:
By default, all of the C# projects are built. Some C# projects require NodeJS to be installed to compile JavaScript assets which are then checked in as source. If NodeJS is detected on the path, the NodeJS projects will be compiled as part of building C# projects. If NodeJS is not detected on the path, the JavaScript assets checked in previously will be used instead. To disable building NodeJS projects, specify `-noBuildNodeJS` or `--no-build-nodejs` on the command line.
-### Using `dotnet` on command line in this repo
+## Step 4: Make your code changes
+
+At this point, you will have all the dependencies installed and a code editor to up and running to make changes in. Once you've made changes, you will need to rebuild the project locally to pick up your changes. You'll also need to run tests locally to verify that your changes worked.
+
+The section below provides some helpful guides for using the `dotnet` CLI in the ASP.NET Core repo.
+
+## Using `dotnet` on command line in this repo
Because we are using pre-release versions of .NET Core, you have to set a handful of environment variables
-to make the .NET Core command line tool work well. You can set these environment variables like this
+to make the .NET Core command line tool work well. You can set these environment variables like this:
On Windows (requires PowerShell):
@@ -207,7 +256,9 @@ On macOS/Linux:
source ./activate.sh
```
-## Running tests on command-line
+> :bulb: Be sure to set the environment variables using the "activate" script above before executing the `dotnet` command inside the repo.
+
+### Running tests on command-line
Tests are not run by default. Use the `-test` option to run tests in addition to building.
@@ -223,13 +274,15 @@ On macOS/Linux:
./build.sh --test
```
-## Building a subset of the code
+> :bulb: If you're working on changes for a particular subset of the project, you might not want to execute the entire test suite. Instead, only run the tests within the subdirectory where changes were made. This can be accomplished by passing the `projects` property like so: `.\build.cmd -test -projects .\src\Framework\test\Microsoft.AspNetCore.App.UnitTests.csproj`.
+
+### Building a subset of the code
This repository is large. Look for `build.cmd`/`.sh` scripts in subfolders. These scripts can be used to invoke build and test on a smaller set of projects.
Furthermore, you can use flags on `build.cmd`/`.sh` to build subsets based on language type, like C++, TypeScript, or C#. Run `build.sh --help` or `build.cmd -help` for details.
-## Build properties
+### Build properties
Additional properties can be added as an argument in the form `/property:$name=$value`, or `/p:$name=$value` for short. For example:
@@ -245,7 +298,7 @@ Configuration | `Debug` or `Release`. Default = `Debug`.
TargetArchitecture | The CPU architecture to build for (x64, x86, arm, arm64).
TargetOsName | The base runtime identifier to build for (win, linux, osx, linux-musl).
-## Use the result of your build
+### Use the result of your build
After building ASP.NET Core from source, you will need to install and use your local version of ASP.NET Core.
See ["Artifacts"](./Artifacts.md) for more explanation of the different folders produced by a build.
@@ -289,4 +342,53 @@ These are available in the [Visual Studio Preview](https://www.visualstudio.com/
## Resx files
-If you need to make changes to a .resx file, run `dotnet msbuild /t:Resx `. This will update the generated C#.
+If you need to make changes to a .resx file, run `dotnet msbuild t:/Resgen `. This will update the generated C#.
+
+## Troubleshooting
+
+This section contains a troubleshooting guide for common issues you might run into while building the repo.
+
+### Common error: CS0006
+
+Opening solution filters and building may produce an error code CS0006 with a message such
+
+> Error CS0006 Metadata file 'C:\src\aspnet\AspNetCore\artifacts\bin\Microsoft.AspNetCore.Metadata\Debug\netstandard2.0\Microsoft.AspNetCore.Metadata.dll' could not be found
+
+The cause of this problem is that the solution filter you are using does not include the project that produces this .dll. This most often occurs after we have added new projects to the repo, but failed to update our .sln/slnf files to include the new project. In some cases, it is sometimes the intended behavior of the .slnf which has been crafted to only include a subset of projects.
+
+#### You can fix this in one of three ways
+
+1. Build the project on command line. In most cases, running `build.cmd` on command line solves this problem.
+2. If the project is missing from the .sln file entirely, you can use `dotnet sln add` to add it, or else right click on the solution/folder in Visual Studio and choose Add->Existing Project, and adding it.
+3. If it is present in the .sln, but not the .slnf, you can update the solution filter to include the missing project. You can either do this one by right-clicking on project in Visual Studio and choosing to load it's direct dependencies, and then saving. Alternatively, you can hand edit the .slnf file - it's a fairly simple json format.
+
+### Common error: Unable to locate the .NET Core SDK
+
+Executing `.\restore.cmd` or `.\build.cmd` may produce these errors:
+
+> error : Unable to locate the .NET Core SDK. Check that it is installed and that the version specified in global.json (if any) matches the installed version.
+> error MSB4236: The SDK 'Microsoft.NET.Sdk' specified could not be found.
+
+In most cases, this is because the option _Use previews of the .NET Core SDK_ in VS2019 is not checked. Start Visual Studio, go to _Tools > Options_ and check _Use previews of the .NET Core SDK_ under _Environment > Preview Features_.
+
+### Common error: HTTP Error 500.33 - ANCM Request Handler Load Failure
+
+The [ASP.NET Core Module](https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/aspnet-core-module) (ANCM) for IIS is not supported when running projects in this repository.
+
+After using `startvs.cmd` to open a solution in Visual Studio, the Kestrel web host option must be used (name of the project) and not IIS Express.
+
+Example of running the `MvcSandbox` project:
+
+`.\startvs.cmd .\src\Mvc\Mvc.sln`
+
+![Web host options in Visual Studio](./vs-iis-express-aspnet-core-mvc-sandbox.jpg)
+
+### Common error: error : Unable to load the service index for …
+
+When attempting to restore servicing tags e.g. `v3.1.7`, the NuGet.config file may contain internal feeds that are not accessible. This will result in errors such as
+
+``` text
+...\aspnetcore\.dotnet\sdk\3.1.103\NuGet.targets(123,5): error : Unable to load the service index for source https://pkgs.dev.azure.com/dnceng/_packaging/darc-int-dotnet-extensions-784b0ffa/nuget/v3/index.json. [...\Temp\1gsd3rdo.srb\restore.csproj] [...\.nuget\packages\microsoft.dotnet.arcade.sdk\1.0.0-beta.20213.4\tools\Tools.proj]
+```
+
+The `darc-int-...` feeds in NuGet.config are used only when building internally and are not needed after the tags are created. Delete all such entries in the file and retry.
diff --git a/docs/PackageArchives.md b/docs/PackageArchives.md
deleted file mode 100644
index 420e0906dfba..000000000000
--- a/docs/PackageArchives.md
+++ /dev/null
@@ -1,62 +0,0 @@
-Package Archives
-================
-
-This repo builds multiple package archives which contain a NuGet fallback folder (also known as the fallback or offline package cache). The fallback folder is a set of NuGet packages that is bundled in the .NET Core SDK installers and available in Azure Web App service.
-
-Package archives are available in four varieties.
-
-* **LZMA** - `nuGetPackagesArchive-$(Version).lzma` - The LZMA is a compressed file format, similar to a .zip. On first use or on install, the .NET Core CLI will expand this LZMA file, extracting the packages inside to %DOTNET_INSTALL_DIR%/sdk/NuGetFallbackFolder. This contains all NuGet packages and their complete contents.
-* **ci-server** - `nuGetPackagesArchive-ci-server-$(Version).zip` - this archive is optimized for CI server environments. It contains the same contents as the LZMA, but trimmed of xml docs (these are only required for IDEs) and .nupkg files (not required for NuGet as for the 2.0 SDK).
-* **ci-server-patch** - `nuGetPackagesArchive-ci-server-$(Version).patch.zip` - this archive is the same as the ci-server archive, but each release is incremental - i.e. it does not bundle files that were present in a previous ci-server archive release. This can be used by first starting with a baseline `nuGetPackagesArchive-ci-server-$(Version).zip` and then applying the `.patch.zip` version for subsequent updates.
-* **ci-server-compat-patch** - `nuGetPackagesArchive-ci-server-compat-$(Version).patch.zip` - similar to the ci-server-patch archive, but this includes .nupkg files to satisfy CI environments that may have older NuGet clients.
-
-These archives are built using the projects in [src/PackageArchive/Archive.\*/](/src/PackageArchive/).
-
-## Using a fallback folder
-
-NuGet restore takes a list of fallback folders in the MSBuild property `RestoreAdditionalProjectFallbackFolders`. Unlike a folder restore source, restore will not copy the packages from a fallback folder into the global NuGet cache.
-
-By default, the .NET Core SDK adds `$(DotNetInstallRoot)/sdk/NuGetFallbackFolder/` to this list. The .NET Core CLI expands its bundled `nuGetPackagesArchive.lzma` file into this location on first use or when the installers run. (See [Microsoft.NET.NuGetOfflineCache.targets](https://github.com/dotnet/sdk/blob/v2.1.300/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.NuGetOfflineCache.targets)).
-
-## Scenarios
-
-The following scenarios are used to determine which packages go into the fallback package cache.
-These requirements are formalized as project files in [src/PackageArchive/Scenario.\*/](/src/PackageArchive/).
-
- - A user should be able to restore the following templates and only use packages from the offline cache:
- - `dotnet new console`
- - `dotnet new library`
- - `dotnet new web`
- - `dotnet new razor`
- - `dotnet new mvc`
-
-The following packages are NOT included in the offline cache.
- - Packages required for standalone publishing, aka projects that set a Runtime Identifier during restore
- - Packages required for F# and VB templates
- - Packages required for Visual Studio code generation in ASP.NET Core projects
- - Packages required to restore .NET Framework projects
- - Packages required to restore test projects, such as xunit, MSTest, NUnit
-
-The result of this typically means including the transitive graph of the following packages:
-
- - Packages that match bundled runtimes
- - Microsoft.NETCore.App
- - Microsoft.AspNetCore.App
- - Packages that Microsoft.NET.Sdk adds implicitly
- - Microsoft.NETCore.App
- - NETStandard.Library
-
-### Example
-
-Given the following parameters:
- - LatestNETCoreAppTFM = netcoreapp2.1
- - DefaultRuntimeVersion = 2.1
- - BundledRuntimeVersion = 2.1.8
- - BundledAspNetRuntimeVersion = 2.1.7
- - LatestNETStandardLibraryTFM = netstandard2.0
- - BundledNETStandardLibraryVersion = 2.0.1
-
-The LZMA should contain
- - Microsoft.NETCore.App/2.1.0 + netcoreapp2.1 dependencies (Microsoft.NET.Sdk will implicitly reference "2.1", which NuGet to 2.1.0)
- - Microsoft.NETCore.App/2.1.8 + netcoreapp2.1 dependencies (Matches the runtime in shared/Microsoft.NETCore.App/2.1.8/)
- - NETStandard.Library/2.0.1 + netstandard2.0 dependencies (Microsoft.NET.Sdk will implicitly reference "2.0.1")
diff --git a/docs/README.md b/docs/README.md
index 230b8d7f5173..67400982b4dd 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -4,8 +4,23 @@ Contributor documentation
The primary audience for documentation in this folder is contributors to ASP.NET Core.
If you are looking for documentation on how to *use* ASP.NET Core, go to .
-# ASP.NET Core developer workflow
+> :bulb: If you're a new contributor looking to set up the repo locally, the [build from source documentation](BuildFromSource.md) is the best place to start.
-- [Building from source](BuildFromSource.md)
-- [Troubleshooting build errors](BuildErrors.md)
-- [Artifacts structure](Artifacts.md)
+The table below outlines the different docs in this folder and what they are helpful for.
+
+| Documentation | What is it about? | Who is it for? |
+|--------------------------------------------------------------------------|-------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|
+| [API review process](APIReviewProcess.md) | Outlines the process for reviewing API changes in ASP.NET Core | Anyone looking to understand the process for making API changes to ASP.NET Core |
+| [Artifacts structure](Artifacts.md) | Outlines the artifacts produced by the build | Anyone looking to understand artifiacts produced from an Azure DevOps build |
+| [Troubleshooting build errors](BuildErrors.md) | Common errors that occur when building the repo and how to resolve them | Anyone running into an issue with the build |
+| [Building from source](BuildFromSource.md) | Setup instructions for the ASP.NET Core repo | First-time contributors |
+| [Working with EventSources and EventCounters](EventSourceAndCounters.md) | Guidance on adding event tracing to a library | Anyone needing to add event tracing for diagnostics purposes |
+| [Tests on Helix](Helix.md) | An overview of the Helix test environment | Anyone debugging tests in Helix or looking to understand the output from Helix builds |
+| [Issue management](IssueManagementPolicies.md) | Overview of policies in place to manage issues| Community members and collaborators looking to understand how we handle closed issue, issues that need author feedback, etc | |
+| [Preparing a patch update](PreparingPatchUpdates.md) | Documentation on how to setup for a patch release of ASP.NET Core | Anyone looking to publish servicing updates |
+| [Project properties](ProjectProperties.md) | Overview of configurable MSBuild properties on the repo | Anyone looking to modify how a project is packaged |
+| [How references are resolved](ReferenceResolution.md) | Overview of dependency reference setup in the repo | Anyone looking to understand how package references are configured in the repo |
+| [Servicing changes](Servicing.md) | Documentation on how to submit servicing PRs to previous releases | Anyone to submit patches or backports to prior releases, contains the "Shiproom Template" |
+| [Shared framework](SharedFramework.md) | Overview of the ASP.NET Core Shared framework | Anyone looking to understand the policies in place for managing the code of the shared framework |
+| Submodules | Documentation on working with submodules in Git | Anyone working with submodules in the repo |
+| [Triage process](TriageProcess.md)| Overview of the issue triage process used in the repo | Anyone looking to understand the triage process on the repo |
diff --git a/docs/TriageProcess.md b/docs/TriageProcess.md
index 0d9577e45831..61955f123cdc 100644
--- a/docs/TriageProcess.md
+++ b/docs/TriageProcess.md
@@ -53,7 +53,7 @@ We may not investigate issues which haven't received many votes/comments and cho
For some feature requests and bug reports, depending on the user involvement, we may choose to move these to the backlog at this point. What this means, is that they will not be looked at again up until the next major release planning.
## Release Planning
-Once we approach to the end of the release cylce (.NET Core 3, .NET 5) we will look through the accumulated issues in the `Backlog` milestone. This is a long process as the amount of issues accumulated in this milestone is quite large.
+Once we approach to the end of the release cycle (.NET Core 3, .NET 5) we will look through the accumulated issues in the `Backlog` milestone. This is a long process as the amount of issues accumulated in this milestone is quite large.
We will try to prioritize issues with most community requests / upvotes assuming these are aligned with our goals.
Issues, which we will think are candidates for the upcoming release, will be moved to the `Next Sprint Planning` milestone.
diff --git a/docs/area-owners.md b/docs/area-owners.md
index e4d6e72071e0..de68f8183151 100644
--- a/docs/area-owners.md
+++ b/docs/area-owners.md
@@ -2,22 +2,21 @@ The below table lists all the `area-`labels used in the `aspnetcore` repository
| Area label | Owner | Description|
|--- | ---| --- |
-| area-azure | anurse | |
+| area-azure | BrennanConroy | |
| area-blazor | mkArtakMSFT | Blazor server and Blazor WASM related |
-| area-commandlinetools | anurse, mkArtakMSFT | dev certs, dotnet watch, |
-| area-dataprotection | anurse | |
+| area-commandlinetools | mkArtakMSFT | dev certs, dotnet watch, |
+| area-dataprotection | Pilchie | |
| area-grpc | shirhatti | |
-| area-healthchecks | rynowak | |
-| area-hosting | anurse | |
-| area-httpclientfactory | anurse | |
+| area-healthchecks | mkArtakMSFT | |
+| area-hosting | BrennanConroy | |
| area-identity | blowdart | |
| area-infrastructure | dougbu | |
-| area-installers | anurse | |
-| area-middleware | anurse | |
+| area-installers | dougbu | |
+| area-middleware | BrennanConroy | |
| area-mvc | mkArtakMSFT | |
-| area-perf | anurse | |
-| area-platform | anurse | |
+| area-perf | sebastienros | |
+| area-platform | JunTaoLuo | |
| area-security | blowdart | |
-| area-servers | anurse | |
-| area-signalr | anurse | |
-| area-websockets | anurse | |
+| area-servers | BrennanConroy | |
+| area-signalr | BrennanConroy | |
+| area-websockets | BrennanConroy | |
diff --git a/eng/AfterSolutionBuild.targets b/eng/AfterSolutionBuild.targets
index 4a3cb4ba2adf..5c2989479709 100644
--- a/eng/AfterSolutionBuild.targets
+++ b/eng/AfterSolutionBuild.targets
@@ -15,7 +15,7 @@
+ SharedFrameworkTargetFramework="$(DefaultNetCoreTargetFramework)" />
diff --git a/eng/Baseline.Designer.props b/eng/Baseline.Designer.props
index d3894b52f088..d1991880ab97 100644
--- a/eng/Baseline.Designer.props
+++ b/eng/Baseline.Designer.props
@@ -2,7 +2,7 @@
$(MSBuildAllProjects);$(MSBuildThisFileFullPath)
- 3.1.7
+ 3.1.8
@@ -14,7 +14,7 @@
- 3.1.7
+ 3.1.8
@@ -25,83 +25,83 @@
- 3.1.7
+ 3.1.8
-
-
-
+
+
+
-
+
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
-
-
+
+
- 3.1.7
+ 3.1.8
-
-
+
+
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
-
+
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
@@ -109,97 +109,97 @@
- 3.1.7
+ 3.1.8
-
-
-
+
+
+
-
-
-
+
+
+
- 3.1.7
+ 3.1.8
-
-
+
+
- 3.1.7
+ 3.1.8
-
+
- 3.1.7
+ 3.1.8
-
+
- 3.1.7
+ 3.1.8
-
-
-
+
+
+
-
-
-
+
+
+
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
-
-
+
+
-
-
+
+
- 3.1.7
+ 3.1.8
-
+
-
+
- 3.1.7
+ 3.1.8
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
@@ -244,215 +244,215 @@
- 3.1.7
+ 3.1.8
-
-
+
+
- 3.1.7
+ 3.1.8
-
-
+
+
-
+
-
+
-
-
+
+
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
-
+
-
+
-
+
- 3.1.7
+ 3.1.8
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
-
+
- 3.1.7
+ 3.1.8
-
+
- 3.1.7
+ 3.1.8
-
-
+
+
- 3.1.7
+ 3.1.8
-
-
+
+
-
-
+
+
- 3.1.7
+ 3.1.8
-
+
- 3.1.7
+ 3.1.8
-
+
- 3.1.7
+ 3.1.8
-
-
+
+
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
-
-
-
+
+
+
-
-
-
+
+
+
- 3.1.7
+ 3.1.8
-
+
-
+
- 3.1.7
+ 3.1.8
-
-
+
+
-
-
+
+
- 3.1.7
+ 3.1.8
-
-
+
+
-
-
+
+
- 3.1.7
+ 3.1.8
-
-
-
+
+
+
- 3.1.7
+ 3.1.8
-
-
+
+
- 3.1.7
+ 3.1.8
@@ -460,236 +460,236 @@
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
-
+
- 3.1.7
+ 3.1.8
-
+
- 3.1.7
+ 3.1.8
-
-
-
+
+
+
- 3.1.7
+ 3.1.8
-
-
-
+
+
+
- 3.1.7
+ 3.1.8
-
+
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
-
+
-
-
+
+
- 3.1.7
+ 3.1.8
-
-
+
+
- 3.1.7
+ 3.1.8
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
- 3.1.7
+ 3.1.8
-
-
+
+
-
-
+
+
- 3.1.7
+ 3.1.8
-
+
-
+
- 3.1.7
+ 3.1.8
-
+
- 3.1.7
+ 3.1.8
-
+
- 3.1.7
+ 3.1.8
-
-
-
-
+
+
+
+
- 3.1.7
+ 3.1.8
-
+
- 3.1.7
+ 3.1.8
-
+
- 3.1.7
+ 3.1.8
-
-
+
+
- 3.1.7
+ 3.1.8
-
+
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
- 3.1.7
+ 3.1.8
-
-
-
+
+
+
- 3.1.7
+ 3.1.8
-
-
-
+
+
+
-
-
-
+
+
+
- 3.1.7
+ 3.1.8
-
-
-
+
+
+
-
-
-
+
+
+
\ No newline at end of file
diff --git a/eng/Baseline.xml b/eng/Baseline.xml
index ca3b6217b81f..ce5a601fe356 100644
--- a/eng/Baseline.xml
+++ b/eng/Baseline.xml
@@ -4,87 +4,87 @@ This file contains a list of all the packages and their versions which were rele
Update this list when preparing for a new patch.
-->
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/eng/Dependencies.props b/eng/Dependencies.props
index 62a7ac2e0f82..a0acb2d7924b 100644
--- a/eng/Dependencies.props
+++ b/eng/Dependencies.props
@@ -94,15 +94,17 @@ and are generated based on the last package release.
+
-
+
+
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index c58297de2d69..3fa9dd819fee 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -9,304 +9,309 @@
-->
-
+ https://github.com/dotnet/efcore
- 69c4c9d142882c71cf196d593a1786180abee181
+ 2352499b52cdfc95ddcfd81c4967e12512e00eee
-
+ https://github.com/dotnet/efcore
- 69c4c9d142882c71cf196d593a1786180abee181
+ 2352499b52cdfc95ddcfd81c4967e12512e00eee
-
+ https://github.com/dotnet/efcore
- 69c4c9d142882c71cf196d593a1786180abee181
+ 2352499b52cdfc95ddcfd81c4967e12512e00eee
-
+ https://github.com/dotnet/efcore
- 69c4c9d142882c71cf196d593a1786180abee181
+ 2352499b52cdfc95ddcfd81c4967e12512e00eee
-
+ https://github.com/dotnet/efcore
- 69c4c9d142882c71cf196d593a1786180abee181
+ 2352499b52cdfc95ddcfd81c4967e12512e00eee
-
+ https://github.com/dotnet/efcore
- 69c4c9d142882c71cf196d593a1786180abee181
+ 2352499b52cdfc95ddcfd81c4967e12512e00eee
-
+ https://github.com/dotnet/efcore
- 69c4c9d142882c71cf196d593a1786180abee181
+ 2352499b52cdfc95ddcfd81c4967e12512e00eee
-
+ https://github.com/dotnet/efcore
- 69c4c9d142882c71cf196d593a1786180abee181
+ 2352499b52cdfc95ddcfd81c4967e12512e00eee
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
+
+
+ https://github.com/dotnet/runtime
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fa
-
+ https://github.com/dotnet/runtime
- 2d8e19f1880c655bcc0994852f41b47341e2c566
+ 4fef87c65e7466000884aeb9dee6498b162fe2fahttps://github.com/dotnet/arcade
diff --git a/eng/Versions.props b/eng/Versions.props
index b632a8647139..466319ae7906 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -6,33 +6,38 @@
-->
- 5
+ 600
+ 1truerelease
- rtm
- RTM $(PreReleaseVersionIteration)
+ alpha
+ Alpha $(PreReleaseVersionIteration)truefalse$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion)true
- $(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion).$(AspNetCorePatchVersion)
+ $(AspNetCoreMajorMinorVersion).$(AspNetCorePatchVersion)$(VersionPrefix)
- $(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion).0
+ $(AspNetCoreMajorMinorVersion).00.3.$(AspNetCorePatchVersion)$([MSBuild]::Add(10, $(AspNetCoreMajorVersion)))$(AspNetCoreMinorVersion)$(AspNetCorePatchVersion)
- $(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion).$([MSBuild]::Subtract($(AspNetCorePatchVersion), 1))
+ $(AspNetCoreMajorMinorVersion).$([MSBuild]::Subtract($(AspNetCorePatchVersion), 1))
+
+ net5.0
@@ -54,81 +59,83 @@
-->
- 5.0.0
- 5.0.0-rtm.20514.6
- 5.0.0
- 5.0.0
- 5.0.0-rtm.20514.6
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0-rtm.20514.6
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0-rtm.20514.6
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
+ 6.0.0-alpha.1.20507.4
- 5.0.0
+ 6.0.0-alpha.1.20507.4
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
- 5.0.0
+ 6.0.0-alpha.1.20509.5
+ 6.0.0-alpha.1.20509.5
+ 6.0.0-alpha.1.20509.5
+ 6.0.0-alpha.1.20509.5
+ 6.0.0-alpha.1.20509.5
+ 6.0.0-alpha.1.20509.5
+ 6.0.0-alpha.1.20509.5
+ 6.0.0-alpha.1.20509.55.0.0-beta.20510.1
@@ -149,6 +156,7 @@
$(MicrosoftNETCoreAppRuntimewinx64PackageVersion)
+
3.8.0-3.20458.65.0.0-preview.4.20180.4
@@ -197,12 +205,15 @@
1.4.06.7.15.7.0
-
+
2.1.12.2.03.1.8-servicing-20421-6$(MicrosoftAspNetCoreAzureAppServicesSiteExtension31PackageVersion)$(MicrosoftAspNetCoreAzureAppServicesSiteExtension31PackageVersion)
+ 5.0.0-preview-7-20365-19
+ $(MicrosoftAspNetCoreAzureAppServicesSiteExtension50PackageVersion)
+ $(MicrosoftAspNetCoreAzureAppServicesSiteExtension50PackageVersion)0.9.90.12.1
@@ -231,7 +242,7 @@
13.0.44.0.0-alpha0517.17134.0
- 85.0.4183.8300
+ 86.0.4240.2200-beta4.0.0-alpha051.4.04.0.0
diff --git a/eng/helix/content/RunTests/RunTestsOptions.cs b/eng/helix/content/RunTests/RunTestsOptions.cs
index 13bd50a80fad..031326ba8a14 100644
--- a/eng/helix/content/RunTests/RunTestsOptions.cs
+++ b/eng/helix/content/RunTests/RunTestsOptions.cs
@@ -50,6 +50,11 @@ public static RunTestsOptions Parse(string[] args)
aliases: new string[] { "--helixTimeout" },
description: "The timeout duration of the Helix job")
{ Argument = new Argument(), Required = true },
+
+ new Option(
+ aliases: new string[] { "--source" },
+ description: "The restore sources to use during testing")
+ { Argument = new Argument() { Arity = ArgumentArity.ZeroOrMore }, Required = true }
};
var parseResult = command.Parse(args);
diff --git a/eng/targets/Helix.Common.props b/eng/targets/Helix.Common.props
index 07b8246029c9..87efd43249d0 100644
--- a/eng/targets/Helix.Common.props
+++ b/eng/targets/Helix.Common.props
@@ -21,25 +21,29 @@
-
+
-
-
-
-
+
+
+
+
+
+
+
+
+
-
diff --git a/eng/tools/BaselineGenerator/BaselineGenerator.csproj b/eng/tools/BaselineGenerator/BaselineGenerator.csproj
index 775e7523c847..d80ea1277248 100644
--- a/eng/tools/BaselineGenerator/BaselineGenerator.csproj
+++ b/eng/tools/BaselineGenerator/BaselineGenerator.csproj
@@ -7,8 +7,8 @@
+
-
diff --git a/eng/tools/BaselineGenerator/Program.cs b/eng/tools/BaselineGenerator/Program.cs
index e77b35edeeeb..a68406a3cd68 100644
--- a/eng/tools/BaselineGenerator/Program.cs
+++ b/eng/tools/BaselineGenerator/Program.cs
@@ -4,6 +4,7 @@
using System;
using System.IO;
using System.Linq;
+using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading;
@@ -30,16 +31,18 @@ static void Main(string[] args)
new Program().Execute(args);
}
- private readonly CommandOption _source;
+ private readonly CommandOption _sources;
private readonly CommandOption _output;
private readonly CommandOption _update;
+ private static readonly string[] _defaultSources = new string[] { "https://api.nuget.org/v3/index.json" };
+
public Program()
{
- _source = Option(
- "-s|--package-source ",
- "The NuGet source of packages to fetch",
- CommandOptionType.SingleValue);
+ _sources = Option(
+ "-s|--package-sources ",
+ "The NuGet source(s) of packages to fetch",
+ CommandOptionType.MultipleValue);
_output = Option("-o|--output ", "The generated file output path", CommandOptionType.SingleValue);
_update = Option("-u|--update", "Regenerate the input (Baseline.xml) file.", CommandOptionType.NoValue);
@@ -56,26 +59,32 @@ private async Task Run()
var inputPath = Path.Combine(Directory.GetCurrentDirectory(), "Baseline.xml");
var input = XDocument.Load(inputPath);
- var source = _source.HasValue() ? _source.Value().TrimEnd('/') : "https://api.nuget.org/v3/index.json";
- var packageSource = new PackageSource(source);
+ var sources = _sources.HasValue() ? _sources.Values.Select(s => s.TrimEnd('/')) : _defaultSources;
+ var packageSources = sources.Select(s => new PackageSource(s));
var providers = Repository.Provider.GetCoreV3(); // Get v2 and v3 API support
- var sourceRepository = new SourceRepository(packageSource, providers);
+ var sourceRepositories = packageSources.Select(ps => new SourceRepository(ps, providers));
if (_update.HasValue())
{
- var updateResult = await RunUpdateAsync(inputPath, input, sourceRepository);
+ var updateResult = await RunUpdateAsync(inputPath, input, sourceRepositories);
if (updateResult != 0)
{
return updateResult;
}
}
- var feedType = await sourceRepository.GetFeedType(CancellationToken.None);
- var feedV3 = feedType == FeedType.HttpV3;
- var packageBase = source + "/package";
- if (feedV3)
+ List<(string packageBase, bool feedV3)> packageBases = new List<(string, bool)>();
+ foreach (var sourceRepository in sourceRepositories)
{
- var resources = await sourceRepository.GetResourceAsync();
- packageBase = resources.GetServiceEntryUri(ServiceTypes.PackageBaseAddress).ToString().TrimEnd('/');
+ var feedType = await sourceRepository.GetFeedType(CancellationToken.None);
+ var feedV3 = feedType == FeedType.HttpV3;
+ var packageBase = sourceRepository.PackageSource + "/package";
+ if (feedV3)
+ {
+ var resources = await sourceRepository.GetResourceAsync();
+ packageBase = resources.GetServiceEntryUri(ServiceTypes.PackageBaseAddress).ToString().TrimEnd('/');
+ }
+
+ packageBases.Add((packageBase, feedV3));
}
var output = _output.HasValue()
@@ -116,18 +125,34 @@ private async Task Run()
if (!File.Exists(nupkgPath))
{
- var url = feedV3 ?
- $"{packageBase}/{id.ToLowerInvariant()}/{version}/{id.ToLowerInvariant()}.{version}.nupkg" :
- $"{packageBase}/{id}/{version}";
-
- Console.WriteLine($"Downloading {url}");
- using (var response = await client.GetStreamAsync(url))
+ foreach ((string packageBase, bool feedV3) in packageBases)
{
- using (var file = File.Create(nupkgPath))
+ var url = feedV3 ?
+ $"{packageBase}/{id.ToLowerInvariant()}/{version}/{id.ToLowerInvariant()}.{version}.nupkg" :
+ $"{packageBase}/{id}/{version}";
+
+ Console.WriteLine($"Downloading {url}");
+ try
+ {
+ using (var response = await client.GetStreamAsync(url))
+ {
+ using (var file = File.Create(nupkgPath))
+ {
+ await response.CopyToAsync(file);
+ }
+ }
+ }
+ catch (HttpRequestException e) when (e.StatusCode == System.Net.HttpStatusCode.NotFound)
{
- await response.CopyToAsync(file);
+ // If it's not found, continue onto the next one.
+ continue;
}
}
+
+ if (!File.Exists(nupkgPath))
+ {
+ throw new Exception($"Could not download package {id} @ {version} using any input feed");
+ }
}
using (var reader = new PackageArchiveReader(nupkgPath))
@@ -195,9 +220,11 @@ private async Task Run()
private async Task RunUpdateAsync(
string documentPath,
XDocument document,
- SourceRepository sourceRepository)
+ IEnumerable sourceRepositories)
{
- var packageMetadataResource = await sourceRepository.GetResourceAsync();
+ var packageMetadataResources = await Task.WhenAll(sourceRepositories.Select(async sr =>
+ await sr.GetResourceAsync()));
+
var logger = new Logger(Error, Out);
var hasChanged = false;
using (var cacheContext = new SourceCacheContext { NoCache = true })
@@ -206,7 +233,7 @@ private async Task RunUpdateAsync(
hasChanged = await TryUpdateVersionAsync(
versionAttribute,
"Microsoft.AspNetCore.App.Runtime.win-x64",
- packageMetadataResource,
+ packageMetadataResources,
logger,
cacheContext);
@@ -217,7 +244,7 @@ private async Task RunUpdateAsync(
var attributeChanged = await TryUpdateVersionAsync(
versionAttribute,
id,
- packageMetadataResource,
+ packageMetadataResources,
logger,
cacheContext);
@@ -261,25 +288,36 @@ private async Task RunUpdateAsync(
private static async Task TryUpdateVersionAsync(
XAttribute versionAttribute,
string packageId,
- PackageMetadataResource packageMetadataResource,
+ IEnumerable packageMetadataResources,
ILogger logger,
SourceCacheContext cacheContext)
{
- var searchMetadata = await packageMetadataResource.GetMetadataAsync(
- packageId,
- includePrerelease: false,
- includeUnlisted: true, // Microsoft.AspNetCore.DataOrotection.Redis package is not listed.
- sourceCacheContext: cacheContext,
- log: logger,
- token: CancellationToken.None);
-
var currentVersion = NuGetVersion.Parse(versionAttribute.Value);
var versionRange = new VersionRange(
currentVersion,
new FloatRange(NuGetVersionFloatBehavior.Patch, currentVersion));
- var latestVersion = versionRange.FindBestMatch(
- searchMetadata.Select(metadata => metadata.Identity.Version));
+ var searchMetadatas = await Task.WhenAll(
+ packageMetadataResources.Select(async pmr => await pmr.GetMetadataAsync(
+ packageId,
+ includePrerelease: false,
+ includeUnlisted: true, // Microsoft.AspNetCore.DataOrotection.Redis package is not listed.
+ sourceCacheContext: cacheContext,
+ log: logger,
+ token: CancellationToken.None)));
+
+ // Find the latest version among each search metadata
+ NuGetVersion latestVersion = null;
+ foreach (var searchMetadata in searchMetadatas)
+ {
+ var potentialLatestVersion = versionRange.FindBestMatch(
+ searchMetadata.Select(metadata => metadata.Identity.Version));
+ if (latestVersion == null ||
+ (potentialLatestVersion != null && potentialLatestVersion.CompareTo(latestVersion) > 0))
+ {
+ latestVersion = potentialLatestVersion;
+ }
+ }
if (latestVersion == null)
{
diff --git a/eng/tools/RepoTasks/.editorconfig b/eng/tools/RepoTasks/.editorconfig
new file mode 100644
index 000000000000..89bb5ad88f65
--- /dev/null
+++ b/eng/tools/RepoTasks/.editorconfig
@@ -0,0 +1,4 @@
+[*.cs]
+dotnet_diagnostic.CA1307.severity = none
+dotnet_diagnostic.CA1308.severity = none
+dotnet_diagnostic.CA1309.severity = none
diff --git a/global.json b/global.json
index 213d84ae5332..e00b9b5b4ac6 100644
--- a/global.json
+++ b/global.json
@@ -1,9 +1,9 @@
{
"sdk": {
- "version": "5.0.100-rc.2.20479.15"
+ "version": "6.0.100-alpha.1.20472.11"
},
"tools": {
- "dotnet": "5.0.100-rc.2.20479.15",
+ "dotnet": "6.0.100-alpha.1.20472.11",
"runtimes": {
"dotnet/x64": [
"2.1.18",
diff --git a/src/Analyzers/Analyzers/test/AnalyzerTestBase.cs b/src/Analyzers/Analyzers/test/AnalyzerTestBase.cs
index 2c324308c0c6..f70ac58c8b3f 100644
--- a/src/Analyzers/Analyzers/test/AnalyzerTestBase.cs
+++ b/src/Analyzers/Analyzers/test/AnalyzerTestBase.cs
@@ -13,7 +13,7 @@ public abstract class AnalyzerTestBase
{
public TestSource Read(string source)
{
- if (!source.EndsWith(".cs"))
+ if (!source.EndsWith(".cs", StringComparison.Ordinal))
{
source = source + ".cs";
}
@@ -30,7 +30,7 @@ public TestSource Read(string source)
public Project CreateProject(string source)
{
- if (!source.EndsWith(".cs"))
+ if (!source.EndsWith(".cs", StringComparison.Ordinal))
{
source = source + ".cs";
}
diff --git a/src/Antiforgery/src/Internal/DefaultAntiforgery.cs b/src/Antiforgery/src/Internal/DefaultAntiforgery.cs
index b310d2286b73..613adf73af9f 100644
--- a/src/Antiforgery/src/Internal/DefaultAntiforgery.cs
+++ b/src/Antiforgery/src/Internal/DefaultAntiforgery.cs
@@ -400,7 +400,7 @@ private void LogCacheHeaderOverrideWarning(HttpResponse response)
var pragmaHeader = response.Headers[HeaderNames.Pragma];
if (!logWarning
&& !string.IsNullOrEmpty(pragmaHeader)
- && string.Compare(pragmaHeader, "no-cache", ignoreCase: true) != 0)
+ && !string.Equals(pragmaHeader, "no-cache", StringComparison.OrdinalIgnoreCase))
{
logWarning = true;
}
diff --git a/src/Components/Analyzers/src/ComponentParametersShouldBePublicCodeFixProvider.cs b/src/Components/Analyzers/src/ComponentParametersShouldBePublicCodeFixProvider.cs
index 173633f0e9fd..0d89f0236d02 100644
--- a/src/Components/Analyzers/src/ComponentParametersShouldBePublicCodeFixProvider.cs
+++ b/src/Components/Analyzers/src/ComponentParametersShouldBePublicCodeFixProvider.cs
@@ -3,6 +3,7 @@
using System.Collections.Immutable;
using System.Composition;
+using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
@@ -37,7 +38,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
var declaration = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType().First();
// Register a code action that will invoke the fix.
- var title = Title.ToString();
+ var title = Title.ToString(CultureInfo.InvariantCulture);
context.RegisterCodeFix(
CodeAction.Create(
title: title,
diff --git a/src/Components/Analyzers/test/AnalyzerTestBase.cs b/src/Components/Analyzers/test/AnalyzerTestBase.cs
index 91bfe2d9cc41..5196831a1b84 100644
--- a/src/Components/Analyzers/test/AnalyzerTestBase.cs
+++ b/src/Components/Analyzers/test/AnalyzerTestBase.cs
@@ -16,7 +16,7 @@ public abstract class AnalyzerTestBase
public TestSource Read(string source)
{
- if (!source.EndsWith(".cs"))
+ if (!source.EndsWith(".cs", StringComparison.Ordinal))
{
source = source + ".cs";
}
@@ -33,7 +33,7 @@ public TestSource Read(string source)
public Project CreateProject(string source)
{
- if (!source.EndsWith(".cs"))
+ if (!source.EndsWith(".cs", StringComparison.Ordinal))
{
source = source + ".cs";
}
diff --git a/src/Components/Analyzers/test/Verifiers/CodeFixVerifier.cs b/src/Components/Analyzers/test/Verifiers/CodeFixVerifier.cs
index cb6c9d432992..693b6ef8cef9 100644
--- a/src/Components/Analyzers/test/Verifiers/CodeFixVerifier.cs
+++ b/src/Components/Analyzers/test/Verifiers/CodeFixVerifier.cs
@@ -3,14 +3,15 @@
// Most of the code in this file comes from the default Roslyn Analyzer project template
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Formatting;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
using Xunit;
namespace TestHelper
@@ -82,7 +83,7 @@ private void VerifyFix(string language, DiagnosticAnalyzer analyzer, CodeFixProv
var analyzerDiagnostics = GetSortedDiagnosticsFromDocuments(analyzer, new[] { document });
var compilerDiagnostics = GetCompilerDiagnostics(document);
var attempts = analyzerDiagnostics.Length;
-
+
for (int i = 0; i < attempts; ++i)
{
var actions = new List();
@@ -113,7 +114,9 @@ private void VerifyFix(string language, DiagnosticAnalyzer analyzer, CodeFixProv
newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, GetCompilerDiagnostics(document));
Assert.True(false,
- string.Format("Fix introduced new compiler diagnostics:\r\n{0}\r\n\r\nNew document:\r\n{1}\r\n",
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "Fix introduced new compiler diagnostics:\r\n{0}\r\n\r\nNew document:\r\n{1}\r\n",
string.Join("\r\n", newCompilerDiagnostics.Select(d => d.ToString())),
document.GetSyntaxRootAsync().Result.ToFullString()));
}
diff --git a/src/Components/Analyzers/test/Verifiers/DiagnosticVerifier.cs b/src/Components/Analyzers/test/Verifiers/DiagnosticVerifier.cs
index f56d4ff93d74..aacb55afac3c 100644
--- a/src/Components/Analyzers/test/Verifiers/DiagnosticVerifier.cs
+++ b/src/Components/Analyzers/test/Verifiers/DiagnosticVerifier.cs
@@ -3,11 +3,13 @@
// Most of the code in this file comes from the default Roslyn Analyzer project template
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.Diagnostics;
+using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Text;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Diagnostics;
using Xunit;
namespace TestHelper
@@ -82,7 +84,7 @@ protected void VerifyBasicDiagnostic(string[] sources, params DiagnosticResult[]
}
///
- /// General method that gets a collection of actual diagnostics found in the source after the analyzer is run,
+ /// General method that gets a collection of actual diagnostics found in the source after the analyzer is run,
/// then verifies each of them.
///
/// An array of strings to create source documents from to run the analyzers on
@@ -115,7 +117,7 @@ private static void VerifyDiagnosticResults(IEnumerable actualResult
string diagnosticsOutput = actualResults.Any() ? FormatDiagnostics(analyzer, actualResults.ToArray()) : " NONE.";
Assert.True(false,
- string.Format("Mismatch between number of diagnostics returned, expected \"{0}\" actual \"{1}\"\r\n\r\nDiagnostics:\r\n{2}\r\n", expectedCount, actualCount, diagnosticsOutput));
+ string.Format(CultureInfo.InvariantCulture, "Mismatch between number of diagnostics returned, expected \"{0}\" actual \"{1}\"\r\n\r\nDiagnostics:\r\n{2}\r\n", expectedCount, actualCount, diagnosticsOutput));
}
for (int i = 0; i < expectedResults.Length; i++)
@@ -128,7 +130,7 @@ private static void VerifyDiagnosticResults(IEnumerable actualResult
if (actual.Location != Location.None)
{
Assert.True(false,
- string.Format("Expected:\nA project diagnostic with No location\nActual:\n{0}",
+ string.Format(CultureInfo.InvariantCulture, "Expected:\nA project diagnostic with No location\nActual:\n{0}",
FormatDiagnostics(analyzer, actual)));
}
}
@@ -140,7 +142,9 @@ private static void VerifyDiagnosticResults(IEnumerable actualResult
if (additionalLocations.Length != expected.Locations.Length - 1)
{
Assert.True(false,
- string.Format("Expected {0} additional locations but got {1} for Diagnostic:\r\n {2}\r\n",
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "Expected {0} additional locations but got {1} for Diagnostic:\r\n {2}\r\n",
expected.Locations.Length - 1, additionalLocations.Length,
FormatDiagnostics(analyzer, actual)));
}
@@ -154,21 +158,27 @@ private static void VerifyDiagnosticResults(IEnumerable actualResult
if (actual.Id != expected.Id)
{
Assert.True(false,
- string.Format("Expected diagnostic id to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "Expected diagnostic id to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
expected.Id, actual.Id, FormatDiagnostics(analyzer, actual)));
}
if (actual.Severity != expected.Severity)
{
Assert.True(false,
- string.Format("Expected diagnostic severity to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "Expected diagnostic severity to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
expected.Severity, actual.Severity, FormatDiagnostics(analyzer, actual)));
}
if (actual.GetMessage() != expected.Message)
{
Assert.True(false,
- string.Format("Expected diagnostic message to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "Expected diagnostic message to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
expected.Message, actual.GetMessage(), FormatDiagnostics(analyzer, actual)));
}
}
@@ -186,7 +196,9 @@ private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagno
var actualSpan = actual.GetLineSpan();
Assert.True(actualSpan.Path == expected.Path || (actualSpan.Path != null && actualSpan.Path.Contains("Test0.") && expected.Path.Contains("Test.")),
- string.Format("Expected diagnostic to be in file \"{0}\" was actually in file \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "Expected diagnostic to be in file \"{0}\" was actually in file \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
expected.Path, actualSpan.Path, FormatDiagnostics(analyzer, diagnostic)));
var actualLinePosition = actualSpan.StartLinePosition;
@@ -197,7 +209,9 @@ private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagno
if (actualLinePosition.Line + 1 != expected.Line)
{
Assert.True(false,
- string.Format("Expected diagnostic to be on line \"{0}\" was actually on line \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "Expected diagnostic to be on line \"{0}\" was actually on line \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
expected.Line, actualLinePosition.Line + 1, FormatDiagnostics(analyzer, diagnostic)));
}
}
@@ -208,7 +222,9 @@ private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagno
if (actualLinePosition.Character + 1 != expected.Column)
{
Assert.True(false,
- string.Format("Expected diagnostic to start at column \"{0}\" was actually at column \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "Expected diagnostic to start at column \"{0}\" was actually at column \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n",
expected.Column, actualLinePosition.Character + 1, FormatDiagnostics(analyzer, diagnostic)));
}
}
@@ -239,17 +255,19 @@ private static string FormatDiagnostics(DiagnosticAnalyzer analyzer, params Diag
var location = diagnostics[i].Location;
if (location == Location.None)
{
- builder.AppendFormat("GetGlobalResult({0}.{1})", analyzerType.Name, rule.Id);
+ builder.AppendFormat(CultureInfo.InvariantCulture, "GetGlobalResult({0}.{1})", analyzerType.Name, rule.Id);
}
else
{
Assert.True(location.IsInSource,
$"Test base does not currently handle diagnostics in metadata locations. Diagnostic in metadata: {diagnostics[i]}\r\n");
- string resultMethodName = diagnostics[i].Location.SourceTree.FilePath.EndsWith(".cs") ? "GetCSharpResultAt" : "GetBasicResultAt";
+ string resultMethodName = diagnostics[i].Location.SourceTree.FilePath.EndsWith(".cs", StringComparison.Ordinal) ? "GetCSharpResultAt" : "GetBasicResultAt";
var linePosition = diagnostics[i].Location.GetLineSpan().StartLinePosition;
- builder.AppendFormat("{0}({1}, {2}, {3}.{4})",
+ builder.AppendFormat(
+ CultureInfo.InvariantCulture,
+ "{0}({1}, {2}, {3}.{4})",
resultMethodName,
linePosition.Line + 1,
linePosition.Character + 1,
diff --git a/src/Components/Components/src/ComponentBase.cs b/src/Components/Components/src/ComponentBase.cs
index dd80af0fd3bf..1780a78a6a84 100644
--- a/src/Components/Components/src/ComponentBase.cs
+++ b/src/Components/Components/src/ComponentBase.cs
@@ -17,8 +17,6 @@ namespace Microsoft.AspNetCore.Components
// about IComponent). This gives us flexibility to change the lifecycle concepts easily,
// or for developers to design their own lifecycles as different base classes.
- // TODO: When the component lifecycle design stabilizes, add proper unit tests for ComponentBase.
-
///
/// Optional base class for components. Alternatively, components may
/// implement directly.
@@ -200,9 +198,8 @@ void IComponent.Attach(RenderHandle renderHandle)
/// A that completes when the component has finished updating and rendering itself.
///
///
- /// The method should be passed the entire set of parameter values each
- /// time is called. It not required that the caller supply a parameter
- /// value for all parameters that are logically understood by the component.
+ /// Parameters are passed when is called. It is not required that
+ /// the caller supply a parameter value for all of the parameters that are logically understood by the component.
///
///
/// The default implementation of will set the value of each property
diff --git a/src/Components/Components/src/Microsoft.AspNetCore.Components.csproj b/src/Components/Components/src/Microsoft.AspNetCore.Components.csproj
index 23f816726b13..a87f735c6fe1 100644
--- a/src/Components/Components/src/Microsoft.AspNetCore.Components.csproj
+++ b/src/Components/Components/src/Microsoft.AspNetCore.Components.csproj
@@ -28,7 +28,7 @@
-
+
diff --git a/src/Components/Components/src/Routing/TemplateSegment.cs b/src/Components/Components/src/Routing/TemplateSegment.cs
index c4d351995199..e08953158484 100644
--- a/src/Components/Components/src/Routing/TemplateSegment.cs
+++ b/src/Components/Components/src/Routing/TemplateSegment.cs
@@ -61,7 +61,7 @@ public TemplateSegment(string template, string segment, bool isParameter)
// Set the IsOptional flag to true if any type constraints
// for this parameter are designated as optional.
- IsOptional = tokens.Skip(1).Any(token => token.EndsWith("?"));
+ IsOptional = tokens.Skip(1).Any(token => token.EndsWith('?'));
Value = tokens[0];
Constraints = tokens.Skip(1)
diff --git a/src/Components/Components/test/EventCallbackFactoryBinderExtensionsTest.cs b/src/Components/Components/test/EventCallbackFactoryBinderExtensionsTest.cs
index 8df50921127b..23889dd40d01 100644
--- a/src/Components/Components/test/EventCallbackFactoryBinderExtensionsTest.cs
+++ b/src/Components/Components/test/EventCallbackFactoryBinderExtensionsTest.cs
@@ -396,7 +396,7 @@ public async Task CreateBinder_DateTime()
var expectedValue = new DateTime(2018, 3, 4, 1, 2, 3);
// Act
- await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(), });
+ await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(CultureInfo.InvariantCulture), });
Assert.Equal(expectedValue, value);
Assert.Equal(1, component.Count);
@@ -415,7 +415,7 @@ public async Task CreateBinder_NullableDateTime()
var expectedValue = new DateTime(2018, 3, 4, 1, 2, 3);
// Act
- await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(), });
+ await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(CultureInfo.InvariantCulture), });
Assert.Equal(expectedValue, value);
Assert.Equal(1, component.Count);
@@ -435,7 +435,7 @@ public async Task CreateBinder_DateTime_Format()
var expectedValue = new DateTime(2018, 3, 4);
// Act
- await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(format), });
+ await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(format, CultureInfo.InvariantCulture), });
Assert.Equal(expectedValue, value);
Assert.Equal(1, component.Count);
@@ -455,7 +455,7 @@ public async Task CreateBinder_NullableDateTime_Format()
var expectedValue = new DateTime(2018, 3, 4);
// Act
- await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(format), });
+ await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(format, CultureInfo.InvariantCulture), });
Assert.Equal(expectedValue, value);
Assert.Equal(1, component.Count);
@@ -474,7 +474,7 @@ public async Task CreateBinder_DateTimeOffset()
var expectedValue = new DateTime(2018, 3, 4, 1, 2, 3);
// Act
- await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(), });
+ await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(CultureInfo.InvariantCulture), });
Assert.Equal(expectedValue, value);
Assert.Equal(1, component.Count);
@@ -493,7 +493,7 @@ public async Task CreateBinder_NullableDateTimeOffset()
var expectedValue = new DateTime(2018, 3, 4, 1, 2, 3);
// Act
- await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(), });
+ await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(CultureInfo.InvariantCulture), });
Assert.Equal(expectedValue, value);
Assert.Equal(1, component.Count);
@@ -513,7 +513,7 @@ public async Task CreateBinder_DateTimeOffset_Format()
var expectedValue = new DateTime(2018, 3, 4);
// Act
- await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(format), });
+ await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(format, CultureInfo.InvariantCulture), });
Assert.Equal(expectedValue, value);
Assert.Equal(1, component.Count);
@@ -533,7 +533,7 @@ public async Task CreateBinder_NullableDateTimeOffset_Format()
var expectedValue = new DateTime(2018, 3, 4);
// Act
- await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(format), });
+ await binder.InvokeAsync(new ChangeEventArgs() { Value = expectedValue.ToString(format, CultureInfo.InvariantCulture), });
Assert.Equal(expectedValue, value);
Assert.Equal(1, component.Count);
diff --git a/src/Components/Components/test/RendererTest.cs b/src/Components/Components/test/RendererTest.cs
index efa3db89915d..5a5acc6e896d 100644
--- a/src/Components/Components/test/RendererTest.cs
+++ b/src/Components/Components/test/RendererTest.cs
@@ -5,6 +5,7 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Globalization;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.Threading;
@@ -224,7 +225,7 @@ public async Task CanRenderAsyncTopLevelComponents()
{
Assert.Equal(RenderTreeEditType.StepOut, edit.Type);
});
- AssertFrame.Text(update.ReferenceFrames[0], (5 - i).ToString());
+ AssertFrame.Text(update.ReferenceFrames[0], (5 - i).ToString(CultureInfo.InvariantCulture));
}
}
diff --git a/src/Components/Components/test/Routing/RouteTableFactoryTests.cs b/src/Components/Components/test/Routing/RouteTableFactoryTests.cs
index 3a4887fba090..3690e4e2821e 100644
--- a/src/Components/Components/test/Routing/RouteTableFactoryTests.cs
+++ b/src/Components/Components/test/Routing/RouteTableFactoryTests.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.Extensions.DependencyModel;
@@ -630,7 +631,7 @@ public void DoesNotThrowIfStableSortComparesRouteWithItself()
Assert.Equal(17, routeTable.Routes.Length);
for (var i = 0; i < 17; i++)
{
- var templateText = "r" + i.ToString().PadLeft(2, '0');
+ var templateText = "r" + i.ToString(CultureInfo.InvariantCulture).PadLeft(2, '0');
Assert.Equal(templateText, routeTable.Routes[i].Template.TemplateText);
}
}
diff --git a/src/Components/Components/test/Routing/RouterTest.cs b/src/Components/Components/test/Routing/RouterTest.cs
index 29da11476bf9..acf84fee4f83 100644
--- a/src/Components/Components/test/Routing/RouterTest.cs
+++ b/src/Components/Components/test/Routing/RouterTest.cs
@@ -62,7 +62,7 @@ public async Task CanceledFailedOnNavigateAsyncDoesNothing()
Action OnNavigateAsync = async (NavigationContext args) =>
{
onNavigateInvoked += 1;
- if (args.Path.EndsWith("jan"))
+ if (args.Path.EndsWith("jan", StringComparison.Ordinal))
{
await Task.Delay(Timeout.Infinite, args.CancellationToken);
throw new Exception("This is an uncaught exception.");
@@ -96,7 +96,7 @@ public async Task AlreadyCanceledOnNavigateAsyncDoesNothing()
var triggerCancel = new TaskCompletionSource();
Action OnNavigateAsync = async (NavigationContext args) =>
{
- if (args.Path.EndsWith("jan"))
+ if (args.Path.EndsWith("jan", StringComparison.Ordinal))
{
var tcs = new TaskCompletionSource();
await triggerCancel.Task;
@@ -152,7 +152,7 @@ public async Task RefreshesOnceOnCancelledOnNavigateAsync()
// Arrange
Action OnNavigateAsync = async (NavigationContext args) =>
{
- if (args.Path.EndsWith("jan"))
+ if (args.Path.EndsWith("jan", StringComparison.Ordinal))
{
await Task.Delay(Timeout.Infinite, args.CancellationToken);
}
diff --git a/src/Components/ComponentsNoDeps.slnf b/src/Components/ComponentsNoDeps.slnf
index 0596b3bc64a1..f4c4daa62617 100644
--- a/src/Components/ComponentsNoDeps.slnf
+++ b/src/Components/ComponentsNoDeps.slnf
@@ -14,6 +14,7 @@
"src\\Components\\Ignitor\\src\\Ignitor.csproj",
"src\\Components\\Ignitor\\test\\Ignitor.Test.csproj",
"src\\Components\\Samples\\BlazorServerApp\\BlazorServerApp.csproj",
+ "src\\Components\\Samples\\IgnitorSample\\IgnitorSample.csproj",
"src\\Components\\Server\\src\\Microsoft.AspNetCore.Components.Server.csproj",
"src\\Components\\Server\\test\\Microsoft.AspNetCore.Components.Server.Tests.csproj",
"src\\Components\\WebAssembly\\Authentication.Msal\\src\\Microsoft.Authentication.WebAssembly.Msal.csproj",
@@ -48,4 +49,4 @@
"src\\Components\\test\\testassets\\TestServer\\Components.TestServer.csproj"
]
}
-}
+}
\ No newline at end of file
diff --git a/src/Components/Ignitor/src/BlazorClient.cs b/src/Components/Ignitor/src/BlazorClient.cs
index b19ab8b3dd5f..a06660e6b678 100644
--- a/src/Components/Ignitor/src/BlazorClient.cs
+++ b/src/Components/Ignitor/src/BlazorClient.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Text.Json;
@@ -35,8 +36,10 @@ public BlazorClient()
});
}
- public TimeSpan? DefaultConnectionTimeout { get; set; } = TimeSpan.FromSeconds(20);
- public TimeSpan? DefaultOperationTimeout { get; set; } = TimeSpan.FromMilliseconds(500);
+ public TimeSpan? DefaultConnectionTimeout { get; set; } = Debugger.IsAttached ?
+ Timeout.InfiniteTimeSpan : TimeSpan.FromSeconds(20);
+ public TimeSpan? DefaultOperationTimeout { get; set; } = Debugger.IsAttached ?
+ Timeout.InfiniteTimeSpan : TimeSpan.FromMilliseconds(500);
///
/// Gets or sets a value that determines whether the client will capture data such
@@ -475,7 +478,7 @@ private Uri GetHubUrl(Uri uri)
else
{
var builder = new UriBuilder(uri);
- builder.Path += builder.Path.EndsWith("/") ? "_blazor" : "/_blazor";
+ builder.Path += builder.Path.EndsWith("/", StringComparison.Ordinal) ? "_blazor" : "/_blazor";
return builder.Uri;
}
}
diff --git a/src/Components/Ignitor/src/ElementHive.cs b/src/Components/Ignitor/src/ElementHive.cs
index b7819b427634..07e551c870bf 100644
--- a/src/Components/Ignitor/src/ElementHive.cs
+++ b/src/Components/Ignitor/src/ElementHive.cs
@@ -259,7 +259,7 @@ private int InsertFrame(RenderBatch batch, ContainerNode parent, int childIndex,
case RenderTreeFrameType.Region:
{
- return InsertFrameRange(batch, parent, childIndex, frames, frameIndex + 1, frameIndex + CountDescendantFrames(frame));
+ return InsertFrameRange(batch, parent, childIndex, frames, frameIndex + 1, frameIndex + frame.RegionSubtreeLength);
}
case RenderTreeFrameType.ElementReferenceCapture:
@@ -322,7 +322,8 @@ private void InsertElement(RenderBatch batch, ContainerNode parent, int childInd
{
// Note: we don't handle SVG here
var newElement = new ElementNode(frame.ElementName);
- parent.InsertLogicalChild(newElement, childIndex);
+
+ var inserted = false;
// Apply attributes
for (var i = frameIndex + 1; i < frameIndex + frame.ElementSubtreeLength; i++)
@@ -334,12 +335,21 @@ private void InsertElement(RenderBatch batch, ContainerNode parent, int childInd
}
else
{
+ parent.InsertLogicalChild(newElement, childIndex);
+ inserted = true;
+
// As soon as we see a non-attribute child, all the subsequent child frames are
// not attributes, so bail out and insert the remnants recursively
InsertFrameRange(batch, newElement, 0, frames, i, frameIndex + frame.ElementSubtreeLength);
break;
}
}
+
+ // this element did not have any children, so it's not inserted yet.
+ if (!inserted)
+ {
+ parent.InsertLogicalChild(newElement, childIndex);
+ }
}
private void ApplyAttribute(RenderBatch batch, ElementNode elementNode, RenderTreeFrame attributeFrame)
diff --git a/src/Components/Ignitor/src/NodeSerializer.cs b/src/Components/Ignitor/src/NodeSerializer.cs
index 814635f6d527..c405bdd394fd 100644
--- a/src/Components/Ignitor/src/NodeSerializer.cs
+++ b/src/Components/Ignitor/src/NodeSerializer.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
#nullable enable
@@ -154,7 +155,7 @@ private void SerializeElement(ElementNode elementNode)
Write(" ");
Write(evt.Value.EventName);
Write("(");
- Write(evt.Value.EventId.ToString());
+ Write(evt.Value.EventId.ToString(CultureInfo.InvariantCulture));
Write(")");
}
Write("]");
@@ -181,7 +182,7 @@ private void SerializeChildren(ContainerNode containerNode)
private void SerializeComponent(ComponentNode component)
{
Write("[Component ( ");
- Write(component.ComponentId.ToString());
+ Write(component.ComponentId.ToString(CultureInfo.InvariantCulture));
WriteLine(" )]");
_depth++;
SerializeChildren(component);
diff --git a/src/Components/Ignitor/test/RenderBatchReaderTest.cs b/src/Components/Ignitor/test/RenderBatchReaderTest.cs
index 7a703be6c6fd..917da8a8acbd 100644
--- a/src/Components/Ignitor/test/RenderBatchReaderTest.cs
+++ b/src/Components/Ignitor/test/RenderBatchReaderTest.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Text;
using Xunit;
@@ -263,7 +264,7 @@ static void AssertBinaryContents(Span data, int startIndex, params object[
{
// Assume enums are represented as ints
var expectedEntry = expectedEntryIterationVar.GetType().IsEnum
- ? Convert.ToInt32(expectedEntryIterationVar)
+ ? Convert.ToInt32(expectedEntryIterationVar, CultureInfo.InvariantCulture)
: expectedEntryIterationVar;
if (expectedEntry is int expectedInt)
diff --git a/src/Components/Samples/BlazorServerApp/Pages/Counter.razor b/src/Components/Samples/BlazorServerApp/Pages/Counter.razor
index 59c0d242c3aa..946512d45a7e 100644
--- a/src/Components/Samples/BlazorServerApp/Pages/Counter.razor
+++ b/src/Components/Samples/BlazorServerApp/Pages/Counter.razor
@@ -2,7 +2,7 @@
Counter
-
Current count: @currentCount
+
Current count: @currentCount
diff --git a/src/Components/Samples/IgnitorSample/IgnitorSample.csproj b/src/Components/Samples/IgnitorSample/IgnitorSample.csproj
new file mode 100644
index 000000000000..36c8c55e4153
--- /dev/null
+++ b/src/Components/Samples/IgnitorSample/IgnitorSample.csproj
@@ -0,0 +1,14 @@
+
+
+
+ $(DefaultNetCoreTargetFramework)
+ false
+ enable
+ Exe
+
+
+
+
+
+
+
diff --git a/src/Components/Samples/IgnitorSample/Program.cs b/src/Components/Samples/IgnitorSample/Program.cs
new file mode 100644
index 000000000000..e272dc5b8787
--- /dev/null
+++ b/src/Components/Samples/IgnitorSample/Program.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Diagnostics;
+using System.Text.Json;
+using System.Threading;
+using System.Threading.Tasks;
+using Ignitor;
+using Microsoft.AspNetCore.SignalR.Client;
+
+namespace IgnitorSample
+{
+ ///
+ /// This is a minimal sample that lets you try out Ignitor against a Blazor Server app.
+ /// To use this, first launch the server app. Update the code below to point to the host url and run the test.
+ ///
+ class Program
+ {
+ private static readonly string ServerUrl = "https://localhost:5001";
+ private static readonly JsonSerializerOptions jsonSerializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web);
+
+ static async Task Main(string[] args)
+ {
+ var client = new BlazorClient();
+ await client.ConnectAsync(new Uri(ServerUrl));
+
+ await VerifyNavigationAsync(client);
+
+ Console.WriteLine("Done");
+ }
+
+ static async ValueTask VerifyNavigationAsync(BlazorClient client)
+ {
+ await client.ExpectRenderBatch(() => client.NavigateAsync($"{ServerUrl}/counter"));
+ client.Hive.TryFindElementById("counter", out var counter);
+ Debug.Assert(counter != null, "We must have navigated to counter.");
+ }
+ }
+
+ static class BlazorClientExtensions
+ {
+ public static Task NavigateAsync(this BlazorClient client, string url, CancellationToken cancellationToken = default)
+ {
+ return client.HubConnection.InvokeAsync("OnLocationChanged", url, false, cancellationToken);
+ }
+ }
+}
diff --git a/src/Components/Server/src/Builder/ComponentEndpointRouteBuilderExtensions.cs b/src/Components/Server/src/Builder/ComponentEndpointRouteBuilderExtensions.cs
index eec26e87adcb..776d2521561c 100644
--- a/src/Components/Server/src/Builder/ComponentEndpointRouteBuilderExtensions.cs
+++ b/src/Components/Server/src/Builder/ComponentEndpointRouteBuilderExtensions.cs
@@ -105,7 +105,7 @@ public static ComponentEndpointConventionBuilder MapBlazorHub(
var hubEndpoint = endpoints.MapHub(path, configureOptions);
var disconnectEndpoint = endpoints.Map(
- (path.EndsWith("/") ? path : path + "/") + "disconnect/",
+ (path.EndsWith('/') ? path : path + "/") + "disconnect/",
endpoints.CreateApplicationBuilder().UseMiddleware().Build())
.WithDisplayName("Blazor disconnect");
diff --git a/src/Components/Server/src/Circuits/CircuitHost.cs b/src/Components/Server/src/Circuits/CircuitHost.cs
index f3b34f4f5758..91222e9513cd 100644
--- a/src/Components/Server/src/Circuits/CircuitHost.cs
+++ b/src/Components/Server/src/Circuits/CircuitHost.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
@@ -112,7 +113,7 @@ public Task InitializeAsync(CancellationToken cancellationToken)
for (var i = 0; i < count; i++)
{
var (componentType, parameters, sequence) = Descriptors[i];
- await Renderer.AddComponentAsync(componentType, parameters, sequence.ToString());
+ await Renderer.AddComponentAsync(componentType, parameters, sequence.ToString(CultureInfo.InvariantCulture));
}
Log.InitializationSucceeded(_logger);
@@ -423,7 +424,7 @@ await Renderer.Dispatcher.InvokeAsync(() =>
{
// A failure in dispatching an event means that it was an attempt to use an invalid event id.
// A well-behaved client won't do this.
- Log.DispatchEventFailedToDispatchEvent(_logger, webEventData.EventHandlerId.ToString(), ex);
+ Log.DispatchEventFailedToDispatchEvent(_logger, webEventData.EventHandlerId.ToString(CultureInfo.InvariantCulture), ex);
await TryNotifyClientErrorAsync(Client, GetClientErrorMessage(ex, "Failed to dispatch event."));
UnhandledException?.Invoke(this, new UnhandledExceptionEventArgs(ex, isTerminating: false));
}
diff --git a/src/Components/Server/src/Circuits/CircuitOptionsJSInteropDetailedErrorsConfiguration.cs b/src/Components/Server/src/Circuits/CircuitOptionsJSInteropDetailedErrorsConfiguration.cs
index ac7be325234c..94c03ea58516 100644
--- a/src/Components/Server/src/Circuits/CircuitOptionsJSInteropDetailedErrorsConfiguration.cs
+++ b/src/Components/Server/src/Circuits/CircuitOptionsJSInteropDetailedErrorsConfiguration.cs
@@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
@@ -18,7 +19,9 @@ public CircuitOptionsJSInteropDetailedErrorsConfiguration(IConfiguration configu
public void Configure(CircuitOptions options)
{
- options.DetailedErrors = Configuration.GetValue(WebHostDefaults.DetailedErrorsKey);
+ var value = Configuration[WebHostDefaults.DetailedErrorsKey];
+ options.DetailedErrors = string.Equals(value, "true", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(value, "1", StringComparison.OrdinalIgnoreCase);
}
}
}
diff --git a/src/Components/Server/src/ComponentHub.cs b/src/Components/Server/src/ComponentHub.cs
index 779b4b005341..389a97ab0341 100644
--- a/src/Components/Server/src/ComponentHub.cs
+++ b/src/Components/Server/src/ComponentHub.cs
@@ -89,8 +89,8 @@ public async ValueTask StartCircuit(string baseUri, string uri, string s
if (baseUri == null ||
uri == null ||
- !Uri.IsWellFormedUriString(baseUri, UriKind.Absolute) ||
- !Uri.IsWellFormedUriString(uri, UriKind.Absolute))
+ !Uri.TryCreate(baseUri, UriKind.Absolute, out _) ||
+ !Uri.TryCreate(uri, UriKind.Absolute, out _))
{
// We do some really minimal validation here to prevent obviously wrong data from getting in
// without duplicating too much logic.
diff --git a/src/Components/Server/test/Circuits/RenderBatchWriterTest.cs b/src/Components/Server/test/Circuits/RenderBatchWriterTest.cs
index b52862bb2dc1..7fdf9231676e 100644
--- a/src/Components/Server/test/Circuits/RenderBatchWriterTest.cs
+++ b/src/Components/Server/test/Circuits/RenderBatchWriterTest.cs
@@ -1,6 +1,12 @@
// 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.Globalization;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
using Microsoft.AspNetCore.Components.RenderTree;
@@ -8,11 +14,6 @@
using Microsoft.AspNetCore.Components.Web.Rendering;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using System.Threading.Tasks;
using Xunit;
namespace Microsoft.AspNetCore.Components.Server
@@ -314,7 +315,7 @@ static void AssertBinaryContents(Span data, int startIndex, params object[
{
// Assume enums are represented as ints
var expectedEntry = expectedEntryIterationVar.GetType().IsEnum
- ? Convert.ToInt32(expectedEntryIterationVar)
+ ? Convert.ToInt32(expectedEntryIterationVar, CultureInfo.InvariantCulture)
: expectedEntryIterationVar;
if (expectedEntry is int expectedInt)
diff --git a/src/Components/Web.JS/.gitignore b/src/Components/Web.JS/.gitignore
index 10999e07926c..b1e47fe5bdee 100644
--- a/src/Components/Web.JS/.gitignore
+++ b/src/Components/Web.JS/.gitignore
@@ -1,2 +1,3 @@
node_modules/
dist/Debug/
+dist/Release/blazor.webassembly.js
diff --git a/src/Components/Web/src/Forms/InputBase.cs b/src/Components/Web/src/Forms/InputBase.cs
index cd0c790457d8..92eb780c8cdd 100644
--- a/src/Components/Web/src/Forms/InputBase.cs
+++ b/src/Components/Web/src/Forms/InputBase.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
@@ -175,7 +176,7 @@ protected string CssClass
{
if (AdditionalAttributes != null &&
AdditionalAttributes.TryGetValue("class", out var @class) &&
- !string.IsNullOrEmpty(Convert.ToString(@class)))
+ !string.IsNullOrEmpty(Convert.ToString(@class, CultureInfo.InvariantCulture)))
{
return $"{@class} {FieldClass}";
}
diff --git a/src/Components/Web/src/Forms/InputDate.cs b/src/Components/Web/src/Forms/InputDate.cs
index 9b180f76e25e..8ab564977f0c 100644
--- a/src/Components/Web/src/Forms/InputDate.cs
+++ b/src/Components/Web/src/Forms/InputDate.cs
@@ -77,7 +77,7 @@ protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(fa
}
else
{
- validationErrorMessage = string.Format(ParsingErrorMessage, DisplayName ?? FieldIdentifier.FieldName);
+ validationErrorMessage = string.Format(CultureInfo.InvariantCulture, ParsingErrorMessage, DisplayName ?? FieldIdentifier.FieldName);
return false;
}
}
diff --git a/src/Components/Web/src/Forms/InputNumber.cs b/src/Components/Web/src/Forms/InputNumber.cs
index 7c51654a855e..ed7593583008 100644
--- a/src/Components/Web/src/Forms/InputNumber.cs
+++ b/src/Components/Web/src/Forms/InputNumber.cs
@@ -64,7 +64,7 @@ protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(fa
}
else
{
- validationErrorMessage = string.Format(ParsingErrorMessage, DisplayName ?? FieldIdentifier.FieldName);
+ validationErrorMessage = string.Format(CultureInfo.InvariantCulture, ParsingErrorMessage, DisplayName ?? FieldIdentifier.FieldName);
return false;
}
}
diff --git a/src/Components/Web/src/Forms/InputRadio.cs b/src/Components/Web/src/Forms/InputRadio.cs
index 77df88376f08..f9091866ae3a 100644
--- a/src/Components/Web/src/Forms/InputRadio.cs
+++ b/src/Components/Web/src/Forms/InputRadio.cs
@@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
using Microsoft.AspNetCore.Components.Rendering;
namespace Microsoft.AspNetCore.Components.Forms
@@ -41,7 +42,7 @@ private string GetCssClass(string fieldClass)
{
if (AdditionalAttributes != null &&
AdditionalAttributes.TryGetValue("class", out var @class) &&
- !string.IsNullOrEmpty(Convert.ToString(@class)))
+ !string.IsNullOrEmpty(Convert.ToString(@class, CultureInfo.InvariantCulture)))
{
return $"{@class} {fieldClass}";
}
diff --git a/src/Components/Web/src/Routing/NavLink.cs b/src/Components/Web/src/Routing/NavLink.cs
index 05f831a89b9b..27a73318cf9c 100644
--- a/src/Components/Web/src/Routing/NavLink.cs
+++ b/src/Components/Web/src/Routing/NavLink.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Diagnostics;
using Microsoft.AspNetCore.Components.Rendering;
@@ -67,7 +68,7 @@ protected override void OnParametersSet()
var href = (string?)null;
if (AdditionalAttributes != null && AdditionalAttributes.TryGetValue("href", out var obj))
{
- href = Convert.ToString(obj);
+ href = Convert.ToString(obj, CultureInfo.InvariantCulture);
}
_hrefAbsolute = href == null ? null : NavigationManger.ToAbsoluteUri(href).AbsoluteUri;
@@ -76,7 +77,7 @@ protected override void OnParametersSet()
_class = (string?)null;
if (AdditionalAttributes != null && AdditionalAttributes.TryGetValue("class", out obj))
{
- _class = Convert.ToString(obj);
+ _class = Convert.ToString(obj, CultureInfo.InvariantCulture);
}
UpdateCssClass();
diff --git a/src/Components/Web/test/Forms/InputBaseTest.cs b/src/Components/Web/test/Forms/InputBaseTest.cs
index 6a8da5ca7666..3542a5b24403 100644
--- a/src/Components/Web/test/Forms/InputBaseTest.cs
+++ b/src/Components/Web/test/Forms/InputBaseTest.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Test.Helpers;
@@ -515,7 +516,7 @@ public async Task SetCurrentValueAsStringAsync(string value)
private class TestDateInputComponent : TestInputComponent
{
protected override string FormatValueAsString(DateTime value)
- => value.ToString("yyyy/MM/dd");
+ => value.ToString("yyyy/MM/dd", CultureInfo.InvariantCulture);
protected override bool TryParseValueFromString(string value, out DateTime result, out string validationErrorMessage)
{
diff --git a/src/Components/WebAssembly/DevServer/src/Microsoft.AspNetCore.Components.WebAssembly.DevServer.csproj b/src/Components/WebAssembly/DevServer/src/Microsoft.AspNetCore.Components.WebAssembly.DevServer.csproj
index 200328464682..4a57cc7f0bb0 100644
--- a/src/Components/WebAssembly/DevServer/src/Microsoft.AspNetCore.Components.WebAssembly.DevServer.csproj
+++ b/src/Components/WebAssembly/DevServer/src/Microsoft.AspNetCore.Components.WebAssembly.DevServer.csproj
@@ -12,24 +12,10 @@
$(NoWarn.Replace('1591', ''))false
-
-
- true
- true
-
-
-
-
+
@@ -46,5 +32,4 @@
-
diff --git a/src/Components/WebAssembly/Sdk/integrationtests/ServiceWorkerAssert.cs b/src/Components/WebAssembly/Sdk/integrationtests/ServiceWorkerAssert.cs
index a107f6bd66a7..b35dcf7dd08a 100644
--- a/src/Components/WebAssembly/Sdk/integrationtests/ServiceWorkerAssert.cs
+++ b/src/Components/WebAssembly/Sdk/integrationtests/ServiceWorkerAssert.cs
@@ -71,8 +71,8 @@ private static bool IsCompressedFile(string path)
private static AssetsManifestFile ReadServiceWorkerAssetsManifest(string assetsManifestResolvedPath)
{
var jsContents = File.ReadAllText(assetsManifestResolvedPath);
- var jsonStart = jsContents.IndexOf("{");
- var jsonLength = jsContents.LastIndexOf("}") - jsonStart + 1;
+ var jsonStart = jsContents.IndexOf('{');
+ var jsonLength = jsContents.LastIndexOf('}') - jsonStart + 1;
var json = jsContents.Substring(jsonStart, jsonLength);
return JsonSerializer.Deserialize(json);
}
diff --git a/src/Components/WebAssembly/Sdk/integrationtests/WasmBuildLazyLoadTest.cs b/src/Components/WebAssembly/Sdk/integrationtests/WasmBuildLazyLoadTest.cs
index 88a7fb842d9a..ed5572fb2ec5 100644
--- a/src/Components/WebAssembly/Sdk/integrationtests/WasmBuildLazyLoadTest.cs
+++ b/src/Components/WebAssembly/Sdk/integrationtests/WasmBuildLazyLoadTest.cs
@@ -165,6 +165,48 @@ public async Task Publish_LazyLoadExplicitAssembly_Release_Works()
Assert.Contains("blazorwasm.dll", assemblies.Keys);
}
+ [Fact]
+ public async Task Build_LazyLoadExplicitAssembly_InvalidAssembly()
+ {
+ // Arrange
+ using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary" });
+ project.Configuration = "Release";
+
+ project.AddProjectFileContent(
+@"
+
+
+
+");
+ // Act
+ var result = await MSBuildProcessManager.DotnetMSBuild(project);
+
+ // Assert
+ Assert.BuildError(result, "BLAZORSDK1001");
+ Assert.BuildFailed(result);
+ }
+
+ [Fact]
+ public async Task Publish_LazyLoadExplicitAssembly_InvalidAssembly()
+ {
+ // Arrange
+ using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary" });
+ project.Configuration = "Release";
+
+ project.AddProjectFileContent(
+@"
+
+
+
+");
+ // Act
+ var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish");
+
+ // Assert
+ Assert.BuildError(result, "BLAZORSDK1001");
+ Assert.BuildFailed(result);
+ }
+
private static BootJsonData ReadBootJsonData(MSBuildResult result, string path)
{
return JsonSerializer.Deserialize(
diff --git a/src/Components/WebAssembly/Sdk/src/targets/Microsoft.NET.Sdk.BlazorWebAssembly.Current.targets b/src/Components/WebAssembly/Sdk/src/targets/Microsoft.NET.Sdk.BlazorWebAssembly.Current.targets
index 0f9a3d9c2b55..66ac6e99d989 100644
--- a/src/Components/WebAssembly/Sdk/src/targets/Microsoft.NET.Sdk.BlazorWebAssembly.Current.targets
+++ b/src/Components/WebAssembly/Sdk/src/targets/Microsoft.NET.Sdk.BlazorWebAssembly.Current.targets
@@ -284,9 +284,15 @@ Copyright (c) .NET Foundation. All rights reserved.
<_BlazorBuildBootJsonPath>$(IntermediateOutputPath)blazor.boot.json
+ <_BlazorOutputContent>@(_BlazorOutputWithHash)
<_BlazorWebAssemblyLoadAllGlobalizationData Condition="'$(BlazorWebAssemblyLoadAllGlobalizationData)' == ''">false
+
+
+
+ <_BlazorOutputContent>@(_BlazorPublishBootResourceWithHash)
+
+
+
+
false
- net5.0
-
$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)..\, 'AspNetCore.sln'))\$(RepoRoot)src\Razor\Microsoft.NET.Sdk.Razor\src\build\netstandard2.0\Sdk.Razor.CurrentVersion.props
diff --git a/src/Components/WebAssembly/Server/src/DebugProxyLauncher.cs b/src/Components/WebAssembly/Server/src/DebugProxyLauncher.cs
index 58f6b260251b..53db2fb5e344 100644
--- a/src/Components/WebAssembly/Server/src/DebugProxyLauncher.cs
+++ b/src/Components/WebAssembly/Server/src/DebugProxyLauncher.cs
@@ -77,7 +77,7 @@ private static void RemoveUnwantedEnvironmentVariables(IDictionary key.StartsWith("ASPNETCORE_")).ToList();
+ var keysToRemove = environment.Keys.Where(key => key.StartsWith("ASPNETCORE_", StringComparison.Ordinal)).ToList();
foreach (var key in keysToRemove)
{
environment.Remove(key);
diff --git a/src/Components/WebAssembly/Server/src/TargetPickerUi.cs b/src/Components/WebAssembly/Server/src/TargetPickerUi.cs
index fda22452d27f..5ce4d4ea2ea5 100644
--- a/src/Components/WebAssembly/Server/src/TargetPickerUi.cs
+++ b/src/Components/WebAssembly/Server/src/TargetPickerUi.cs
@@ -9,6 +9,7 @@
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Text.Json;
+using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
@@ -23,7 +24,7 @@ public class TargetPickerUi
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
PropertyNameCaseInsensitive = true,
- IgnoreNullValues = true
+ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
private string _browserHost;
diff --git a/src/Components/WebAssembly/WebAssembly.Authentication/src/RemoteAuthenticatorViewCore.cs b/src/Components/WebAssembly/WebAssembly.Authentication/src/RemoteAuthenticatorViewCore.cs
index 30763ce44aca..f285301e9e6a 100644
--- a/src/Components/WebAssembly/WebAssembly.Authentication/src/RemoteAuthenticatorViewCore.cs
+++ b/src/Components/WebAssembly/WebAssembly.Authentication/src/RemoteAuthenticatorViewCore.cs
@@ -339,7 +339,7 @@ private string GetReturnUrl(TAuthenticationState state, string defaultReturnUrl
}
var fromQuery = QueryStringHelper.GetParameter(new Uri(Navigation.Uri).Query, "returnUrl");
- if (!string.IsNullOrWhiteSpace(fromQuery) && !fromQuery.StartsWith(Navigation.BaseUri))
+ if (!string.IsNullOrWhiteSpace(fromQuery) && !fromQuery.StartsWith(Navigation.BaseUri, StringComparison.Ordinal))
{
// This is an extra check to prevent open redirects.
throw new InvalidOperationException("Invalid return url. The return url needs to have the same origin as the current page.");
diff --git a/src/Components/WebAssembly/WebAssembly.Authentication/test/WebAssemblyAuthenticationServiceCollectionExtensionsTests.cs b/src/Components/WebAssembly/WebAssembly.Authentication/test/WebAssemblyAuthenticationServiceCollectionExtensionsTests.cs
index d9996a124d7f..e05a55b76c02 100644
--- a/src/Components/WebAssembly/WebAssembly.Authentication/test/WebAssemblyAuthenticationServiceCollectionExtensionsTests.cs
+++ b/src/Components/WebAssembly/WebAssembly.Authentication/test/WebAssemblyAuthenticationServiceCollectionExtensionsTests.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Globalization;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
@@ -366,7 +367,7 @@ public void AddOidc_CustomState_SetsUpConfiguration()
var builder = new WebAssemblyHostBuilder(new TestWebAssemblyJSRuntimeInvoker());
var calls = 0;
- builder.Services.AddOidcAuthentication(options => options.ProviderOptions.Authority = (++calls).ToString());
+ builder.Services.AddOidcAuthentication(options => options.ProviderOptions.Authority = (++calls).ToString(CultureInfo.InvariantCulture));
builder.Services.Replace(ServiceDescriptor.Singleton(typeof(NavigationManager), new TestNavigationManager()));
var host = builder.Build();
@@ -388,7 +389,7 @@ public void AddOidc_CustomStateAndAccount_SetsUpConfiguration()
var builder = new WebAssemblyHostBuilder(new TestWebAssemblyJSRuntimeInvoker());
var calls = 0;
- builder.Services.AddOidcAuthentication(options => options.ProviderOptions.Authority = (++calls).ToString());
+ builder.Services.AddOidcAuthentication(options => options.ProviderOptions.Authority = (++calls).ToString(CultureInfo.InvariantCulture));
builder.Services.Replace(ServiceDescriptor.Singleton(typeof(NavigationManager), new TestNavigationManager()));
var host = builder.Build();
diff --git a/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs b/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs
index 9e6215c70a75..8861ece33e8d 100644
--- a/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs
+++ b/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Globalization;
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Components.Routing;
@@ -86,7 +87,7 @@ private void InitializeRegisteredRootComponents(WebAssemblyJSRuntimeInvoker jsRu
var typeName = jsRuntimeInvoker.InvokeUnmarshalled(RegisteredComponentsInterop.GetTypeName, id, null, null);
var serializedParameterDefinitions = jsRuntimeInvoker.InvokeUnmarshalled(RegisteredComponentsInterop.GetParameterDefinitions, id, null, null);
var serializedParameterValues = jsRuntimeInvoker.InvokeUnmarshalled(RegisteredComponentsInterop.GetParameterValues, id, null, null);
- registeredComponents[i] = new WebAssemblyComponentMarker(WebAssemblyComponentMarker.ClientMarkerType, assembly, typeName, serializedParameterDefinitions, serializedParameterValues, id.ToString());
+ registeredComponents[i] = new WebAssemblyComponentMarker(WebAssemblyComponentMarker.ClientMarkerType, assembly, typeName, serializedParameterDefinitions, serializedParameterValues, id.ToString(CultureInfo.InvariantCulture));
}
var componentDeserializer = WebAssemblyComponentParameterDeserializer.Instance;
diff --git a/src/Components/WebAssembly/WebAssembly/src/Services/DefaultWebAssemblyJSRuntime.cs b/src/Components/WebAssembly/WebAssembly/src/Services/DefaultWebAssemblyJSRuntime.cs
index a9820985ebc6..6ae0c7a02d2f 100644
--- a/src/Components/WebAssembly/WebAssembly/src/Services/DefaultWebAssemblyJSRuntime.cs
+++ b/src/Components/WebAssembly/WebAssembly/src/Services/DefaultWebAssemblyJSRuntime.cs
@@ -1,6 +1,7 @@
// 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.Globalization;
using Microsoft.JSInterop.Infrastructure;
using Microsoft.JSInterop.WebAssembly;
@@ -21,7 +22,7 @@ private DefaultWebAssemblyJSRuntime()
#pragma warning disable IDE0051 // Remove unused private members. Invoked via Mono's JS interop mechanism (invoke_method)
private static string InvokeDotNet(string assemblyName, string methodIdentifier, string dotNetObjectId, string argsJson)
{
- var callInfo = new DotNetInvocationInfo(assemblyName, methodIdentifier, dotNetObjectId == null ? default : long.Parse(dotNetObjectId), callId: null);
+ var callInfo = new DotNetInvocationInfo(assemblyName, methodIdentifier, dotNetObjectId == null ? default : long.Parse(dotNetObjectId, CultureInfo.InvariantCulture), callId: null);
return DotNetDispatcher.Invoke(Instance, callInfo, argsJson);
}
@@ -39,7 +40,7 @@ private static void BeginInvokeDotNet(string callId, string assemblyNameOrDotNet
long dotNetObjectId;
if (char.IsDigit(assemblyNameOrDotNetObjectId[0]))
{
- dotNetObjectId = long.Parse(assemblyNameOrDotNetObjectId);
+ dotNetObjectId = long.Parse(assemblyNameOrDotNetObjectId, CultureInfo.InvariantCulture);
assemblyName = null;
}
else
diff --git a/src/Components/WebAssembly/WebAssembly/test/Hosting/WebAssemblyHostConfigurationTest.cs b/src/Components/WebAssembly/WebAssembly/test/Hosting/WebAssemblyHostConfigurationTest.cs
index 922293fa0a3a..ac1550db3616 100644
--- a/src/Components/WebAssembly/WebAssembly/test/Hosting/WebAssemblyHostConfigurationTest.cs
+++ b/src/Components/WebAssembly/WebAssembly/test/Hosting/WebAssemblyHostConfigurationTest.cs
@@ -211,7 +211,7 @@ public void NewConfigurationProviderOverridesOldOneWhenKeyIsDuplicated()
private class CustomizedTestConfigurationProvider : ConfigurationProvider
{
public CustomizedTestConfigurationProvider(string key, string value)
- => Data.Add(key, value.ToUpper());
+ => Data.Add(key, value.ToUpperInvariant());
public override void Set(string key, string value)
{
diff --git a/src/Components/WebAssembly/testassets/HostedInAspNet.Server/Startup.cs b/src/Components/WebAssembly/testassets/HostedInAspNet.Server/Startup.cs
index 66b236ddf8ed..7bf7c69171aa 100644
--- a/src/Components/WebAssembly/testassets/HostedInAspNet.Server/Startup.cs
+++ b/src/Components/WebAssembly/testassets/HostedInAspNet.Server/Startup.cs
@@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
@@ -26,7 +27,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, BootReso
// and that it was possible to override the loading mechanism
if (context.Request.Query.ContainsKey("customizedbootresource")
|| context.Request.Headers.ContainsKey("customizedbootresource")
- || context.Request.Path.Value.EndsWith("/blazor.boot.json"))
+ || context.Request.Path.Value.EndsWith("/blazor.boot.json", StringComparison.Ordinal))
{
bootResourceRequestLog.AddRequest(context.Request);
}
diff --git a/src/Components/benchmarkapps/Wasm.Performance/ConsoleHost/Scenarios/ComponentRenderingScenarioBase.cs b/src/Components/benchmarkapps/Wasm.Performance/ConsoleHost/Scenarios/ComponentRenderingScenarioBase.cs
index bf5cbc5d833c..55705c91c2bd 100644
--- a/src/Components/benchmarkapps/Wasm.Performance/ConsoleHost/Scenarios/ComponentRenderingScenarioBase.cs
+++ b/src/Components/benchmarkapps/Wasm.Performance/ConsoleHost/Scenarios/ComponentRenderingScenarioBase.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Globalization;
using System.Threading.Tasks;
using Microsoft.Extensions.CommandLineUtils;
using Microsoft.Extensions.DependencyInjection;
@@ -20,7 +21,7 @@ protected ComponentRenderingScenarioBase(string name)
OnExecute(() =>
{
- var numCycles = cyclesOption.HasValue() ? int.Parse(cyclesOption.Value()) : 1;
+ var numCycles = cyclesOption.HasValue() ? int.Parse(cyclesOption.Value(), CultureInfo.InvariantCulture) : 1;
var serviceCollection = new ServiceCollection();
PopulateServiceCollection(serviceCollection);
diff --git a/src/Components/test/E2ETest/Infrastructure/ServerFixtures/ServerFixture.cs b/src/Components/test/E2ETest/Infrastructure/ServerFixtures/ServerFixture.cs
index 1b1ed2a70286..57234090223f 100644
--- a/src/Components/test/E2ETest/Infrastructure/ServerFixtures/ServerFixture.cs
+++ b/src/Components/test/E2ETest/Infrastructure/ServerFixtures/ServerFixture.cs
@@ -41,7 +41,7 @@ public ServerFixture()
private static Dictionary FindProjects()
{
return typeof(ServerFixture).Assembly.GetCustomAttributes()
- .Where(m => m.Key.StartsWith("TestAssemblyApplication["))
+ .Where(m => m.Key.StartsWith("TestAssemblyApplication[", StringComparison.Ordinal))
.ToDictionary(m =>
m.Key.Replace("TestAssemblyApplication", "").TrimStart('[').TrimEnd(']'),
m => m.Value);
diff --git a/src/Components/test/E2ETest/Infrastructure/WebDriverExtensions/BasicTestAppAuthenticationWebDriverExtensions.cs b/src/Components/test/E2ETest/Infrastructure/WebDriverExtensions/BasicTestAppAuthenticationWebDriverExtensions.cs
index 8fec725d9b90..938e8508d1db 100644
--- a/src/Components/test/E2ETest/Infrastructure/WebDriverExtensions/BasicTestAppAuthenticationWebDriverExtensions.cs
+++ b/src/Components/test/E2ETest/Infrastructure/WebDriverExtensions/BasicTestAppAuthenticationWebDriverExtensions.cs
@@ -9,7 +9,7 @@ internal static class BasicTestAppAuthenticationWebDriverExtensions
{
public static void SignInAs(this IWebDriver browser, Uri baseUri, string usernameOrNull, string rolesOrNull, bool useSeparateTab = false)
{
- var basePath = baseUri.LocalPath.EndsWith("/") ? baseUri.LocalPath : baseUri.LocalPath + "/";
+ var basePath = baseUri.LocalPath.EndsWith("/", StringComparison.Ordinal) ? baseUri.LocalPath : baseUri.LocalPath + "/";
var authenticationPageUrl = $"{basePath}Authentication";
var baseRelativeUri = usernameOrNull == null
? $"{authenticationPageUrl}?signout=true"
diff --git a/src/Components/test/E2ETest/ServerExecutionTests/ServerGlobalizationTest.cs b/src/Components/test/E2ETest/ServerExecutionTests/ServerGlobalizationTest.cs
index 53f7a0c80526..0dae5ec04342 100644
--- a/src/Components/test/E2ETest/ServerExecutionTests/ServerGlobalizationTest.cs
+++ b/src/Components/test/E2ETest/ServerExecutionTests/ServerGlobalizationTest.cs
@@ -34,7 +34,6 @@ protected override void InitializeAsyncCore()
Browser.Exists(By.Id("culture-selector"));
}
- [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/24692")]
[Theory]
[InlineData("en-US")]
[InlineData("fr-FR")]
diff --git a/src/Components/test/E2ETest/Tests/BindTest.cs b/src/Components/test/E2ETest/Tests/BindTest.cs
index ea5a0265d035..f6f21b199c54 100644
--- a/src/Components/test/E2ETest/Tests/BindTest.cs
+++ b/src/Components/test/E2ETest/Tests/BindTest.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Globalization;
using System.Text.Json;
using BasicTestApp;
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure;
@@ -389,7 +390,6 @@ public void CanBindTextboxShort()
}
[Fact]
- [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23826")]
public void CanBindTextboxNullableShort()
{
var target = Browser.Exists(By.Id("textbox-nullable-short"));
@@ -512,7 +512,6 @@ public void CanBindTextboxDouble()
}
[Fact]
- [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23596")]
public void CanBindTextboxNullableDouble()
{
var target = Browser.Exists(By.Id("textbox-nullable-double"));
@@ -612,7 +611,6 @@ public void CanBindTextboxNullableDecimal()
// This tests what happens you put invalid (unconvertable) input in. This is separate from the
// other tests because it requires type="text" - the other tests use type="number"
[Fact]
- [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/24756")]
public void CanBindTextbox_Decimal_InvalidInput()
{
var target = Browser.Exists(By.Id("textbox-decimal-invalid"));
@@ -731,23 +729,23 @@ public void CanBindTextboxDateTime()
var boundValue = Browser.Exists(By.Id("textbox-datetime-value"));
var mirrorValue = Browser.Exists(By.Id("textbox-datetime-mirror"));
var expected = new DateTime(1985, 3, 4);
- Assert.Equal(expected, DateTime.Parse(target.GetAttribute("value")));
- Assert.Equal(expected, DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Assert.Equal(expected, DateTime.Parse(target.GetAttribute("value"), CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Clear textbox; value updates to 01/01/0001 because that's the default
target.Clear();
expected = default;
- Browser.Equal(expected, () => DateTime.Parse(target.GetAttribute("value")));
- Assert.Equal(expected, DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTime.Parse(target.GetAttribute("value"), CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Modify target; verify value is updated and that textboxes linked to the same data are updated
target.SendKeys(Keys.Control + "a"); // select all
target.SendKeys("01/02/2000 00:00:00\t");
expected = new DateTime(2000, 1, 2);
- Browser.Equal(expected, () => DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
}
// For date comparisons, we parse (non-formatted) values to compare them. Client-side and server-side
@@ -770,8 +768,8 @@ public void CanBindTextboxNullableDateTime()
// Modify target; verify value is updated and that textboxes linked to the same data are updated
var expected = new DateTime(2000, 1, 2);
target.SendKeys("01/02/2000 00:00:00\t");
- Browser.Equal(expected, () => DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Modify target; verify value is updated and that textboxes linked to the same data are updated
target.Clear();
@@ -789,23 +787,23 @@ public void CanBindTextboxDateTimeOffset()
var boundValue = Browser.Exists(By.Id("textbox-datetimeoffset-value"));
var mirrorValue = Browser.Exists(By.Id("textbox-datetimeoffset-mirror"));
var expected = new DateTimeOffset(new DateTime(1985, 3, 4), TimeSpan.FromHours(8));
- Assert.Equal(expected, DateTimeOffset.Parse(target.GetAttribute("value")));
- Assert.Equal(expected, DateTimeOffset.Parse(boundValue.Text));
- Assert.Equal(expected, DateTimeOffset.Parse(mirrorValue.GetAttribute("value")));
+ Assert.Equal(expected, DateTimeOffset.Parse(target.GetAttribute("value"), CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTimeOffset.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTimeOffset.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Clear textbox; value updates to 01/01/0001 because that's the default
target.Clear();
expected = default;
- Browser.Equal(expected, () => DateTimeOffset.Parse(target.GetAttribute("value")));
- Assert.Equal(expected, DateTimeOffset.Parse(boundValue.Text));
- Assert.Equal(expected, DateTimeOffset.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTimeOffset.Parse(target.GetAttribute("value"), CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTimeOffset.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTimeOffset.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Modify target; verify value is updated and that textboxes linked to the same data are updated
target.SendKeys(Keys.Control + "a"); // select all
target.SendKeys("01/02/2000 00:00:00 +08:00\t");
expected = new DateTimeOffset(new DateTime(2000, 1, 2), TimeSpan.FromHours(8));
- Browser.Equal(expected, () => DateTimeOffset.Parse(boundValue.Text));
- Assert.Equal(expected, DateTimeOffset.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTimeOffset.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTimeOffset.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
}
// For date comparisons, we parse (non-formatted) values to compare them. Client-side and server-side
@@ -828,8 +826,8 @@ public void CanBindTextboxNullableDateTimeOffset()
// Modify target; verify value is updated and that textboxes linked to the same data are updated
target.SendKeys("01/02/2000 00:00:00 +08:00" + "\t");
var expected = new DateTimeOffset(new DateTime(2000, 1, 2), TimeSpan.FromHours(8));
- Browser.Equal(expected, () => DateTimeOffset.Parse(boundValue.Text));
- Assert.Equal(expected, DateTimeOffset.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTimeOffset.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTimeOffset.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Modify target; verify value is updated and that textboxes linked to the same data are updated
target.Clear();
@@ -848,23 +846,23 @@ public void CanBindTextboxDateTimeWithFormat()
var mirrorValue = Browser.Exists(By.Id("textbox-datetime-format-mirror"));
var expected = new DateTime(1985, 3, 4);
Assert.Equal("03-04", target.GetAttribute("value"));
- Assert.Equal(expected, DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Assert.Equal(expected, DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Clear textbox; value updates to the default
target.Clear();
target.SendKeys("\t");
expected = default;
Browser.Equal("01-01", () => target.GetAttribute("value"));
- Assert.Equal(expected, DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Assert.Equal(expected, DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Modify target; verify value is updated and that textboxes linked to the same data are updated
target.SendKeys(Keys.Control + "a"); // select all
target.SendKeys("01-02\t");
expected = new DateTime(DateTime.Now.Year, 1, 2);
- Browser.Equal(expected, () => DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
}
// For date comparisons, we parse (non-formatted) values to compare them. Client-side and server-side
@@ -887,8 +885,8 @@ public void CanBindTextboxNullableDateTimeWithFormat()
// Modify target; verify value is updated and that textboxes linked to the same data are updated
target.SendKeys("01-02\t");
var expected = new DateTime(DateTime.Now.Year, 1, 2);
- Browser.Equal(expected, () => DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Modify target; verify value is updated and that textboxes linked to the same data are updated
target.Clear();
@@ -907,22 +905,22 @@ public void CanBindTextboxDateTimeOffsetWithFormat()
var mirrorValue = Browser.Exists(By.Id("textbox-datetimeoffset-format-mirror"));
var expected = new DateTimeOffset(new DateTime(1985, 3, 4), TimeSpan.FromHours(8));
Assert.Equal("03-04", target.GetAttribute("value"));
- Assert.Equal(expected, DateTimeOffset.Parse(boundValue.Text));
- Assert.Equal(expected, DateTimeOffset.Parse(mirrorValue.GetAttribute("value")));
+ Assert.Equal(expected, DateTimeOffset.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTimeOffset.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Clear textbox; value updates to the default
target.Clear();
expected = default;
Browser.Equal("01-01", () => target.GetAttribute("value"));
- Assert.Equal(expected, DateTimeOffset.Parse(boundValue.Text));
- Assert.Equal(expected, DateTimeOffset.Parse(mirrorValue.GetAttribute("value")));
+ Assert.Equal(expected, DateTimeOffset.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTimeOffset.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Modify target; verify value is updated and that textboxes linked to the same data are updated
target.SendKeys(Keys.Control + "a"); // select all
target.SendKeys("01-02\t");
expected = new DateTimeOffset(new DateTime(DateTime.Now.Year, 1, 2), TimeSpan.FromHours(0));
- Browser.Equal(expected.DateTime, () => DateTimeOffset.Parse(boundValue.Text).DateTime);
- Assert.Equal(expected.DateTime, DateTimeOffset.Parse(mirrorValue.GetAttribute("value")).DateTime);
+ Browser.Equal(expected.DateTime, () => DateTimeOffset.Parse(boundValue.Text, CultureInfo.InvariantCulture).DateTime);
+ Assert.Equal(expected.DateTime, DateTimeOffset.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture).DateTime);
}
// For date comparisons, we parse (non-formatted) values to compare them. Client-side and server-side
@@ -948,8 +946,8 @@ public void CanBindTextboxNullableDateTimeOffsetWithFormat()
// Modify target; verify value is updated and that textboxes linked to the same data are updated
target.SendKeys("01-02" + "\t");
var expected = new DateTimeOffset(new DateTime(DateTime.Now.Year, 1, 2), TimeSpan.FromHours(0));
- Browser.Equal(expected.DateTime, () => DateTimeOffset.Parse(boundValue.Text).DateTime);
- Assert.Equal(expected.DateTime, DateTimeOffset.Parse(mirrorValue.GetAttribute("value")).DateTime);
+ Browser.Equal(expected.DateTime, () => DateTimeOffset.Parse(boundValue.Text, CultureInfo.InvariantCulture).DateTime);
+ Assert.Equal(expected.DateTime, DateTimeOffset.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture).DateTime);
// Modify target; verify value is updated and that textboxes linked to the same data are updated
target.Clear();
@@ -973,8 +971,8 @@ public void CanBindTextboxNullableDateTime_InvalidValue()
// Modify target; verify value is updated and that textboxes linked to the same data are updated
var expected = new DateTime(2000, 1, 2);
target.SendKeys("01/02/2000 00:00:00\t");
- Browser.Equal(expected, () => DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Modify target to something invalid - the invalid change is reverted
// back to the last valid value
@@ -982,16 +980,16 @@ public void CanBindTextboxNullableDateTime_InvalidValue()
target.SendKeys("05/06X");
Browser.Equal("05/06X", () => target.GetAttribute("value"));
target.SendKeys("\t");
- Browser.Equal(expected, () => DateTime.Parse(target.GetAttribute("value")));
- Assert.Equal(expected, DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTime.Parse(target.GetAttribute("value"), CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Now change it to something valid
target.SendKeys(Keys.Control + "a"); // select all
target.SendKeys("05/06\t");
expected = new DateTime(DateTime.Now.Year, 5, 6);
- Browser.Equal(expected, () => DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
}
// For date comparisons, we parse (non-formatted) values to compare them. Client-side and server-side
@@ -1003,16 +1001,16 @@ public void CanBindTextboxDateTimeOffset_InvalidValue()
var boundValue = Browser.Exists(By.Id("textbox-datetimeoffset-invalid-value"));
var mirrorValue = Browser.Exists(By.Id("textbox-datetimeoffset-invalid-mirror"));
var expected = new DateTimeOffset(new DateTime(1985, 3, 4), TimeSpan.FromHours(8));
- Assert.Equal(expected, DateTimeOffset.Parse(target.GetAttribute("value")));
- Assert.Equal(expected, DateTimeOffset.Parse(boundValue.Text));
- Assert.Equal(expected, DateTimeOffset.Parse(mirrorValue.GetAttribute("value")));
+ Assert.Equal(expected, DateTimeOffset.Parse(target.GetAttribute("value"), CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTimeOffset.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTimeOffset.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Modify target; verify value is updated and that textboxes linked to the same data are updated
expected = new DateTime(2000, 1, 2);
target.SendKeys(Keys.Control + "a"); // select all
target.SendKeys("01/02/2000 00:00:00\t");
- Browser.Equal(expected.DateTime, () => DateTimeOffset.Parse(boundValue.Text).DateTime);
- Assert.Equal(expected.DateTime, DateTimeOffset.Parse(mirrorValue.GetAttribute("value")).DateTime);
+ Browser.Equal(expected.DateTime, () => DateTimeOffset.Parse(boundValue.Text, CultureInfo.InvariantCulture).DateTime);
+ Assert.Equal(expected.DateTime, DateTimeOffset.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture).DateTime);
// Modify target to something invalid - the invalid change is reverted
// back to the last valid value
@@ -1020,16 +1018,16 @@ public void CanBindTextboxDateTimeOffset_InvalidValue()
target.SendKeys("05/06X");
Browser.Equal("05/06X", () => target.GetAttribute("value"));
target.SendKeys("\t");
- Browser.Equal(expected.DateTime, () => DateTimeOffset.Parse(target.GetAttribute("value")).DateTime);
- Assert.Equal(expected.DateTime, DateTimeOffset.Parse(boundValue.Text).DateTime);
- Assert.Equal(expected.DateTime, DateTimeOffset.Parse(mirrorValue.GetAttribute("value")).DateTime);
+ Browser.Equal(expected.DateTime, () => DateTimeOffset.Parse(target.GetAttribute("value"), CultureInfo.InvariantCulture).DateTime);
+ Assert.Equal(expected.DateTime, DateTimeOffset.Parse(boundValue.Text, CultureInfo.InvariantCulture).DateTime);
+ Assert.Equal(expected.DateTime, DateTimeOffset.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture).DateTime);
// Now change it to something valid
target.SendKeys(Keys.Control + "a"); // select all
target.SendKeys("05/06\t");
expected = new DateTime(DateTime.Now.Year, 5, 6);
- Browser.Equal(expected.DateTime, () => DateTimeOffset.Parse(boundValue.Text).DateTime);
- Assert.Equal(expected.DateTime, DateTimeOffset.Parse(mirrorValue.GetAttribute("value")).DateTime);
+ Browser.Equal(expected.DateTime, () => DateTimeOffset.Parse(boundValue.Text, CultureInfo.InvariantCulture).DateTime);
+ Assert.Equal(expected.DateTime, DateTimeOffset.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture).DateTime);
}
// For date comparisons, we parse (non-formatted) values to compare them. Client-side and server-side
@@ -1042,8 +1040,8 @@ public void CanBindTextboxDateTimeWithFormat_InvalidValue()
var mirrorValue = Browser.Exists(By.Id("textbox-datetime-format-invalid-mirror"));
var expected = new DateTime(1985, 3, 4);
Assert.Equal("03-04", target.GetAttribute("value"));
- Assert.Equal(expected, DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Assert.Equal(expected, DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Modify target to something invalid - the invalid change is reverted
// back to the last valid value
@@ -1052,15 +1050,15 @@ public void CanBindTextboxDateTimeWithFormat_InvalidValue()
Browser.Equal("05/06", () => target.GetAttribute("value"));
target.SendKeys("\t");
Browser.Equal("03-04", () => target.GetAttribute("value"));
- Assert.Equal(expected, DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Assert.Equal(expected, DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Now change it to something valid
target.SendKeys(Keys.Control + "a"); // select all
target.SendKeys("05-06\t");
expected = new DateTime(DateTime.Now.Year, 5, 6);
- Browser.Equal(expected, () => DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
}
// For date comparisons, we parse (non-formatted) values to compare them. Client-side and server-side
@@ -1079,8 +1077,8 @@ public void CanBindTextboxNullableDateTimeOffsetWithFormat_InvalidValue()
var expected = new DateTimeOffset(new DateTime(DateTime.Now.Year, 1, 2));
target.SendKeys(Keys.Control + "a"); // select all
target.SendKeys("01-02\t");
- Browser.Equal(expected.DateTime, () => DateTimeOffset.Parse(boundValue.Text).DateTime);
- Assert.Equal(expected.DateTime, DateTimeOffset.Parse(mirrorValue.GetAttribute("value")).DateTime);
+ Browser.Equal(expected.DateTime, () => DateTimeOffset.Parse(boundValue.Text, CultureInfo.InvariantCulture).DateTime);
+ Assert.Equal(expected.DateTime, DateTimeOffset.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture).DateTime);
// Modify target to something invalid - the invalid change is reverted
// back to the last valid value
@@ -1088,16 +1086,16 @@ public void CanBindTextboxNullableDateTimeOffsetWithFormat_InvalidValue()
target.SendKeys("05/06");
Browser.Equal("05/06", () => target.GetAttribute("value"));
target.SendKeys("\t");
- Browser.Equal(expected.DateTime, () => DateTimeOffset.Parse(target.GetAttribute("value")).DateTime);
- Assert.Equal(expected.DateTime, DateTimeOffset.Parse(boundValue.Text).DateTime);
- Assert.Equal(expected.DateTime, DateTimeOffset.Parse(mirrorValue.GetAttribute("value")).DateTime);
+ Browser.Equal(expected.DateTime, () => DateTimeOffset.Parse(target.GetAttribute("value"), CultureInfo.InvariantCulture).DateTime);
+ Assert.Equal(expected.DateTime, DateTimeOffset.Parse(boundValue.Text, CultureInfo.InvariantCulture).DateTime);
+ Assert.Equal(expected.DateTime, DateTimeOffset.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture).DateTime);
// Now change it to something valid
target.SendKeys(Keys.Control + "a"); // select all
target.SendKeys("05-06\t");
expected = new DateTime(DateTime.Now.Year, 5, 6);
- Browser.Equal(expected.DateTime, () => DateTimeOffset.Parse(boundValue.Text).DateTime);
- Assert.Equal(expected.DateTime, DateTimeOffset.Parse(mirrorValue.GetAttribute("value")).DateTime);
+ Browser.Equal(expected.DateTime, () => DateTimeOffset.Parse(boundValue.Text, CultureInfo.InvariantCulture).DateTime);
+ Assert.Equal(expected.DateTime, DateTimeOffset.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture).DateTime);
}
// For date comparisons, we parse (non-formatted) values to compare them. Client-side and server-side
@@ -1109,23 +1107,23 @@ public void CanBindDateTimeLocalTextboxDateTime()
var boundValue = Browser.Exists(By.Id("datetime-local-textbox-datetime-value"));
var mirrorValue = Browser.Exists(By.Id("datetime-local-textbox-datetime-mirror"));
var expected = new DateTime(1985, 3, 4);
- Assert.Equal(expected, DateTime.Parse(target.GetAttribute("value")));
- Assert.Equal(expected, DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Assert.Equal(expected, DateTime.Parse(target.GetAttribute("value"), CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Clear textbox; value updates to 01/01/0001 because that's the default
target.Clear();
expected = default;
- Browser.Equal(expected, () => DateTime.Parse(target.GetAttribute("value")));
- Assert.Equal(expected, DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTime.Parse(target.GetAttribute("value"), CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// We have to do it this way because the browser gets in the way when sending keys to the input
// element directly.
ApplyInputValue("#datetime-local-textbox-datetime", "2000-01-02T04:05:06");
expected = new DateTime(2000, 1, 2, 04, 05, 06);
- Browser.Equal(expected, () => DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
}
// For date comparisons, we parse (non-formatted) values to compare them. Client-side and server-side
@@ -1150,8 +1148,8 @@ public void CanBindDateTimeLocalTextboxNullableDateTime()
// element directly.
ApplyInputValue("#datetime-local-textbox-nullable-datetime", "2000-01-02T04:05:06");
var expected = new DateTime(2000, 1, 2, 04, 05, 06);
- Browser.Equal(expected, () => DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Modify target; verify value is updated and that textboxes linked to the same data are updated
target.Clear();
@@ -1169,25 +1167,25 @@ public void CanBindMonthTextboxDateTime()
var boundValue = Browser.Exists(By.Id("month-textbox-datetime-value"));
var mirrorValue = Browser.Exists(By.Id("month-textbox-datetime-mirror"));
var expected = new DateTime(1985, 3, 1);
- Assert.Equal(expected, DateTime.Parse(target.GetAttribute("value")));
+ Assert.Equal(expected, DateTime.Parse(target.GetAttribute("value"), CultureInfo.InvariantCulture));
// When the value gets displayed the first time it gets truncated to the 1st day,
// until there is no change the bound value doesn't get updated.
- Assert.Equal(expected.AddDays(3), DateTime.Parse(boundValue.Text));
- Assert.Equal(expected.AddDays(3), DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Assert.Equal(expected.AddDays(3), DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected.AddDays(3), DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Clear textbox; value updates to 01/01/0001 because that's the default
target.Clear();
expected = default;
- Browser.Equal(expected, () => DateTime.Parse(target.GetAttribute("value")));
- Assert.Equal(expected, DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTime.Parse(target.GetAttribute("value"), CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// We have to do it this way because the browser gets in the way when sending keys to the input
// element directly.
ApplyInputValue("#month-textbox-datetime", "2000-02");
expected = new DateTime(2000, 2, 1);
- Browser.Equal(expected, () => DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
}
// For date comparisons, we parse (non-formatted) values to compare them. Client-side and server-side
@@ -1212,8 +1210,8 @@ public void CanBindMonthTextboxNullableDateTime()
// element directly.
ApplyInputValue("#month-textbox-nullable-datetime", "2000-02");
var expected = new DateTime(2000, 2, 1);
- Browser.Equal(expected, () => DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Modify target; verify value is updated and that textboxes linked to the same data are updated
target.Clear();
@@ -1231,23 +1229,23 @@ public void CanBindTimeTextboxDateTime()
var boundValue = Browser.Exists(By.Id("time-textbox-datetime-value"));
var mirrorValue = Browser.Exists(By.Id("time-textbox-datetime-mirror"));
var expected = DateTime.Now.Date.AddHours(8).AddMinutes(5);
- Assert.Equal(expected, DateTime.Parse(target.GetAttribute("value")));
- Assert.Equal(expected, DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Assert.Equal(expected, DateTime.Parse(target.GetAttribute("value"), CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Clear textbox; value updates to 00:00 because that's the default
target.Clear();
expected = default;
- Browser.Equal(DateTime.Now.Date, () => DateTime.Parse(target.GetAttribute("value")));
- Assert.Equal(default, DateTime.Parse(boundValue.Text));
- Assert.Equal(default, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(DateTime.Now.Date, () => DateTime.Parse(target.GetAttribute("value"), CultureInfo.InvariantCulture));
+ Assert.Equal(default, DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(default, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// We have to do it this way because the browser gets in the way when sending keys to the input
// element directly.
ApplyInputValue("#time-textbox-datetime", "04:05");
expected = DateTime.Now.Date.Add(new TimeSpan(4, 5, 0));
- Browser.Equal(expected, () => DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
}
// For date comparisons, we parse (non-formatted) values to compare them. Client-side and server-side
@@ -1272,8 +1270,8 @@ public void CanBindTimeTextboxNullableDateTime()
// element directly.
ApplyInputValue("#time-textbox-nullable-datetime", "05:06");
var expected = DateTime.Now.Date.Add(new TimeSpan(05, 06, 0));
- Browser.Equal(expected, () => DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Modify target; verify value is updated and that textboxes linked to the same data are updated
target.Clear();
@@ -1291,23 +1289,23 @@ public void CanBindTimeStepTextboxDateTime()
var boundValue = Browser.Exists(By.Id("time-step-textbox-datetime-value"));
var mirrorValue = Browser.Exists(By.Id("time-step-textbox-datetime-mirror"));
var expected = DateTime.Now.Date.Add(new TimeSpan(8, 5, 30));
- Assert.Equal(expected, DateTime.Parse(target.GetAttribute("value")));
- Assert.Equal(expected, DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Assert.Equal(expected, DateTime.Parse(target.GetAttribute("value"), CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Clear textbox; value updates to 00:00 because that's the default
target.Clear();
expected = default;
- Browser.Equal(DateTime.Now.Date, () => DateTime.Parse(target.GetAttribute("value")));
- Assert.Equal(default, DateTime.Parse(boundValue.Text));
- Assert.Equal(default, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(DateTime.Now.Date, () => DateTime.Parse(target.GetAttribute("value"), CultureInfo.InvariantCulture));
+ Assert.Equal(default, DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(default, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// We have to do it this way because the browser gets in the way when sending keys to the input
// element directly.
ApplyInputValue("#time-step-textbox-datetime", "04:05:06");
expected = DateTime.Now.Date.Add(new TimeSpan(4, 5, 6));
- Browser.Equal(expected, () => DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
}
// For date comparisons, we parse (non-formatted) values to compare them. Client-side and server-side
@@ -1332,8 +1330,8 @@ public void CanBindTimeStepTextboxNullableDateTime()
// element directly.
ApplyInputValue("#time-step-textbox-nullable-datetime", "05:06");
var expected = DateTime.Now.Date.Add(new TimeSpan(05, 06, 0));
- Browser.Equal(expected, () => DateTime.Parse(boundValue.Text));
- Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value")));
+ Browser.Equal(expected, () => DateTime.Parse(boundValue.Text, CultureInfo.InvariantCulture));
+ Assert.Equal(expected, DateTime.Parse(mirrorValue.GetAttribute("value"), CultureInfo.InvariantCulture));
// Modify target; verify value is updated and that textboxes linked to the same data are updated
target.Clear();
diff --git a/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs b/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs
index 7cda8292c2a2..fc2549974dab 100644
--- a/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs
+++ b/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs
@@ -46,10 +46,10 @@ public void CachesResourcesAfterFirstLoad()
Navigate("/");
WaitUntilLoaded();
var initialResourcesRequested = GetAndClearRequestedPaths();
- Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith("/blazor.boot.json")));
- Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith("/dotnet.wasm")));
- Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith(".js")));
- Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith(".dll")));
+ Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith("/blazor.boot.json", StringComparison.Ordinal)));
+ Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith("/dotnet.wasm", StringComparison.Ordinal)));
+ Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith(".js", StringComparison.Ordinal)));
+ Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith(".dll", StringComparison.Ordinal)));
// On subsequent loads, we skip the items referenced from blazor.boot.json
// which includes .dll files and dotnet.wasm
@@ -57,10 +57,10 @@ public void CachesResourcesAfterFirstLoad()
Navigate("/");
WaitUntilLoaded();
var subsequentResourcesRequested = GetAndClearRequestedPaths();
- Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith("/blazor.boot.json")));
- Assert.Empty(subsequentResourcesRequested.Where(path => path.EndsWith("/dotnet.wasm")));
- Assert.NotEmpty(subsequentResourcesRequested.Where(path => path.EndsWith(".js")));
- Assert.Empty(subsequentResourcesRequested.Where(path => path.EndsWith(".dll")));
+ Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith("/blazor.boot.json", StringComparison.Ordinal)));
+ Assert.Empty(subsequentResourcesRequested.Where(path => path.EndsWith("/dotnet.wasm", StringComparison.Ordinal)));
+ Assert.NotEmpty(subsequentResourcesRequested.Where(path => path.EndsWith(".js", StringComparison.Ordinal)));
+ Assert.Empty(subsequentResourcesRequested.Where(path => path.EndsWith(".dll", StringComparison.Ordinal)));
}
[Fact]
diff --git a/src/Components/test/E2ETest/Tests/ErrorNotificationTest.cs b/src/Components/test/E2ETest/Tests/ErrorNotificationTest.cs
index 328e3c67df11..1dedce23c1ed 100644
--- a/src/Components/test/E2ETest/Tests/ErrorNotificationTest.cs
+++ b/src/Components/test/E2ETest/Tests/ErrorNotificationTest.cs
@@ -34,7 +34,6 @@ protected override void InitializeAsyncCore()
}
[Fact]
- [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23643")]
public void ShowsErrorNotification_OnError_Dismiss()
{
var errorUi = Browser.Exists(By.Id("blazor-error-ui"));
@@ -52,7 +51,6 @@ public void ShowsErrorNotification_OnError_Dismiss()
}
[Fact]
- [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23596")]
public void ShowsErrorNotification_OnError_Reload()
{
var causeErrorButton = Browser.Exists(By.Id("throw-simple-exception"));
diff --git a/src/Components/test/E2ETest/Tests/EventCallbackTest.cs b/src/Components/test/E2ETest/Tests/EventCallbackTest.cs
index dbd587068f4d..a985d1532210 100644
--- a/src/Components/test/E2ETest/Tests/EventCallbackTest.cs
+++ b/src/Components/test/E2ETest/Tests/EventCallbackTest.cs
@@ -30,7 +30,6 @@ protected override void InitializeAsyncCore()
}
[Theory]
- [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23643")]
[InlineData("capturing_lambda")]
[InlineData("unbound_lambda")]
[InlineData("unbound_lambda_nested")]
diff --git a/src/Components/test/E2ETest/Tests/EventTest.cs b/src/Components/test/E2ETest/Tests/EventTest.cs
index 218b6a7acaaa..9b676994b374 100644
--- a/src/Components/test/E2ETest/Tests/EventTest.cs
+++ b/src/Components/test/E2ETest/Tests/EventTest.cs
@@ -177,6 +177,7 @@ public void PreventDefault_AppliesToFormOnSubmitHandlers()
}
[Fact]
+ [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/25929")]
public void PreventDefault_DotNotApplyByDefault()
{
var appElement = Browser.MountTestComponent();
diff --git a/src/Components/test/E2ETest/Tests/FormsTest.cs b/src/Components/test/E2ETest/Tests/FormsTest.cs
index d974ace64f12..cb6cf4691a45 100644
--- a/src/Components/test/E2ETest/Tests/FormsTest.cs
+++ b/src/Components/test/E2ETest/Tests/FormsTest.cs
@@ -408,7 +408,7 @@ public void CanWireUpINotifyPropertyChangedToEditContext()
Browser.Equal("modified valid", () => acceptsTermsInput.GetAttribute("class"));
Browser.Equal(string.Empty, () => submissionStatus.Text);
submitButton.Click();
- Browser.True(() => submissionStatus.Text.StartsWith("Submitted"));
+ Browser.True(() => submissionStatus.Text.StartsWith("Submitted", StringComparison.Ordinal));
// Fields can revert to unmodified
Browser.Equal("valid", () => userNameInput.GetAttribute("class"));
diff --git a/src/Components/test/E2ETest/Tests/GlobalizationTest.cs b/src/Components/test/E2ETest/Tests/GlobalizationTest.cs
index 8fca11ec183b..9d1244036bc3 100644
--- a/src/Components/test/E2ETest/Tests/GlobalizationTest.cs
+++ b/src/Components/test/E2ETest/Tests/GlobalizationTest.cs
@@ -87,7 +87,6 @@ public virtual void CanSetCultureAndParseCultureSensitiveNumbersAndDates(string
// We need to do step 4 to make sure that the value we're entering can "stick" in the form field.
// We can't use ".Text" because DOM reasons :(
[Theory]
- [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23643")]
[InlineData("en-US")]
[InlineData("fr-FR")]
public void CanSetCultureAndParseCultureInvariantNumbersAndDatesWithInputFields(string culture)
diff --git a/src/Components/test/E2ETest/Tests/InputFileTest.cs b/src/Components/test/E2ETest/Tests/InputFileTest.cs
index 72d346c9ff70..24b1bf2add86 100644
--- a/src/Components/test/E2ETest/Tests/InputFileTest.cs
+++ b/src/Components/test/E2ETest/Tests/InputFileTest.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
@@ -9,6 +10,7 @@
using BasicTestApp.FormsTest;
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure;
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
+using Microsoft.AspNetCore.Testing;
using Microsoft.AspNetCore.E2ETesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.Extensions;
@@ -57,13 +59,14 @@ public void CanUploadSingleSmallFile()
// Validate that the file was uploaded correctly and all fields are present
Browser.False(() => string.IsNullOrWhiteSpace(fileNameElement.Text));
- Browser.NotEqual(default, () => DateTimeOffset.Parse(fileLastModifiedElement.Text));
- Browser.Equal(file.Contents.Length.ToString(), () => fileSizeElement.Text);
+ Browser.NotEqual(default, () => DateTimeOffset.Parse(fileLastModifiedElement.Text, CultureInfo.InvariantCulture));
+ Browser.Equal(file.Contents.Length.ToString(CultureInfo.InvariantCulture), () => fileSizeElement.Text);
Browser.Equal("text/plain", () => fileContentTypeElement.Text);
Browser.Equal(file.Text, () => fileContentElement.Text);
}
[Fact]
+ [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/26331")]
public void CanUploadSingleLargeFile()
{
// Create a large text file
@@ -72,7 +75,7 @@ public void CanUploadSingleLargeFile()
for (int i = 0; i < fileContentSizeInBytes; i++)
{
- contentBuilder.Append((i % 10).ToString());
+ contentBuilder.Append((i % 10).ToString(CultureInfo.InvariantCulture));
}
var file = TempFile.Create(_tempDirectory, "txt", contentBuilder.ToString());
@@ -90,8 +93,8 @@ public void CanUploadSingleLargeFile()
// Validate that the file was uploaded correctly and all fields are present
Browser.False(() => string.IsNullOrWhiteSpace(fileNameElement.Text));
- Browser.NotEqual(default, () => DateTimeOffset.Parse(fileLastModifiedElement.Text));
- Browser.Equal(file.Contents.Length.ToString(), () => fileSizeElement.Text);
+ Browser.NotEqual(default, () => DateTimeOffset.Parse(fileLastModifiedElement.Text, CultureInfo.InvariantCulture));
+ Browser.Equal(file.Contents.Length.ToString(CultureInfo.InvariantCulture), () => fileSizeElement.Text);
Browser.Equal("text/plain", () => fileContentTypeElement.Text);
Browser.Equal(file.Text, () => fileContentElement.Text);
}
@@ -120,14 +123,15 @@ public void CanUploadMultipleFiles()
// Validate that the file was uploaded correctly and all fields are present
Browser.False(() => string.IsNullOrWhiteSpace(fileNameElement.Text));
- Browser.NotEqual(default, () => DateTimeOffset.Parse(fileLastModifiedElement.Text));
- Browser.Equal(file.Contents.Length.ToString(), () => fileSizeElement.Text);
+ Browser.NotEqual(default, () => DateTimeOffset.Parse(fileLastModifiedElement.Text, CultureInfo.InvariantCulture));
+ Browser.Equal(file.Contents.Length.ToString(CultureInfo.InvariantCulture), () => fileSizeElement.Text);
Browser.Equal("text/plain", () => fileContentTypeElement.Text);
Browser.Equal(file.Text, () => fileContentElement.Text);
});
}
[Fact]
+ [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/25929")]
public void CanUploadAndConvertImageFile()
{
var sourceImageId = "image-source";
diff --git a/src/Components/test/E2ETest/Tests/InteropTest.cs b/src/Components/test/E2ETest/Tests/InteropTest.cs
index 4f11502ec40b..bec8607db60d 100644
--- a/src/Components/test/E2ETest/Tests/InteropTest.cs
+++ b/src/Components/test/E2ETest/Tests/InteropTest.cs
@@ -7,6 +7,7 @@
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure;
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
using Microsoft.AspNetCore.E2ETesting;
+using Microsoft.AspNetCore.Testing;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
using Xunit;
@@ -32,6 +33,7 @@ protected override void InitializeAsyncCore()
}
[Fact]
+ [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/26288")]
public void CanInvokeDotNetMethods()
{
// Arrange
diff --git a/src/Components/test/E2ETest/Tests/KeyTest.cs b/src/Components/test/E2ETest/Tests/KeyTest.cs
index 778867f6faf5..71dae5c29032 100644
--- a/src/Components/test/E2ETest/Tests/KeyTest.cs
+++ b/src/Components/test/E2ETest/Tests/KeyTest.cs
@@ -92,7 +92,6 @@ public void CanInsertUnkeyed()
}
[Fact]
- [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/24190")]
public void CanDeleteUnkeyed()
{
PerformTest(
@@ -112,7 +111,6 @@ public void CanDeleteUnkeyed()
}
[Fact]
- [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/24190")]
public void CanReorder()
{
PerformTest(
diff --git a/src/Components/test/E2ETest/Tests/RoutingTest.cs b/src/Components/test/E2ETest/Tests/RoutingTest.cs
index ef4a065392d3..358bede758c0 100644
--- a/src/Components/test/E2ETest/Tests/RoutingTest.cs
+++ b/src/Components/test/E2ETest/Tests/RoutingTest.cs
@@ -12,7 +12,6 @@
using Microsoft.AspNetCore.Testing;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;
-using OpenQA.Selenium.Support.UI;
using Xunit;
using Xunit.Abstractions;
@@ -341,19 +340,19 @@ public void CanGoBackFromNotAComponent()
// First go to some URL on the router
var app = Browser.MountTestComponent();
app.FindElement(By.LinkText("Other")).Click();
- Browser.True(() => Browser.Url.EndsWith("/Other"));
+ Browser.True(() => Browser.Url.EndsWith("/Other", StringComparison.Ordinal));
// Now follow a link out of the SPA entirely
app.FindElement(By.LinkText("Not a component")).Click();
Browser.Equal("Not a component!", () => Browser.Exists(By.Id("test-info")).Text);
- Browser.True(() => Browser.Url.EndsWith("/NotAComponent.html"));
+ Browser.True(() => Browser.Url.EndsWith("/NotAComponent.html", StringComparison.Ordinal));
// Now click back
// Because of how the tests are structured with the router not appearing until the router
// tests are selected, we can only observe the test selector being there, but this is enough
// to show we did go back to the right place and the Blazor app started up
Browser.Navigate().Back();
- Browser.True(() => Browser.Url.EndsWith("/Other"));
+ Browser.True(() => Browser.Url.EndsWith("/Other", StringComparison.Ordinal));
Browser.WaitUntilTestSelectorReady();
}
@@ -366,7 +365,7 @@ public void CanNavigateProgrammatically()
var testSelector = Browser.WaitUntilTestSelectorReady();
app.FindElement(By.Id("do-navigation")).Click();
- Browser.True(() => Browser.Url.EndsWith("/Other"));
+ Browser.True(() => Browser.Url.EndsWith("/Other", StringComparison.Ordinal));
Browser.Equal("This is another page.", () => app.FindElement(By.Id("test-info")).Text);
AssertHighlightedLinks("Other", "Other with base-relative URL (matches all)");
@@ -383,7 +382,7 @@ public void CanNavigateProgrammaticallyWithForceLoad()
var testSelector = Browser.WaitUntilTestSelectorReady();
app.FindElement(By.Id("do-navigation-forced")).Click();
- Browser.True(() => Browser.Url.EndsWith("/Other"));
+ Browser.True(() => Browser.Url.EndsWith("/Other", StringComparison.Ordinal));
// Because this was a full-page load, our element references should no longer be valid
Assert.Throws(() =>
@@ -608,18 +607,30 @@ public void OnNavigate_DoesNotRenderWhileOnNavigateExecuting()
Browser.Equal("This is a long page you can scroll.", () => app.FindElement(By.Id("test-info")).Text);
}
+ [Theory]
+ [InlineData("/WithParameters/Name/Ñoño ñi/LastName/O'Jkl")]
+ [InlineData("/WithParameters/Name/[Ñoño ñi]/LastName/O'Jkl")]
+ [InlineData("/other?abc=Ñoño ñi")]
+ [InlineData("/other?abc=[Ñoño ñi]")]
+ public void CanArriveAtPageWithSpecialURL(string relativeUrl)
+ {
+ SetUrlViaPushState(relativeUrl, true);
+ var errorUi = Browser.Exists(By.Id("blazor-error-ui"));
+ Browser.Equal("none", () => errorUi.GetCssValue("display"));
+ }
+
private long BrowserScrollY
{
get => (long)((IJavaScriptExecutor)Browser).ExecuteScript("return window.scrollY");
set => ((IJavaScriptExecutor)Browser).ExecuteScript($"window.scrollTo(0, {value})");
}
- private string SetUrlViaPushState(string relativeUri)
+ private string SetUrlViaPushState(string relativeUri, bool forceLoad = false)
{
var pathBaseWithoutHash = ServerPathBase.Split('#')[0];
var jsExecutor = (IJavaScriptExecutor)Browser;
var absoluteUri = new Uri(_serverFixture.RootUri, $"{pathBaseWithoutHash}{relativeUri}");
- jsExecutor.ExecuteScript($"Blazor.navigateTo('{absoluteUri.ToString().Replace("'", "\\'")}')");
+ jsExecutor.ExecuteScript($"Blazor.navigateTo('{absoluteUri.ToString().Replace("'", "\\'")}', {(forceLoad ? "true" : "false")})");
return absoluteUri.AbsoluteUri;
}
diff --git a/src/Components/test/E2ETest/Tests/VirtualizationTest.cs b/src/Components/test/E2ETest/Tests/VirtualizationTest.cs
index f047bbb00288..94a92a19134a 100644
--- a/src/Components/test/E2ETest/Tests/VirtualizationTest.cs
+++ b/src/Components/test/E2ETest/Tests/VirtualizationTest.cs
@@ -167,6 +167,7 @@ public void RerendersWhenItemSizeShrinks_Async()
}
[Fact]
+ [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/25929")]
public void CancelsOutdatedRefreshes_Async()
{
Browser.MountTestComponent();
diff --git a/src/Components/test/E2ETest/Tests/WebAssemblyAuthenticationTests.cs b/src/Components/test/E2ETest/Tests/WebAssemblyAuthenticationTests.cs
index 13ebf2e5e5a8..4378506b8e4a 100644
--- a/src/Components/test/E2ETest/Tests/WebAssemblyAuthenticationTests.cs
+++ b/src/Components/test/E2ETest/Tests/WebAssemblyAuthenticationTests.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Data.Common;
+using System.Globalization;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
@@ -201,8 +202,8 @@ public void AuthenticatedUser_ProfileIncludesDetails_And_AccessToken()
},
payload.Scopes.OrderBy(id => id));
- var currentTime = DateTimeOffset.Parse(Browser.Exists(By.Id("current-time")).Text);
- var tokenExpiration = DateTimeOffset.Parse(Browser.Exists(By.Id("access-token-expires")).Text);
+ var currentTime = DateTimeOffset.Parse(Browser.Exists(By.Id("current-time")).Text, CultureInfo.InvariantCulture);
+ var tokenExpiration = DateTimeOffset.Parse(Browser.Exists(By.Id("access-token-expires")).Text, CultureInfo.InvariantCulture);
Assert.True(currentTime.AddMinutes(50) < tokenExpiration);
Assert.True(currentTime.AddMinutes(60) >= tokenExpiration);
}
diff --git a/src/Components/test/E2ETest/Tests/WebAssemblyConfigurationHostedTest.cs b/src/Components/test/E2ETest/Tests/WebAssemblyConfigurationHostedTest.cs
index 245c4c3b6183..62941d7c66ed 100644
--- a/src/Components/test/E2ETest/Tests/WebAssemblyConfigurationHostedTest.cs
+++ b/src/Components/test/E2ETest/Tests/WebAssemblyConfigurationHostedTest.cs
@@ -6,6 +6,7 @@
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure;
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
using Microsoft.AspNetCore.E2ETesting;
+using Microsoft.AspNetCore.Testing;
using OpenQA.Selenium;
using Xunit;
using Xunit.Abstractions;
diff --git a/src/Components/test/testassets/BasicTestApp/Program.cs b/src/Components/test/testassets/BasicTestApp/Program.cs
index c3be8fafd7f1..1e75553db716 100644
--- a/src/Components/test/testassets/BasicTestApp/Program.cs
+++ b/src/Components/test/testassets/BasicTestApp/Program.cs
@@ -33,7 +33,7 @@ public static async Task Main(string[] args)
builder.Services.AddAuthorizationCore(options =>
{
options.AddPolicy("NameMustStartWithB", policy =>
- policy.RequireAssertion(ctx => ctx.User.Identity.Name?.StartsWith("B") ?? false));
+ policy.RequireAssertion(ctx => ctx.User.Identity.Name?.StartsWith('B') ?? false));
});
builder.Logging.AddConfiguration(builder.Configuration.GetSection("Logging"));
diff --git a/src/Components/test/testassets/TestServer/AuthenticationStartup.cs b/src/Components/test/testassets/TestServer/AuthenticationStartup.cs
index ca6648d13397..61e81dff5dff 100644
--- a/src/Components/test/testassets/TestServer/AuthenticationStartup.cs
+++ b/src/Components/test/testassets/TestServer/AuthenticationStartup.cs
@@ -1,4 +1,5 @@
using System;
+using System.Globalization;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
@@ -32,13 +33,17 @@ public void ConfigureServices(IServiceCollection services)
services.AddAuthorization(options =>
{
options.AddPolicy("NameMustStartWithB", policy =>
- policy.RequireAssertion(ctx => ctx.User.Identity.Name?.StartsWith("B") ?? false));
+ policy.RequireAssertion(ctx => ctx.User.Identity.Name?.StartsWith('B') ?? false));
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
+ var enUs = new CultureInfo("en-US");
+ CultureInfo.DefaultThreadCurrentCulture = enUs;
+ CultureInfo.DefaultThreadCurrentUICulture = enUs;
+
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
diff --git a/src/Components/test/testassets/TestServer/Components.TestServer.csproj b/src/Components/test/testassets/TestServer/Components.TestServer.csproj
index ebe6254a9054..40fb11d8c400 100644
--- a/src/Components/test/testassets/TestServer/Components.TestServer.csproj
+++ b/src/Components/test/testassets/TestServer/Components.TestServer.csproj
@@ -2,9 +2,12 @@
$(DefaultNetCoreTargetFramework)
+
+
+ true
-
+
diff --git a/src/Components/test/testassets/TestServer/Controllers/CookieController.cs b/src/Components/test/testassets/TestServer/Controllers/CookieController.cs
index 72d5bd17e9ad..58a45a77f485 100644
--- a/src/Components/test/testassets/TestServer/Controllers/CookieController.cs
+++ b/src/Components/test/testassets/TestServer/Controllers/CookieController.cs
@@ -1,4 +1,8 @@
-using Microsoft.AspNetCore.Cors;
+// 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.Globalization;
+using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
namespace TestServer.Controllers
@@ -20,11 +24,11 @@ public string Increment()
var counter = 0;
if (Request.Cookies.TryGetValue(cookieKey, out var incomingValue))
{
- counter = int.Parse(incomingValue);
+ counter = int.Parse(incomingValue, CultureInfo.InvariantCulture);
}
counter++;
- Response.Cookies.Append(cookieKey, counter.ToString());
+ Response.Cookies.Append(cookieKey, counter.ToString(CultureInfo.InvariantCulture));
return $"Counter value is {counter}";
}
diff --git a/src/Components/test/testassets/TestServer/CorsStartup.cs b/src/Components/test/testassets/TestServer/CorsStartup.cs
index 7459d9fb8698..df447c8d671e 100644
--- a/src/Components/test/testassets/TestServer/CorsStartup.cs
+++ b/src/Components/test/testassets/TestServer/CorsStartup.cs
@@ -1,3 +1,8 @@
+// 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.Globalization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
@@ -27,7 +32,7 @@ public void ConfigureServices(IServiceCollection services)
// specify explicitly which origin we want to allow.
options.AddPolicy("AllowAll", policy => policy
- .SetIsOriginAllowed(host => host.StartsWith("http://localhost:") || host.StartsWith("http://127.0.0.1:"))
+ .SetIsOriginAllowed(host => host.StartsWith("http://localhost:", StringComparison.Ordinal) || host.StartsWith("http://127.0.0.1:", StringComparison.Ordinal))
.AllowAnyHeader()
.WithExposedHeaders("MyCustomHeader")
.AllowAnyMethod()
@@ -38,6 +43,10 @@ public void ConfigureServices(IServiceCollection services)
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
+ var enUs = new CultureInfo("en-US");
+ CultureInfo.DefaultThreadCurrentCulture = enUs;
+ CultureInfo.DefaultThreadCurrentUICulture = enUs;
+
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
diff --git a/src/Components/test/testassets/TestServer/MultipleComponents.cs b/src/Components/test/testassets/TestServer/MultipleComponents.cs
index 3a3bf468a62a..a965cbfd086b 100644
--- a/src/Components/test/testassets/TestServer/MultipleComponents.cs
+++ b/src/Components/test/testassets/TestServer/MultipleComponents.cs
@@ -1,3 +1,4 @@
+using System.Globalization;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
@@ -27,6 +28,10 @@ public void ConfigureServices(IServiceCollection services)
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
+ var enUs = new CultureInfo("en-US");
+ CultureInfo.DefaultThreadCurrentCulture = enUs;
+ CultureInfo.DefaultThreadCurrentUICulture = enUs;
+
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
diff --git a/src/Components/test/testassets/TestServer/PrerenderedStartup.cs b/src/Components/test/testassets/TestServer/PrerenderedStartup.cs
index c4d7ad3c94dd..0a3e28bf3418 100644
--- a/src/Components/test/testassets/TestServer/PrerenderedStartup.cs
+++ b/src/Components/test/testassets/TestServer/PrerenderedStartup.cs
@@ -5,6 +5,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Components.WebAssembly.Services;
+using System.Globalization;
namespace TestServer
{
@@ -29,6 +30,10 @@ public void ConfigureServices(IServiceCollection services)
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
+ var enUs = new CultureInfo("en-US");
+ CultureInfo.DefaultThreadCurrentCulture = enUs;
+ CultureInfo.DefaultThreadCurrentUICulture = enUs;
+
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
diff --git a/src/Components/test/testassets/TestServer/ServerStartup.cs b/src/Components/test/testassets/TestServer/ServerStartup.cs
index 6b4c5668bdb1..acc321be06a6 100644
--- a/src/Components/test/testassets/TestServer/ServerStartup.cs
+++ b/src/Components/test/testassets/TestServer/ServerStartup.cs
@@ -1,3 +1,4 @@
+using System.Globalization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
@@ -25,6 +26,10 @@ public void ConfigureServices(IServiceCollection services)
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
+ var enUs = new CultureInfo("en-US");
+ CultureInfo.DefaultThreadCurrentCulture = enUs;
+ CultureInfo.DefaultThreadCurrentUICulture = enUs;
+
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
diff --git a/src/Components/test/testassets/TestServer/Startup.cs b/src/Components/test/testassets/TestServer/Startup.cs
index f110edfaddac..23d927cb4a74 100644
--- a/src/Components/test/testassets/TestServer/Startup.cs
+++ b/src/Components/test/testassets/TestServer/Startup.cs
@@ -1,3 +1,4 @@
+using System.Globalization;
using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
@@ -26,6 +27,10 @@ public void ConfigureServices(IServiceCollection services)
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
+ var enUs = new CultureInfo("en-US");
+ CultureInfo.DefaultThreadCurrentCulture = enUs;
+ CultureInfo.DefaultThreadCurrentUICulture = enUs;
+
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
diff --git a/src/Components/test/testassets/TestServer/StartupWithMapFallbackToClientSideBlazor.cs b/src/Components/test/testassets/TestServer/StartupWithMapFallbackToClientSideBlazor.cs
index a65b87c23096..b11cbdfe59a4 100644
--- a/src/Components/test/testassets/TestServer/StartupWithMapFallbackToClientSideBlazor.cs
+++ b/src/Components/test/testassets/TestServer/StartupWithMapFallbackToClientSideBlazor.cs
@@ -1,6 +1,7 @@
// 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.Globalization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
@@ -25,6 +26,10 @@ public void ConfigureServices(IServiceCollection services)
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
+ var enUs = new CultureInfo("en-US");
+ CultureInfo.DefaultThreadCurrentCulture = enUs;
+ CultureInfo.DefaultThreadCurrentUICulture = enUs;
+
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
diff --git a/src/Configuration.KeyPerFile/src/KeyPerFileConfigurationProvider.cs b/src/Configuration.KeyPerFile/src/KeyPerFileConfigurationProvider.cs
index f586896fc275..6d4e318b1540 100644
--- a/src/Configuration.KeyPerFile/src/KeyPerFileConfigurationProvider.cs
+++ b/src/Configuration.KeyPerFile/src/KeyPerFileConfigurationProvider.cs
@@ -40,7 +40,7 @@ private static string NormalizeKey(string key)
=> key.Replace("__", ConfigurationPath.KeyDelimiter);
private static string TrimNewLine(string value)
- => value.EndsWith(Environment.NewLine)
+ => value.EndsWith(Environment.NewLine, StringComparison.Ordinal)
? value.Substring(0, value.Length - Environment.NewLine.Length)
: value;
diff --git a/src/Configuration.KeyPerFile/src/KeyPerFileConfigurationSource.cs b/src/Configuration.KeyPerFile/src/KeyPerFileConfigurationSource.cs
index 2b64d5a8dda7..f8f84f7b276c 100644
--- a/src/Configuration.KeyPerFile/src/KeyPerFileConfigurationSource.cs
+++ b/src/Configuration.KeyPerFile/src/KeyPerFileConfigurationSource.cs
@@ -13,7 +13,7 @@ public class KeyPerFileConfigurationSource : IConfigurationSource
/// Constructor;
///
public KeyPerFileConfigurationSource()
- => IgnoreCondition = s => IgnorePrefix != null && s.StartsWith(IgnorePrefix);
+ => IgnoreCondition = s => IgnorePrefix != null && s.StartsWith(IgnorePrefix, StringComparison.Ordinal);
///
/// The FileProvider whos root "/" directory files will be used as configuration data.
diff --git a/src/DataProtection/DataProtection/src/KeyManagement/XmlKeyManager.cs b/src/DataProtection/DataProtection/src/KeyManagement/XmlKeyManager.cs
index 094832e43c0e..a73d52793ee2 100644
--- a/src/DataProtection/DataProtection/src/KeyManagement/XmlKeyManager.cs
+++ b/src/DataProtection/DataProtection/src/KeyManagement/XmlKeyManager.cs
@@ -145,7 +145,7 @@ public IKey CreateNewKey(DateTimeOffset activationDate, DateTimeOffset expiratio
private static string DateTimeOffsetToFilenameSafeString(DateTimeOffset dateTime)
{
// similar to the XML format for dates, but with punctuation stripped
- return dateTime.UtcDateTime.ToString("yyyyMMddTHHmmssFFFFFFFZ");
+ return dateTime.UtcDateTime.ToString("yyyyMMddTHHmmssFFFFFFFZ", CultureInfo.InvariantCulture);
}
public IReadOnlyCollection GetAllKeys()
diff --git a/src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorDeserializerTests.cs b/src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorDeserializerTests.cs
index 69cc556e6bf6..ef2604e8ec2e 100644
--- a/src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorDeserializerTests.cs
+++ b/src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorDeserializerTests.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Globalization;
using System.Security.Cryptography;
using System.Xml.Linq;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
@@ -30,7 +31,9 @@ public void ImportFromXml_BuiltInTypes_CreatesAppropriateDescriptor(Type encrypt
"k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret());
var control = CreateEncryptorInstanceFromDescriptor(descriptor);
- string xml = string.Format(@"
+ string xml = string.Format(
+ CultureInfo.InvariantCulture,
+ @"
@@ -64,7 +67,9 @@ public void ImportFromXml_CustomType_CreatesAppropriateDescriptor()
"k88VrwGLINfVAqzlAp7U4EAjdlmUG17c756McQGdjHU8Ajkfc/A3YOKdqlMcF6dXaIxATED+g2f62wkRRRRRzA==".ToSecret());
var control = CreateEncryptorInstanceFromDescriptor(descriptor);
- string xml = string.Format(@"
+ string xml = string.Format(
+ CultureInfo.InvariantCulture,
+ @"
diff --git a/src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorTests.cs b/src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorTests.cs
index 4e4f4534484e..6d92fcf7ddbc 100644
--- a/src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorTests.cs
+++ b/src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorTests.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Globalization;
using System.Security.Cryptography;
using Xunit;
@@ -26,7 +27,9 @@ public void ExportToXml_CustomTypes_ProducesCorrectPayload()
// Assert
Assert.Equal(typeof(ManagedAuthenticatedEncryptorDescriptorDeserializer), retVal.DeserializerType);
- string expectedXml = string.Format(@"
+ string expectedXml = string.Format(
+ CultureInfo.InvariantCulture,
+ @"
@@ -59,7 +62,9 @@ public void ExportToXml_BuiltInTypes_ProducesCorrectPayload(Type encryptionAlgor
// Assert
Assert.Equal(typeof(ManagedAuthenticatedEncryptorDescriptorDeserializer), retVal.DeserializerType);
- string expectedXml = string.Format(@"
+ string expectedXml = string.Format(
+ CultureInfo.InvariantCulture,
+ @"
diff --git a/src/DataProtection/DataProtection/test/KeyManagement/XmlKeyManagerTests.cs b/src/DataProtection/DataProtection/test/KeyManagement/XmlKeyManagerTests.cs
index c6a2e068a3fb..efb107feca72 100644
--- a/src/DataProtection/DataProtection/test/KeyManagement/XmlKeyManagerTests.cs
+++ b/src/DataProtection/DataProtection/test/KeyManagement/XmlKeyManagerTests.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
@@ -136,7 +137,9 @@ public void CreateNewKey_Internal_NoEscrowOrEncryption()
Assert.Same(expectedAuthenticatedEncryptor, testEncryptorFactory.CreateEncryptorInstance(newKey));
// Finally, was the correct element stored in the repository?
- string expectedXml = string.Format(@"
+ string expectedXml = string.Format(
+ CultureInfo.InvariantCulture,
+ @"
{1}
{2}
@@ -233,7 +236,9 @@ public void CreateNewKey_Internal_WithEscrowAndEncryption()
// Was the correct element stored in escrow?
// This should not have gone through the encryptor.
- string expectedEscrowXml = string.Format(@"
+ string expectedEscrowXml = string.Format(
+ CultureInfo.InvariantCulture,
+ @"
{1}
{2}
@@ -255,7 +260,9 @@ public void CreateNewKey_Internal_WithEscrowAndEncryption()
// Finally, was the correct element stored in the repository?
// This should have gone through the encryptor (which we set to be the null encryptor in this test)
- string expectedRepositoryXml = String.Format(@"
+ string expectedRepositoryXml = String.Format(
+ CultureInfo.InvariantCulture,
+ @"
{2}
{3}
@@ -696,7 +703,9 @@ public void RevokeSingleKey_Internal()
Assert.False(secondCancellationToken.IsCancellationRequested);
// Was the correct element stored in the repository?
- var expectedRepositoryXml = string.Format(@"
+ var expectedRepositoryXml = string.Format(
+ CultureInfo.InvariantCulture,
+ @"
{0}
diff --git a/src/DataProtection/DataProtection/test/XmlAssert.cs b/src/DataProtection/DataProtection/test/XmlAssert.cs
index 3bd5ccdc161f..d6febaa0b378 100644
--- a/src/DataProtection/DataProtection/test/XmlAssert.cs
+++ b/src/DataProtection/DataProtection/test/XmlAssert.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Xml.Linq;
using Xunit;
@@ -124,7 +125,7 @@ private static bool ShouldIncludeNodeDuringComparison(XNode node)
return true; // relevant
}
- throw new NotSupportedException(string.Format("Node of type '{0}' is not supported.", node.GetType().Name));
+ throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "Node of type '{0}' is not supported.", node.GetType().Name));
}
}
diff --git a/src/DataProtection/DataProtection/test/XmlEncryption/XmlEncryptionExtensionsTests.cs b/src/DataProtection/DataProtection/test/XmlEncryption/XmlEncryptionExtensionsTests.cs
index bf3c455b5a52..7abe4972df56 100644
--- a/src/DataProtection/DataProtection/test/XmlEncryption/XmlEncryptionExtensionsTests.cs
+++ b/src/DataProtection/DataProtection/test/XmlEncryption/XmlEncryptionExtensionsTests.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Globalization;
using System.Linq;
using System.Xml.Linq;
using Microsoft.AspNetCore.DataProtection.Internal;
@@ -151,7 +152,9 @@ public void EncryptIfNecessary_MultipleNodesRequireEncryption_Success()
");
- var expected = string.Format(@"
+ var expected = string.Format(
+ CultureInfo.InvariantCulture,
+ @"
@@ -194,7 +197,9 @@ public void EncryptIfNecessary_NullEncryptorWithRecursion_NoStackDive_Success()
");
- var expected = string.Format(@"
+ var expected = string.Format(
+ CultureInfo.InvariantCulture,
+ @"
diff --git a/src/DataProtection/Extensions/test/DataProtectionProviderTests.cs b/src/DataProtection/Extensions/test/DataProtectionProviderTests.cs
index 951b0030636d..8fb700d452da 100644
--- a/src/DataProtection/Extensions/test/DataProtectionProviderTests.cs
+++ b/src/DataProtection/Extensions/test/DataProtectionProviderTests.cs
@@ -115,7 +115,7 @@ public void System_UsesProvidedDirectory_WithConfigurationCallback()
[ConditionalFact]
[X509StoreIsAvailable(StoreName.My, StoreLocation.CurrentUser)]
- [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720", Queues = "OSX.1014.Amd64;OSX.1014.Amd64.Open")]
+ [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720 and https://github.com/dotnet/aspnetcore/issues/26871", Queues = "All.OSX;Windows.10.Arm64.Open")]
public void System_UsesProvidedDirectoryAndCertificate()
{
var filePath = Path.Combine(GetTestFilesPath(), "TestCert.pfx");
diff --git a/src/Features/JsonPatch/src/JsonPatchDocumentOfT.cs b/src/Features/JsonPatch/src/JsonPatchDocumentOfT.cs
index eb3276ffa187..6ccefe3808ce 100644
--- a/src/Features/JsonPatch/src/JsonPatchDocumentOfT.cs
+++ b/src/Features/JsonPatch/src/JsonPatchDocumentOfT.cs
@@ -85,7 +85,7 @@ public JsonPatchDocument Add(
Operations.Add(new Operation(
"add",
- GetPath(path, position.ToString()),
+ GetPath(path, position.ToString(CultureInfo.InvariantCulture)),
from: null,
value: value));
@@ -149,7 +149,7 @@ public JsonPatchDocument Remove(Expression(
"remove",
- GetPath(path, position.ToString()),
+ GetPath(path, position.ToString(CultureInfo.InvariantCulture)),
from: null));
return this;
@@ -217,7 +217,7 @@ public JsonPatchDocument Replace(Expression(
"replace",
- GetPath(path, position.ToString()),
+ GetPath(path, position.ToString(CultureInfo.InvariantCulture)),
from: null,
value: value));
@@ -288,7 +288,7 @@ public JsonPatchDocument Test(Expression(
"test",
- GetPath(path, position.ToString()),
+ GetPath(path, position.ToString(CultureInfo.InvariantCulture)),
from: null,
value: value));
@@ -373,7 +373,7 @@ public JsonPatchDocument Move(
Operations.Add(new Operation(
"move",
GetPath(path, null),
- GetPath(from, positionFrom.ToString())));
+ GetPath(from, positionFrom.ToString(CultureInfo.InvariantCulture))));
return this;
}
@@ -403,7 +403,7 @@ public JsonPatchDocument Move(
Operations.Add(new Operation(
"move",
- GetPath(path, positionTo.ToString()),
+ GetPath(path, positionTo.ToString(CultureInfo.InvariantCulture)),
GetPath(from, null)));
return this;
@@ -436,8 +436,8 @@ public JsonPatchDocument Move(
Operations.Add(new Operation(
"move",
- GetPath(path, positionTo.ToString()),
- GetPath(from, positionFrom.ToString())));
+ GetPath(path, positionTo.ToString(CultureInfo.InvariantCulture)),
+ GetPath(from, positionFrom.ToString(CultureInfo.InvariantCulture))));
return this;
}
@@ -468,7 +468,7 @@ public JsonPatchDocument Move(
Operations.Add(new Operation(
"move",
GetPath(path, "-"),
- GetPath(from, positionFrom.ToString())));
+ GetPath(from, positionFrom.ToString(CultureInfo.InvariantCulture))));
return this;
}
@@ -557,7 +557,7 @@ public JsonPatchDocument Copy(
Operations.Add(new Operation(
"copy",
GetPath(path, null),
- GetPath(from, positionFrom.ToString())));
+ GetPath(from, positionFrom.ToString(CultureInfo.InvariantCulture))));
return this;
}
@@ -587,7 +587,7 @@ public JsonPatchDocument Copy(
Operations.Add(new Operation(
"copy",
- GetPath(path, positionTo.ToString()),
+ GetPath(path, positionTo.ToString(CultureInfo.InvariantCulture)),
GetPath(from, null)));
return this;
@@ -620,8 +620,8 @@ public JsonPatchDocument Copy(
Operations.Add(new Operation(
"copy",
- GetPath(path, positionTo.ToString()),
- GetPath(from, positionFrom.ToString())));
+ GetPath(path, positionTo.ToString(CultureInfo.InvariantCulture)),
+ GetPath(from, positionFrom.ToString(CultureInfo.InvariantCulture))));
return this;
}
@@ -652,7 +652,7 @@ public JsonPatchDocument Copy(
Operations.Add(new Operation(
"copy",
GetPath(path, "-"),
- GetPath(from, positionFrom.ToString())));
+ GetPath(from, positionFrom.ToString(CultureInfo.InvariantCulture))));
return this;
}
diff --git a/src/Features/JsonPatch/test/Internal/DictionaryAdapterTest.cs b/src/Features/JsonPatch/test/Internal/DictionaryAdapterTest.cs
index a0dcd82ab017..e055009b8274 100644
--- a/src/Features/JsonPatch/test/Internal/DictionaryAdapterTest.cs
+++ b/src/Features/JsonPatch/test/Internal/DictionaryAdapterTest.cs
@@ -1,8 +1,9 @@
-// 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.
using System;
using System.Collections.Generic;
+using System.Globalization;
using Newtonsoft.Json.Serialization;
using Xunit;
@@ -41,7 +42,7 @@ public void Add_IntKeyWhichAlreadyExists_ReplacesExistingValue()
var resolver = new DefaultContractResolver();
// Act
- var addStatus = dictionaryAdapter.TryAdd(dictionary, intKey.ToString(), resolver, "James", out var message);
+ var addStatus = dictionaryAdapter.TryAdd(dictionary, intKey.ToString(CultureInfo.InvariantCulture), resolver, "James", out var message);
// Assert
Assert.True(addStatus);
@@ -60,7 +61,7 @@ public void GetInvalidKey_ThrowsInvalidPathSegmentException()
var dictionary = new Dictionary();
// Act
- var addStatus = dictionaryAdapter.TryAdd(dictionary, key.ToString(), resolver, "James", out var message);
+ var addStatus = dictionaryAdapter.TryAdd(dictionary, key.ToString(CultureInfo.InvariantCulture), resolver, "James", out var message);
// Assert
Assert.True(addStatus);
@@ -97,7 +98,7 @@ public void Get_UsingCaseSensitiveKey_FailureScenario()
Assert.Equal("James", dictionary[nameKey]);
// Act
- var getStatus = dictionaryAdapter.TryGet(dictionary, nameKey.ToUpper(), resolver, out var outValue, out message);
+ var getStatus = dictionaryAdapter.TryGet(dictionary, nameKey.ToUpperInvariant(), resolver, out var outValue, out message);
// Assert
Assert.False(getStatus);
diff --git a/src/Features/JsonPatch/test/Internal/ListAdapterTest.cs b/src/Features/JsonPatch/test/Internal/ListAdapterTest.cs
index f31e57541b02..65c87bab1830 100644
--- a/src/Features/JsonPatch/test/Internal/ListAdapterTest.cs
+++ b/src/Features/JsonPatch/test/Internal/ListAdapterTest.cs
@@ -1,8 +1,9 @@
-// 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.
using System.Collections;
using System.Collections.Generic;
+using System.Globalization;
using Moq;
using Newtonsoft.Json.Serialization;
using Xunit;
@@ -52,7 +53,7 @@ public void Add_WithIndexSameAsNumberOfElements_Works()
var resolver = new Mock(MockBehavior.Strict);
var targetObject = new List() { "James", "Mike" };
var listAdapter = new ListAdapter();
- var position = targetObject.Count.ToString();
+ var position = targetObject.Count.ToString(CultureInfo.InvariantCulture);
// Act
var addStatus = listAdapter.TryAdd(targetObject, position, resolver.Object, "Rob", out var message);
diff --git a/src/Framework/App.Runtime/src/Microsoft.AspNetCore.App.Runtime.csproj b/src/Framework/App.Runtime/src/Microsoft.AspNetCore.App.Runtime.csproj
index 2e10f9ff36eb..1b2286889fbb 100644
--- a/src/Framework/App.Runtime/src/Microsoft.AspNetCore.App.Runtime.csproj
+++ b/src/Framework/App.Runtime/src/Microsoft.AspNetCore.App.Runtime.csproj
@@ -92,7 +92,7 @@ This package is an internal implementation of the .NET Core SDK and is not meant
:%3B
- x64_arm
+ x64_armx64_arm64x86_arm
diff --git a/src/Framework/Directory.Build.props b/src/Framework/Directory.Build.props
index 555b1633d650..026b3c7047aa 100644
--- a/src/Framework/Directory.Build.props
+++ b/src/Framework/Directory.Build.props
@@ -7,15 +7,15 @@
PlatformManifest.txt$(ArtifactsObjDir)$(PlatformManifestFileName)
-
- $(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion).0
+
+ $(AspNetCoreMajorMinorVersion).0$(ReferencePackSharedFxVersion)-$(VersionSuffix)
-
+
diff --git a/src/Framework/test/Microsoft.AspNetCore.App.UnitTests.csproj b/src/Framework/test/Microsoft.AspNetCore.App.UnitTests.csproj
index 3a594e0f301f..bee9ff9066d4 100644
--- a/src/Framework/test/Microsoft.AspNetCore.App.UnitTests.csproj
+++ b/src/Framework/test/Microsoft.AspNetCore.App.UnitTests.csproj
@@ -16,6 +16,10 @@
<_Parameter1>SharedFxVersion
<_Parameter2>$(SharedFxVersion)
+
+ <_Parameter1>DefaultNetCoreTargetFramework
+ <_Parameter2>$(DefaultNetCoreTargetFramework)
+
<_Parameter1>TargetRuntimeIdentifier
<_Parameter2>$(TargetRuntimeIdentifier)
diff --git a/src/Framework/test/SharedFxTests.cs b/src/Framework/test/SharedFxTests.cs
index 227c53140c0e..a6753f803302 100644
--- a/src/Framework/test/SharedFxTests.cs
+++ b/src/Framework/test/SharedFxTests.cs
@@ -27,7 +27,7 @@ public class SharedFxTests
public SharedFxTests(ITestOutputHelper output)
{
_output = output;
- _expectedTfm = "net" + TestData.GetSharedFxVersion().Substring(0, 3);
+ _expectedTfm = TestData.GetDefaultNetCoreTargetFramework();
_expectedRid = TestData.GetSharedFxRuntimeIdentifier();
_sharedFxRoot = string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ASPNET_RUNTIME_PATH"))
? Path.Combine(TestData.GetTestDataValue("SharedFrameworkLayoutRoot"), "shared", "Microsoft.AspNetCore.App", TestData.GetTestDataValue("RuntimePackageVersion"))
@@ -108,7 +108,7 @@ public void SharedFrameworkContainsValidDepsJson()
{
var depsFilePath = Path.Combine(_sharedFxRoot, "Microsoft.AspNetCore.App.deps.json");
- var target = $".NETCoreApp,Version=v{TestData.GetSharedFxVersion().Substring(0, 3)}/{_expectedRid}";
+ var target = $".NETCoreApp,Version=v{_expectedTfm.Substring(3)}/{_expectedRid}";
var ridPackageId = $"Microsoft.AspNetCore.App.Runtime.{_expectedRid}";
var libraryId = $"{ridPackageId}/{TestData.GetTestDataValue("RuntimePackageVersion")}";
@@ -192,7 +192,7 @@ public void SharedFrameworkAssemblyReferencesHaveExpectedAssemblyVersions()
using var fileStream = File.OpenRead(path);
using var peReader = new PEReader(fileStream, PEStreamOptions.Default);
var reader = peReader.GetMetadataReader(MetadataReaderOptions.Default);
-
+
Assert.All(reader.AssemblyReferences, handle =>
{
var reference = reader.GetAssemblyReference(handle);
@@ -290,7 +290,7 @@ public void RuntimeListListsContainsCorrectPaths()
ZipArchive archive = ZipFile.OpenRead(sharedFxPath);
var actualPaths = archive.Entries
- .Where(i => i.FullName.EndsWith(".dll"))
+ .Where(i => i.FullName.EndsWith(".dll", StringComparison.Ordinal))
.Select(i => i.FullName).ToHashSet();
var expectedPaths = runtimeListEntries.Select(i => i.Attribute("Path").Value).ToHashSet();
diff --git a/src/Framework/test/TargetingPackTests.cs b/src/Framework/test/TargetingPackTests.cs
index 8d9f02524e24..5f34153949c5 100644
--- a/src/Framework/test/TargetingPackTests.cs
+++ b/src/Framework/test/TargetingPackTests.cs
@@ -29,7 +29,7 @@ public TargetingPackTests(ITestOutputHelper output)
{
_output = output;
_expectedRid = TestData.GetSharedFxRuntimeIdentifier();
- _targetingPackTfm = "net" + TestData.GetSharedFxVersion().Substring(0, 3);
+ _targetingPackTfm = TestData.GetDefaultNetCoreTargetFramework();
var root = string.IsNullOrEmpty(Environment.GetEnvironmentVariable("helix")) ?
TestData.GetTestDataValue("TargetingPackLayoutRoot") :
Environment.GetEnvironmentVariable("DOTNET_ROOT");
@@ -370,7 +370,7 @@ public void FrameworkListListsContainsCorrectPaths()
ZipArchive archive = ZipFile.OpenRead(targetingPackPath);
var actualPaths = archive.Entries
- .Where(i => i.FullName.EndsWith(".dll"))
+ .Where(i => i.FullName.EndsWith(".dll", StringComparison.Ordinal))
.Select(i => i.FullName).ToHashSet();
var expectedPaths = frameworkListEntries.Select(i => i.Attribute("Path").Value).ToHashSet();
diff --git a/src/Framework/test/TestData.cs b/src/Framework/test/TestData.cs
index 2271d24ece6f..e73cd74901a3 100644
--- a/src/Framework/test/TestData.cs
+++ b/src/Framework/test/TestData.cs
@@ -151,83 +151,83 @@ static TestData()
};
ListedTargetingPackAssemblies = new SortedDictionary
{
- { "Microsoft.AspNetCore", "5.0.0.0" },
- { "Microsoft.AspNetCore.Antiforgery", "5.0.0.0" },
- { "Microsoft.AspNetCore.Authentication", "5.0.0.0" },
- { "Microsoft.AspNetCore.Authentication.Abstractions", "5.0.0.0" },
- { "Microsoft.AspNetCore.Authentication.Cookies", "5.0.0.0" },
- { "Microsoft.AspNetCore.Authentication.Core", "5.0.0.0" },
- { "Microsoft.AspNetCore.Authentication.OAuth", "5.0.0.0" },
- { "Microsoft.AspNetCore.Authorization", "5.0.0.0" },
- { "Microsoft.AspNetCore.Authorization.Policy", "5.0.0.0" },
- { "Microsoft.AspNetCore.Components", "5.0.0.0" },
- { "Microsoft.AspNetCore.Components.Authorization", "5.0.0.0" },
- { "Microsoft.AspNetCore.Components.Forms", "5.0.0.0" },
- { "Microsoft.AspNetCore.Components.Server", "5.0.0.0" },
- { "Microsoft.AspNetCore.Components.Web", "5.0.0.0" },
- { "Microsoft.AspNetCore.Connections.Abstractions", "5.0.0.0" },
- { "Microsoft.AspNetCore.CookiePolicy", "5.0.0.0" },
- { "Microsoft.AspNetCore.Cors", "5.0.0.0" },
- { "Microsoft.AspNetCore.Cryptography.Internal", "5.0.0.0" },
- { "Microsoft.AspNetCore.Cryptography.KeyDerivation", "5.0.0.0" },
- { "Microsoft.AspNetCore.DataProtection", "5.0.0.0" },
- { "Microsoft.AspNetCore.DataProtection.Abstractions", "5.0.0.0" },
- { "Microsoft.AspNetCore.DataProtection.Extensions", "5.0.0.0" },
- { "Microsoft.AspNetCore.Diagnostics", "5.0.0.0" },
- { "Microsoft.AspNetCore.Diagnostics.Abstractions", "5.0.0.0" },
- { "Microsoft.AspNetCore.Diagnostics.HealthChecks", "5.0.0.0" },
- { "Microsoft.AspNetCore.HostFiltering", "5.0.0.0" },
- { "Microsoft.AspNetCore.Hosting", "5.0.0.0" },
- { "Microsoft.AspNetCore.Hosting.Abstractions", "5.0.0.0" },
- { "Microsoft.AspNetCore.Hosting.Server.Abstractions", "5.0.0.0" },
- { "Microsoft.AspNetCore.Html.Abstractions", "5.0.0.0" },
- { "Microsoft.AspNetCore.Http", "5.0.0.0" },
- { "Microsoft.AspNetCore.Http.Abstractions", "5.0.0.0" },
- { "Microsoft.AspNetCore.Http.Connections", "5.0.0.0" },
- { "Microsoft.AspNetCore.Http.Connections.Common", "5.0.0.0" },
- { "Microsoft.AspNetCore.Http.Extensions", "5.0.0.0" },
- { "Microsoft.AspNetCore.Http.Features", "5.0.0.0" },
- { "Microsoft.AspNetCore.HttpOverrides", "5.0.0.0" },
- { "Microsoft.AspNetCore.HttpsPolicy", "5.0.0.0" },
- { "Microsoft.AspNetCore.Identity", "5.0.0.0" },
- { "Microsoft.AspNetCore.Localization", "5.0.0.0" },
- { "Microsoft.AspNetCore.Localization.Routing", "5.0.0.0" },
- { "Microsoft.AspNetCore.Metadata", "5.0.0.0" },
- { "Microsoft.AspNetCore.Mvc", "5.0.0.0" },
- { "Microsoft.AspNetCore.Mvc.Abstractions", "5.0.0.0" },
- { "Microsoft.AspNetCore.Mvc.ApiExplorer", "5.0.0.0" },
- { "Microsoft.AspNetCore.Mvc.Core", "5.0.0.0" },
- { "Microsoft.AspNetCore.Mvc.Cors", "5.0.0.0" },
- { "Microsoft.AspNetCore.Mvc.DataAnnotations", "5.0.0.0" },
- { "Microsoft.AspNetCore.Mvc.Formatters.Json", "5.0.0.0" },
- { "Microsoft.AspNetCore.Mvc.Formatters.Xml", "5.0.0.0" },
- { "Microsoft.AspNetCore.Mvc.Localization", "5.0.0.0" },
- { "Microsoft.AspNetCore.Mvc.Razor", "5.0.0.0" },
- { "Microsoft.AspNetCore.Mvc.RazorPages", "5.0.0.0" },
- { "Microsoft.AspNetCore.Mvc.TagHelpers", "5.0.0.0" },
- { "Microsoft.AspNetCore.Mvc.ViewFeatures", "5.0.0.0" },
- { "Microsoft.AspNetCore.Razor", "5.0.0.0" },
- { "Microsoft.AspNetCore.Razor.Runtime", "5.0.0.0" },
- { "Microsoft.AspNetCore.ResponseCaching", "5.0.0.0" },
- { "Microsoft.AspNetCore.ResponseCaching.Abstractions", "5.0.0.0" },
- { "Microsoft.AspNetCore.ResponseCompression", "5.0.0.0" },
- { "Microsoft.AspNetCore.Rewrite", "5.0.0.0" },
- { "Microsoft.AspNetCore.Routing", "5.0.0.0" },
- { "Microsoft.AspNetCore.Routing.Abstractions", "5.0.0.0" },
- { "Microsoft.AspNetCore.Server.HttpSys", "5.0.0.0" },
- { "Microsoft.AspNetCore.Server.IIS", "5.0.0.0" },
- { "Microsoft.AspNetCore.Server.IISIntegration", "5.0.0.0" },
- { "Microsoft.AspNetCore.Server.Kestrel", "5.0.0.0" },
- { "Microsoft.AspNetCore.Server.Kestrel.Core", "5.0.0.0" },
- { "Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets", "5.0.0.0" },
- { "Microsoft.AspNetCore.Session", "5.0.0.0" },
- { "Microsoft.AspNetCore.SignalR", "5.0.0.0" },
- { "Microsoft.AspNetCore.SignalR.Common", "5.0.0.0" },
- { "Microsoft.AspNetCore.SignalR.Core", "5.0.0.0" },
- { "Microsoft.AspNetCore.SignalR.Protocols.Json", "5.0.0.0" },
- { "Microsoft.AspNetCore.StaticFiles", "5.0.0.0" },
- { "Microsoft.AspNetCore.WebSockets", "5.0.0.0" },
- { "Microsoft.AspNetCore.WebUtilities", "5.0.0.0" },
+ { "Microsoft.AspNetCore", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Antiforgery", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Authentication", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Authentication.Abstractions", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Authentication.Cookies", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Authentication.Core", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Authentication.OAuth", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Authorization", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Authorization.Policy", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Components", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Components.Authorization", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Components.Forms", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Components.Server", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Components.Web", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Connections.Abstractions", "6.0.0.0" },
+ { "Microsoft.AspNetCore.CookiePolicy", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Cors", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Cryptography.Internal", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Cryptography.KeyDerivation", "6.0.0.0" },
+ { "Microsoft.AspNetCore.DataProtection", "6.0.0.0" },
+ { "Microsoft.AspNetCore.DataProtection.Abstractions", "6.0.0.0" },
+ { "Microsoft.AspNetCore.DataProtection.Extensions", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Diagnostics", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Diagnostics.Abstractions", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Diagnostics.HealthChecks", "6.0.0.0" },
+ { "Microsoft.AspNetCore.HostFiltering", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Hosting", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Hosting.Abstractions", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Hosting.Server.Abstractions", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Html.Abstractions", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Http", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Http.Abstractions", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Http.Connections", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Http.Connections.Common", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Http.Extensions", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Http.Features", "6.0.0.0" },
+ { "Microsoft.AspNetCore.HttpOverrides", "6.0.0.0" },
+ { "Microsoft.AspNetCore.HttpsPolicy", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Identity", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Localization", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Localization.Routing", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Metadata", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Mvc", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Mvc.Abstractions", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Mvc.ApiExplorer", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Mvc.Core", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Mvc.Cors", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Mvc.DataAnnotations", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Mvc.Formatters.Json", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Mvc.Formatters.Xml", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Mvc.Localization", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Mvc.Razor", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Mvc.RazorPages", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Mvc.TagHelpers", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Mvc.ViewFeatures", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Razor", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Razor.Runtime", "6.0.0.0" },
+ { "Microsoft.AspNetCore.ResponseCaching", "6.0.0.0" },
+ { "Microsoft.AspNetCore.ResponseCaching.Abstractions", "6.0.0.0" },
+ { "Microsoft.AspNetCore.ResponseCompression", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Rewrite", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Routing", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Routing.Abstractions", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Server.HttpSys", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Server.IIS", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Server.IISIntegration", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Server.Kestrel", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Server.Kestrel.Core", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets", "6.0.0.0" },
+ { "Microsoft.AspNetCore.Session", "6.0.0.0" },
+ { "Microsoft.AspNetCore.SignalR", "6.0.0.0" },
+ { "Microsoft.AspNetCore.SignalR.Common", "6.0.0.0" },
+ { "Microsoft.AspNetCore.SignalR.Core", "6.0.0.0" },
+ { "Microsoft.AspNetCore.SignalR.Protocols.Json", "6.0.0.0" },
+ { "Microsoft.AspNetCore.StaticFiles", "6.0.0.0" },
+ { "Microsoft.AspNetCore.WebSockets", "6.0.0.0" },
+ { "Microsoft.AspNetCore.WebUtilities", "6.0.0.0" },
{ "Microsoft.Extensions.Caching.Abstractions", "5.0.0.0" },
{ "Microsoft.Extensions.Caching.Memory", "5.0.0.0" },
{ "Microsoft.Extensions.Configuration", "5.0.0.0" },
@@ -238,25 +238,25 @@ static TestData()
{ "Microsoft.Extensions.Configuration.FileExtensions", "5.0.0.0" },
{ "Microsoft.Extensions.Configuration.Ini", "5.0.0.0" },
{ "Microsoft.Extensions.Configuration.Json", "5.0.0.0" },
- { "Microsoft.Extensions.Configuration.KeyPerFile", "5.0.0.0" },
+ { "Microsoft.Extensions.Configuration.KeyPerFile", "6.0.0.0" },
{ "Microsoft.Extensions.Configuration.UserSecrets", "5.0.0.0" },
{ "Microsoft.Extensions.Configuration.Xml", "5.0.0.0" },
{ "Microsoft.Extensions.DependencyInjection", "5.0.0.0" },
{ "Microsoft.Extensions.DependencyInjection.Abstractions", "5.0.0.0" },
- { "Microsoft.Extensions.Diagnostics.HealthChecks", "5.0.0.0" },
- { "Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions", "5.0.0.0" },
+ { "Microsoft.Extensions.Diagnostics.HealthChecks", "6.0.0.0" },
+ { "Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions", "6.0.0.0" },
{ "Microsoft.Extensions.FileProviders.Abstractions", "5.0.0.0" },
{ "Microsoft.Extensions.FileProviders.Composite", "5.0.0.0" },
- { "Microsoft.Extensions.FileProviders.Embedded", "5.0.0.0" },
+ { "Microsoft.Extensions.FileProviders.Embedded", "6.0.0.0" },
{ "Microsoft.Extensions.FileProviders.Physical", "5.0.0.0" },
{ "Microsoft.Extensions.FileSystemGlobbing", "5.0.0.0" },
{ "Microsoft.Extensions.Hosting", "5.0.0.0" },
{ "Microsoft.Extensions.Hosting.Abstractions", "5.0.0.0" },
{ "Microsoft.Extensions.Http", "5.0.0.0" },
- { "Microsoft.Extensions.Identity.Core", "5.0.0.0" },
- { "Microsoft.Extensions.Identity.Stores", "5.0.0.0" },
- { "Microsoft.Extensions.Localization", "5.0.0.0" },
- { "Microsoft.Extensions.Localization.Abstractions", "5.0.0.0" },
+ { "Microsoft.Extensions.Identity.Core", "6.0.0.0" },
+ { "Microsoft.Extensions.Identity.Stores", "6.0.0.0" },
+ { "Microsoft.Extensions.Localization", "6.0.0.0" },
+ { "Microsoft.Extensions.Localization.Abstractions", "6.0.0.0" },
{ "Microsoft.Extensions.Logging", "5.0.0.0" },
{ "Microsoft.Extensions.Logging.Abstractions", "5.0.0.0" },
{ "Microsoft.Extensions.Logging.Configuration", "5.0.0.0" },
@@ -265,14 +265,14 @@ static TestData()
{ "Microsoft.Extensions.Logging.EventLog", "5.0.0.0" },
{ "Microsoft.Extensions.Logging.EventSource", "5.0.0.0" },
{ "Microsoft.Extensions.Logging.TraceSource", "5.0.0.0" },
- { "Microsoft.Extensions.ObjectPool", "5.0.0.0" },
+ { "Microsoft.Extensions.ObjectPool", "6.0.0.0" },
{ "Microsoft.Extensions.Options", "5.0.0.0" },
{ "Microsoft.Extensions.Options.ConfigurationExtensions", "5.0.0.0" },
{ "Microsoft.Extensions.Options.DataAnnotations", "5.0.0.0" },
{ "Microsoft.Extensions.Primitives", "5.0.0.0" },
- { "Microsoft.Extensions.WebEncoders", "5.0.0.0" },
- { "Microsoft.JSInterop", "5.0.0.0" },
- { "Microsoft.Net.Http.Headers", "5.0.0.0" },
+ { "Microsoft.Extensions.WebEncoders", "6.0.0.0" },
+ { "Microsoft.JSInterop", "6.0.0.0" },
+ { "Microsoft.Net.Http.Headers", "6.0.0.0" },
{ "Microsoft.Win32.Registry", "5.0.0.0" },
{ "System.Diagnostics.EventLog", "5.0.0.0" },
{ "System.IO.Pipelines", "5.0.0.0" },
@@ -292,6 +292,8 @@ static TestData()
public static string GetSharedFxVersion() => GetTestDataValue("SharedFxVersion");
+ public static string GetDefaultNetCoreTargetFramework() => GetTestDataValue("DefaultNetCoreTargetFramework");
+
public static string GetMicrosoftNETCoreAppPackageVersion() => GetTestDataValue("MicrosoftNETCoreAppRuntimeVersion");
public static string GetReferencePackSharedFxVersion() => GetTestDataValue("ReferencePackSharedFxVersion");
diff --git a/src/Grpc/test/InteropTests/InteropTests.cs b/src/Grpc/test/InteropTests/InteropTests.cs
index 040ccc939188..8e4437b66f4c 100644
--- a/src/Grpc/test/InteropTests/InteropTests.cs
+++ b/src/Grpc/test/InteropTests/InteropTests.cs
@@ -29,18 +29,15 @@ public InteropTests(ITestOutputHelper output)
public Task EmptyUnary() => InteropTestCase("empty_unary");
[Fact]
- [QuarantinedTest]
public Task LargeUnary() => InteropTestCase("large_unary");
[Fact]
- [QuarantinedTest]
public Task ClientStreaming() => InteropTestCase("client_streaming");
[Fact]
public Task ServerStreaming() => InteropTestCase("server_streaming");
[Fact]
- [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/22101")]
public Task PingPong() => InteropTestCase("ping_pong");
[Fact]
@@ -56,7 +53,6 @@ public InteropTests(ITestOutputHelper output)
public Task TimeoutOnSleepingServer() => InteropTestCase("timeout_on_sleeping_server");
[Fact]
- [QuarantinedTest]
public Task CustomMetadata() => InteropTestCase("custom_metadata");
[Fact]
@@ -72,15 +68,12 @@ public InteropTests(ITestOutputHelper output)
public Task UnimplementedMethod() => InteropTestCase("unimplemented_method");
[Fact]
- [QuarantinedTest("Server is getting 'identity' encoding. Will resolve in gRPC project when updated SDK is available.")]
public Task ClientCompressedUnary() => InteropTestCase("client_compressed_unary");
[Fact]
- [QuarantinedTest("Server is getting 'identity' encoding. Will resolve in gRPC project when updated SDK is available.")]
public Task ClientCompressedStreaming() => InteropTestCase("client_compressed_streaming");
[Fact]
- [QuarantinedTest]
public Task ServerCompressedUnary() => InteropTestCase("server_compressed_unary");
[Fact]
diff --git a/src/Grpc/test/testassets/InteropClient/InteropClient.cs b/src/Grpc/test/testassets/InteropClient/InteropClient.cs
index 2b5cb6519623..c522f9915e94 100644
--- a/src/Grpc/test/testassets/InteropClient/InteropClient.cs
+++ b/src/Grpc/test/testassets/InteropClient/InteropClient.cs
@@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
@@ -879,8 +880,8 @@ private static Metadata CreateTestMetadata()
// Consider providing ca file in a different format and removing method
private byte[]? GetBytesFromPem(string pemString, string section)
{
- var header = string.Format("-----BEGIN {0}-----", section);
- var footer = string.Format("-----END {0}-----", section);
+ var header = string.Format(CultureInfo.InvariantCulture, "-----BEGIN {0}-----", section);
+ var footer = string.Format(CultureInfo.InvariantCulture, "-----END {0}-----", section);
var start = pemString.IndexOf(header, StringComparison.Ordinal);
if (start == -1)
diff --git a/src/Hosting/Hosting/src/Internal/ConfigureBuilder.cs b/src/Hosting/Hosting/src/Internal/ConfigureBuilder.cs
index e391acd0f3e3..0de9cdedf316 100644
--- a/src/Hosting/Hosting/src/Internal/ConfigureBuilder.cs
+++ b/src/Hosting/Hosting/src/Internal/ConfigureBuilder.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Globalization;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
@@ -44,6 +45,7 @@ private void Invoke(object instance, IApplicationBuilder builder)
catch (Exception ex)
{
throw new Exception(string.Format(
+ CultureInfo.InvariantCulture,
"Could not resolve a service of type '{0}' for the parameter '{1}' of method '{2}' on type '{3}'.",
parameterInfo.ParameterType.FullName,
parameterInfo.Name,
diff --git a/src/Hosting/Hosting/src/Internal/HostingEventSource.cs b/src/Hosting/Hosting/src/Internal/HostingEventSource.cs
index 6fcfa6726060..10420aaa75e6 100644
--- a/src/Hosting/Hosting/src/Internal/HostingEventSource.cs
+++ b/src/Hosting/Hosting/src/Internal/HostingEventSource.cs
@@ -87,23 +87,23 @@ protected override void OnEventCommand(EventCommandEventArgs command)
// This is the convention for initializing counters in the RuntimeEventSource (lazily on the first enable command).
// They aren't disabled afterwards...
- _requestsPerSecondCounter ??= new IncrementingPollingCounter("requests-per-second", this, () => _totalRequests)
+ _requestsPerSecondCounter ??= new IncrementingPollingCounter("requests-per-second", this, () => Volatile.Read(ref _totalRequests))
{
DisplayName = "Request Rate",
DisplayRateTimeScale = TimeSpan.FromSeconds(1)
};
- _totalRequestsCounter ??= new PollingCounter("total-requests", this, () => _totalRequests)
+ _totalRequestsCounter ??= new PollingCounter("total-requests", this, () => Volatile.Read(ref _totalRequests))
{
DisplayName = "Total Requests",
};
- _currentRequestsCounter ??= new PollingCounter("current-requests", this, () => _currentRequests)
+ _currentRequestsCounter ??= new PollingCounter("current-requests", this, () => Volatile.Read(ref _currentRequests))
{
DisplayName = "Current Requests"
};
- _failedRequestsCounter ??= new PollingCounter("failed-requests", this, () => _failedRequests)
+ _failedRequestsCounter ??= new PollingCounter("failed-requests", this, () => Volatile.Read(ref _failedRequests))
{
DisplayName = "Failed Requests"
};
diff --git a/src/Hosting/Hosting/src/Internal/StartupLoader.cs b/src/Hosting/Hosting/src/Internal/StartupLoader.cs
index 163c94226976..0b5b774a2b8d 100644
--- a/src/Hosting/Hosting/src/Internal/StartupLoader.cs
+++ b/src/Hosting/Hosting/src/Internal/StartupLoader.cs
@@ -36,7 +36,7 @@ internal class StartupLoader
// ConfigureContainer
// ConfigureContainerFilter2
// ConfigureContainerFilter1
- //
+ //
// If the Startup class ConfigureServices returns an and there is at least an registered we
// throw as the filters can't be applied.
public static StartupMethods LoadMethods(IServiceProvider hostingServiceProvider, [DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Type startupType, string environmentName, object instance = null)
@@ -228,15 +228,17 @@ public static Type FindStartupType(string startupAssemblyName, string environmen
if (string.IsNullOrEmpty(startupAssemblyName))
{
throw new ArgumentException(
- string.Format("A startup method, startup type or startup assembly is required. If specifying an assembly, '{0}' cannot be null or empty.",
- nameof(startupAssemblyName)),
- nameof(startupAssemblyName));
+ string.Format(
+ CultureInfo.CurrentCulture,
+ "A startup method, startup type or startup assembly is required. If specifying an assembly, '{0}' cannot be null or empty.",
+ nameof(startupAssemblyName)),
+ nameof(startupAssemblyName));
}
var assembly = Assembly.Load(new AssemblyName(startupAssemblyName));
if (assembly == null)
{
- throw new InvalidOperationException(String.Format("The assembly '{0}' failed to load.", startupAssemblyName));
+ throw new InvalidOperationException($"The assembly '{startupAssemblyName}' failed to load.");
}
var startupNameWithEnv = "Startup" + environmentName;
@@ -266,7 +268,9 @@ public static Type FindStartupType(string startupAssemblyName, string environmen
if (type == null)
{
- throw new InvalidOperationException(String.Format("A type named '{0}' or '{1}' could not be found in assembly '{2}'.",
+ throw new InvalidOperationException(string.Format(
+ CultureInfo.CurrentCulture,
+ "A type named '{0}' or '{1}' could not be found in assembly '{2}'.",
startupNameWithEnv,
startupNameWithoutEnv,
startupAssemblyName));
@@ -308,14 +312,14 @@ private static MethodInfo FindMethod([DynamicallyAccessedMembers(StartupLinkerOp
var selectedMethods = methods.Where(method => method.Name.Equals(methodNameWithEnv, StringComparison.OrdinalIgnoreCase)).ToList();
if (selectedMethods.Count > 1)
{
- throw new InvalidOperationException(string.Format("Having multiple overloads of method '{0}' is not supported.", methodNameWithEnv));
+ throw new InvalidOperationException($"Having multiple overloads of method '{methodNameWithEnv}' is not supported.");
}
if (selectedMethods.Count == 0)
{
selectedMethods = methods.Where(method => method.Name.Equals(methodNameWithNoEnv, StringComparison.OrdinalIgnoreCase)).ToList();
if (selectedMethods.Count > 1)
{
- throw new InvalidOperationException(string.Format("Having multiple overloads of method '{0}' is not supported.", methodNameWithNoEnv));
+ throw new InvalidOperationException($"Having multiple overloads of method '{methodNameWithNoEnv}' is not supported.");
}
}
@@ -324,7 +328,9 @@ private static MethodInfo FindMethod([DynamicallyAccessedMembers(StartupLinkerOp
{
if (required)
{
- throw new InvalidOperationException(string.Format("A public method named '{0}' or '{1}' could not be found in the '{2}' type.",
+ throw new InvalidOperationException(string.Format(
+ CultureInfo.CurrentCulture,
+ "A public method named '{0}' or '{1}' could not be found in the '{2}' type.",
methodNameWithEnv,
methodNameWithNoEnv,
startupType.FullName));
@@ -336,7 +342,9 @@ private static MethodInfo FindMethod([DynamicallyAccessedMembers(StartupLinkerOp
{
if (required)
{
- throw new InvalidOperationException(string.Format("The '{0}' method in the type '{1}' must have a return type of '{2}'.",
+ throw new InvalidOperationException(string.Format(
+ CultureInfo.CurrentCulture,
+ "The '{0}' method in the type '{1}' must have a return type of '{2}'.",
methodInfo.Name,
startupType.FullName,
returnType.Name));
diff --git a/src/Hosting/Hosting/src/StaticWebAssets/StaticWebAssetsFileProvider.cs b/src/Hosting/Hosting/src/StaticWebAssets/StaticWebAssetsFileProvider.cs
index 8e2b9a5c082f..5a9d3a58101e 100644
--- a/src/Hosting/Hosting/src/StaticWebAssets/StaticWebAssetsFileProvider.cs
+++ b/src/Hosting/Hosting/src/StaticWebAssets/StaticWebAssetsFileProvider.cs
@@ -96,7 +96,7 @@ public IChangeToken Watch(string filter)
private static string NormalizePath(string path)
{
path = path.Replace('\\', '/');
- return path.StartsWith("/") ? path : "/" + path;
+ return path.StartsWith('/') ? path : "/" + path;
}
private bool StartsWithBasePath(string subpath, out PathString rest)
diff --git a/src/Hosting/Hosting/test/HostingApplicationDiagnosticsTests.cs b/src/Hosting/Hosting/test/HostingApplicationDiagnosticsTests.cs
index 8298649bf0f0..dc166044b87e 100644
--- a/src/Hosting/Hosting/test/HostingApplicationDiagnosticsTests.cs
+++ b/src/Hosting/Hosting/test/HostingApplicationDiagnosticsTests.cs
@@ -93,7 +93,7 @@ public void ActivityIsNotCreatedWhenIsEnabledForActivityIsFalse()
diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair =>
{
- eventsFired |= pair.Key.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn");
+ eventsFired |= pair.Key.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn", StringComparison.Ordinal);
}), (s, o, arg3) =>
{
if (s == "Microsoft.AspNetCore.Hosting.HttpRequestIn")
@@ -127,7 +127,7 @@ public void ActivityIsCreatedButNotLoggedWhenIsEnabledForActivityStartIsFalse()
diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair =>
{
- eventsFired |= pair.Key.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn");
+ eventsFired |= pair.Key.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn", StringComparison.Ordinal);
}), (s, o, arg3) =>
{
if (s == "Microsoft.AspNetCore.Hosting.HttpRequestIn")
@@ -257,7 +257,7 @@ public void ActivityIsAvailibleDuringRequest()
diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => { }),
s =>
{
- if (s.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn"))
+ if (s.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn", StringComparison.Ordinal))
{
return true;
}
@@ -279,7 +279,7 @@ public void ActivityParentIdAndBaggeReadFromHeaders()
diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => { }),
s =>
{
- if (s.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn"))
+ if (s.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn", StringComparison.Ordinal))
{
return true;
}
@@ -310,7 +310,7 @@ public void ActivityBaggagePreservesItemsOrder()
diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => { }),
s =>
{
- if (s.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn"))
+ if (s.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn", StringComparison.Ordinal))
{
return true;
}
@@ -347,7 +347,7 @@ public void ActivityBaggageValuesAreUrlDecodedFromHeaders()
diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => { }),
s =>
{
- if (s.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn"))
+ if (s.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn", StringComparison.Ordinal))
{
return true;
}
@@ -376,7 +376,7 @@ public void ActivityTraceParentAndTraceStateFromHeaders()
diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => { }),
s =>
{
- if (s.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn"))
+ if (s.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn", StringComparison.Ordinal))
{
return true;
}
diff --git a/src/Hosting/Server.IntegrationTesting/src/Common/DeploymentParameters.cs b/src/Hosting/Server.IntegrationTesting/src/Common/DeploymentParameters.cs
index 0e26e772a0fd..74dbe8697527 100644
--- a/src/Hosting/Server.IntegrationTesting/src/Common/DeploymentParameters.cs
+++ b/src/Hosting/Server.IntegrationTesting/src/Common/DeploymentParameters.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Reflection;
@@ -61,7 +62,7 @@ public DeploymentParameters(
if (!Directory.Exists(applicationPath))
{
- throw new DirectoryNotFoundException(string.Format("Application path {0} does not exist.", applicationPath));
+ throw new DirectoryNotFoundException($"Application path {applicationPath} does not exist.");
}
ApplicationPath = applicationPath;
@@ -187,12 +188,13 @@ public DeploymentParameters(DeploymentParameters parameters)
public override string ToString()
{
return string.Format(
- "[Variation] :: ServerType={0}, Runtime={1}, Arch={2}, BaseUrlHint={3}, Publish={4}",
- ServerType,
- RuntimeFlavor,
- RuntimeArchitecture,
- ApplicationBaseUriHint,
- PublishApplicationBeforeDeployment);
+ CultureInfo.InvariantCulture,
+ "[Variation] :: ServerType={0}, Runtime={1}, Arch={2}, BaseUrlHint={3}, Publish={4}",
+ ServerType,
+ RuntimeFlavor,
+ RuntimeArchitecture,
+ ApplicationBaseUriHint,
+ PublishApplicationBeforeDeployment);
}
}
}
diff --git a/src/Hosting/Server.IntegrationTesting/src/Common/DotNetCommands.cs b/src/Hosting/Server.IntegrationTesting/src/Common/DotNetCommands.cs
index 1bc54b4d555d..e6d4924076f3 100644
--- a/src/Hosting/Server.IntegrationTesting/src/Common/DotNetCommands.cs
+++ b/src/Hosting/Server.IntegrationTesting/src/Common/DotNetCommands.cs
@@ -33,7 +33,7 @@ public static string GetDotNetHome()
}
else if (!string.IsNullOrEmpty(dotnetRoot))
{
- if (dotnetRoot.EndsWith("x64"))
+ if (dotnetRoot.EndsWith("x64", StringComparison.Ordinal))
{
// DOTNET_ROOT has x64 appended to the path, which we append again in GetDotNetInstallDir
result = dotnetRoot[0..^3];
diff --git a/src/Hosting/Server.IntegrationTesting/src/Deployers/ApplicationDeployer.cs b/src/Hosting/Server.IntegrationTesting/src/Deployers/ApplicationDeployer.cs
index c6464a9833b4..5aa7c1190840 100644
--- a/src/Hosting/Server.IntegrationTesting/src/Deployers/ApplicationDeployer.cs
+++ b/src/Hosting/Server.IntegrationTesting/src/Deployers/ApplicationDeployer.cs
@@ -54,7 +54,7 @@ private void ValidateParameters()
if (!Directory.Exists(DeploymentParameters.ApplicationPath))
{
- throw new DirectoryNotFoundException(string.Format("Application path {0} does not exist.", DeploymentParameters.ApplicationPath));
+ throw new DirectoryNotFoundException($"Application path {DeploymentParameters.ApplicationPath} does not exist.");
}
if (string.IsNullOrEmpty(DeploymentParameters.ApplicationName))
diff --git a/src/Hosting/Server.IntegrationTesting/src/Deployers/ApplicationDeployerFactory.cs b/src/Hosting/Server.IntegrationTesting/src/Deployers/ApplicationDeployerFactory.cs
index 959f4ffeedec..8d5799faf040 100644
--- a/src/Hosting/Server.IntegrationTesting/src/Deployers/ApplicationDeployerFactory.cs
+++ b/src/Hosting/Server.IntegrationTesting/src/Deployers/ApplicationDeployerFactory.cs
@@ -1,7 +1,8 @@
-// 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.
using System;
+using System.Globalization;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Server.IntegrationTesting
@@ -41,8 +42,10 @@ public static ApplicationDeployer Create(DeploymentParameters deploymentParamete
return new NginxDeployer(deploymentParameters, loggerFactory);
default:
throw new NotSupportedException(
- string.Format("Found no deployers suitable for server type '{0}' with the current runtime.",
- deploymentParameters.ServerType)
+ string.Format(
+ CultureInfo.CurrentCulture,
+ "Found no deployers suitable for server type '{0}' with the current runtime.",
+ deploymentParameters.ServerType)
);
}
}
diff --git a/src/Hosting/Server.IntegrationTesting/src/Deployers/NginxDeployer.cs b/src/Hosting/Server.IntegrationTesting/src/Deployers/NginxDeployer.cs
index 262ff80ce89d..90eff1c833df 100644
--- a/src/Hosting/Server.IntegrationTesting/src/Deployers/NginxDeployer.cs
+++ b/src/Hosting/Server.IntegrationTesting/src/Deployers/NginxDeployer.cs
@@ -1,8 +1,9 @@
-// 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.
using System;
using System.Diagnostics;
+using System.Globalization;
using System.IO;
using System.Net;
using System.Net.Http;
@@ -144,7 +145,7 @@ private void SetupNginx(string redirectUri, Uri originalUri)
.Replace("[user]", userName)
.Replace("[errorlog]", errorLog)
.Replace("[accesslog]", accessLog)
- .Replace("[listenPort]", originalUri.Port.ToString() + (_portSelector != null ? " reuseport" : ""))
+ .Replace("[listenPort]", originalUri.Port.ToString(CultureInfo.InvariantCulture) + (_portSelector != null ? " reuseport" : ""))
.Replace("[redirectUri]", redirectUri)
.Replace("[pidFile]", pidFile);
Logger.LogDebug("Using PID file: {pidFile}", pidFile);
diff --git a/src/Hosting/Server.IntegrationTesting/src/xunit/SkipIfEnvironmentVariableNotEnabled.cs b/src/Hosting/Server.IntegrationTesting/src/xunit/SkipIfEnvironmentVariableNotEnabled.cs
index caed568f639a..dad8ea3037c8 100644
--- a/src/Hosting/Server.IntegrationTesting/src/xunit/SkipIfEnvironmentVariableNotEnabled.cs
+++ b/src/Hosting/Server.IntegrationTesting/src/xunit/SkipIfEnvironmentVariableNotEnabled.cs
@@ -1,4 +1,4 @@
-// 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.
using System;
@@ -24,7 +24,7 @@ public bool IsMet
{
get
{
- return string.Compare(Environment.GetEnvironmentVariable(_environmentVariableName), "true", ignoreCase: true) == 0;
+ return string.Equals(Environment.GetEnvironmentVariable(_environmentVariableName), "true", StringComparison.OrdinalIgnoreCase);
}
}
@@ -38,4 +38,4 @@ public string SkipReason
public string AdditionalInfo { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/src/Hosting/TestHost/src/ClientHandler.cs b/src/Hosting/TestHost/src/ClientHandler.cs
index 0b8cc69dc289..e31d80e36921 100644
--- a/src/Hosting/TestHost/src/ClientHandler.cs
+++ b/src/Hosting/TestHost/src/ClientHandler.cs
@@ -37,7 +37,7 @@ internal ClientHandler(PathString pathBase, ApplicationWrapper application)
_application = application ?? throw new ArgumentNullException(nameof(application));
// PathString.StartsWithSegments that we use below requires the base path to not end in a slash.
- if (pathBase.HasValue && pathBase.Value.EndsWith("/"))
+ if (pathBase.HasValue && pathBase.Value.EndsWith('/'))
{
pathBase = new PathString(pathBase.Value[..^1]); // All but the last character
}
diff --git a/src/Hosting/TestHost/src/TestServer.cs b/src/Hosting/TestHost/src/TestServer.cs
index 1ba0471c74c4..275a73b69ecb 100644
--- a/src/Hosting/TestHost/src/TestServer.cs
+++ b/src/Hosting/TestHost/src/TestServer.cs
@@ -172,7 +172,7 @@ public async Task SendAsync(Action configureContext, C
request.Host = new HostString(request.Host.Host);
}
var pathBase = PathString.FromUriComponent(BaseAddress);
- if (pathBase.HasValue && pathBase.Value.EndsWith("/"))
+ if (pathBase.HasValue && pathBase.Value.EndsWith('/'))
{
pathBase = new PathString(pathBase.Value[..^1]); // All but the last character.
}
diff --git a/src/Hosting/TestHost/src/WebSocketClient.cs b/src/Hosting/TestHost/src/WebSocketClient.cs
index 1d9b5df6463a..ea3fb80ae904 100644
--- a/src/Hosting/TestHost/src/WebSocketClient.cs
+++ b/src/Hosting/TestHost/src/WebSocketClient.cs
@@ -28,7 +28,7 @@ internal WebSocketClient(PathString pathBase, ApplicationWrapper application)
_application = application ?? throw new ArgumentNullException(nameof(application));
// PathString.StartsWithSegments that we use below requires the base path to not end in a slash.
- if (pathBase.HasValue && pathBase.Value.EndsWith("/"))
+ if (pathBase.HasValue && pathBase.Value.EndsWith('/'))
{
pathBase = new PathString(pathBase.Value[..^1]); // All but the last character.
}
diff --git a/src/Hosting/test/FunctionalTests/ShutdownTests.cs b/src/Hosting/test/FunctionalTests/ShutdownTests.cs
index ca689f8092f9..1434c21d98ff 100644
--- a/src/Hosting/test/FunctionalTests/ShutdownTests.cs
+++ b/src/Hosting/test/FunctionalTests/ShutdownTests.cs
@@ -3,6 +3,7 @@
using System;
using System.Diagnostics;
+using System.Globalization;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
@@ -73,14 +74,14 @@ private async Task ExecuteShutdownTest(string testName, string shutdownMechanic)
{
await deployer.DeployAsync();
- var started = new ManualResetEventSlim();
- var completed = new ManualResetEventSlim();
+ var startedTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
+ var completedTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
var output = string.Empty;
deployer.HostProcess.OutputDataReceived += (sender, args) =>
{
- if (!string.IsNullOrEmpty(args.Data) && args.Data.StartsWith(StartedMessage))
+ if (!string.IsNullOrEmpty(args.Data) && args.Data.StartsWith(StartedMessage, StringComparison.Ordinal))
{
- started.Set();
+ startedTcs.TrySetResult();
output += args.Data.Substring(StartedMessage.Length) + '\n';
}
else
@@ -90,26 +91,30 @@ private async Task ExecuteShutdownTest(string testName, string shutdownMechanic)
if (output.Contains(CompletionMessage))
{
- completed.Set();
+ completedTcs.TrySetResult();
}
};
- started.Wait(50000);
-
- if (!started.IsSet)
+ try
+ {
+ await startedTcs.Task.TimeoutAfter(TimeSpan.FromMinutes(1));
+ }
+ catch (TimeoutException ex)
{
- throw new InvalidOperationException("Application did not start successfully");
+ throw new InvalidOperationException("Timeout while waiting for host process to output started message.", ex);
}
SendSIGINT(deployer.HostProcess.Id);
WaitForExitOrKill(deployer.HostProcess);
- completed.Wait(50000);
-
- if (!started.IsSet)
+ try
+ {
+ await completedTcs.Task.TimeoutAfter(TimeSpan.FromMinutes(1));
+ }
+ catch (TimeoutException ex)
{
- throw new InvalidOperationException($"Application did not write the expected output. The received output is: {output}");
+ throw new InvalidOperationException($"Timeout while waiting for host process to output completion message. The received output is: {output}", ex);
}
output = output.Trim('\n');
@@ -124,7 +129,7 @@ private static void SendSIGINT(int processId)
var startInfo = new ProcessStartInfo
{
FileName = "kill",
- Arguments = processId.ToString(),
+ Arguments = processId.ToString(CultureInfo.InvariantCulture),
RedirectStandardOutput = true,
UseShellExecute = false
};
diff --git a/src/Hosting/test/FunctionalTests/WebHostBuilderTests.cs b/src/Hosting/test/FunctionalTests/WebHostBuilderTests.cs
index a6735ea9e28d..8e5ebd058ed9 100644
--- a/src/Hosting/test/FunctionalTests/WebHostBuilderTests.cs
+++ b/src/Hosting/test/FunctionalTests/WebHostBuilderTests.cs
@@ -1,6 +1,7 @@
// 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.Threading;
using System.Threading.Tasks;
@@ -28,7 +29,7 @@ public async Task InjectedStartup_DefaultApplicationNameIsEntryAssembly(TestVari
{
var logger = loggerFactory.CreateLogger(nameof(InjectedStartup_DefaultApplicationNameIsEntryAssembly));
-// https://github.com/dotnet/aspnetcore/issues/8247
+ // https://github.com/dotnet/aspnetcore/issues/8247
#pragma warning disable 0618
var applicationPath = Path.Combine(TestPathUtilities.GetSolutionRootDirectory("Hosting"), "test", "testassets", "IStartupInjectionAssemblyName");
#pragma warning restore 0618
@@ -44,17 +45,24 @@ public async Task InjectedStartup_DefaultApplicationNameIsEntryAssembly(TestVari
await deployer.DeployAsync();
string output = string.Empty;
- var mre = new ManualResetEventSlim();
+ var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
deployer.HostProcess.OutputDataReceived += (sender, args) =>
{
if (!string.IsNullOrWhiteSpace(args.Data))
{
output += args.Data + '\n';
- mre.Set();
+ tcs.TrySetResult();
}
};
- mre.Wait(50000);
+ try
+ {
+ await tcs.Task.TimeoutAfter(TimeSpan.FromMinutes(1));
+ }
+ catch (TimeoutException ex)
+ {
+ throw new InvalidOperationException("Timeout while waiting for output from host process.", ex);
+ }
output = output.Trim('\n');
diff --git a/src/Html/Abstractions/test/HtmlContentBuilderExtensionsTest.cs b/src/Html/Abstractions/test/HtmlContentBuilderExtensionsTest.cs
index c14daeeebb69..5fc4a8d03b48 100644
--- a/src/Html/Abstractions/test/HtmlContentBuilderExtensionsTest.cs
+++ b/src/Html/Abstractions/test/HtmlContentBuilderExtensionsTest.cs
@@ -347,7 +347,7 @@ public void Builder_AppendFormat_WithDifferentCurrentCulture()
var builder = new TestHtmlContentBuilder();
// Act
- builder.AppendFormat(CultureInfo.CurrentCulture, "{0:D}", DateTime.Parse("01/02/2015"));
+ builder.AppendFormat(CultureInfo.CurrentCulture, "{0:D}", new DateTime(2015, 02, 01));
// Assert
Assert.Equal(
diff --git a/src/Html/Abstractions/test/HtmlFormattableStringTest.cs b/src/Html/Abstractions/test/HtmlFormattableStringTest.cs
index 64e000751ec4..bc4be7c1064c 100644
--- a/src/Html/Abstractions/test/HtmlFormattableStringTest.cs
+++ b/src/Html/Abstractions/test/HtmlFormattableStringTest.cs
@@ -196,7 +196,7 @@ public void HtmlFormattableString_UsesPassedInCulture()
public void HtmlFormattableString_UsesCurrentCulture()
{
// Arrange
- var formattableString = new HtmlFormattableString("{0:D}", DateTime.Parse("01/02/2015"));
+ var formattableString = new HtmlFormattableString("{0:D}", new DateTime(2015, 02, 01));
// Act
var result = HtmlContentToString(formattableString);
diff --git a/src/Http/Headers/src/HeaderUtilities.cs b/src/Http/Headers/src/HeaderUtilities.cs
index c1e3ad90d42b..cda9cf82b4f2 100644
--- a/src/Http/Headers/src/HeaderUtilities.cs
+++ b/src/Http/Headers/src/HeaderUtilities.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using System.Globalization;
using Microsoft.Extensions.Primitives;
@@ -228,7 +229,7 @@ private static int AdvanceCacheDirectiveIndex(int current, string headerValue)
/// .
///
// e.g. { "headerValue=10, targetHeaderValue=30" }
- public static bool TryParseSeconds(StringValues headerValues, string targetValue, out TimeSpan? value)
+ public static bool TryParseSeconds(StringValues headerValues, string targetValue, [NotNullWhen(true)] out TimeSpan? value)
{
if (StringValues.IsNullOrEmpty(headerValues) || string.IsNullOrEmpty(targetValue))
{
@@ -597,7 +598,7 @@ public static string FormatDate(DateTimeOffset dateTime, bool quoted)
});
}
- return dateTime.ToString("r");
+ return dateTime.ToString("r", CultureInfo.InvariantCulture);
}
public static StringSegment RemoveQuotes(StringSegment input)
diff --git a/src/Http/Headers/src/MediaTypeHeaderValue.cs b/src/Http/Headers/src/MediaTypeHeaderValue.cs
index af2bba6e2207..2ba881539b6a 100644
--- a/src/Http/Headers/src/MediaTypeHeaderValue.cs
+++ b/src/Http/Headers/src/MediaTypeHeaderValue.cs
@@ -437,6 +437,32 @@ public MediaTypeHeaderValue CopyAsReadOnly()
return other;
}
+ ///
+ /// Gets a value indicating whether is a subset of
+ /// this in terms of type/subType. A "subset" is defined as the same or a more specific media type
+ /// according to the precedence described in https://www.ietf.org/rfc/rfc2068.txt section 14.1, Accept.
+ ///
+ /// The to compare.
+ ///
+ /// A value indicating whether is a subset of
+ /// this .
+ ///
+ ///
+ /// For example "multipart/mixed" is a subset of "multipart/mixed",
+ /// "multipart/*", and "*/*" but not "multipart/message."
+ ///
+ public bool MatchesMediaType(StringSegment otherMediaType)
+ {
+ if (StringSegment.IsNullOrEmpty(otherMediaType))
+ {
+ return false;
+ }
+ GetMediaTypeExpressionLength(otherMediaType, 0, out var mediaType);
+
+ return MatchesType(mediaType) && MatchesSubtype(mediaType);
+ }
+
+
public override string ToString()
{
var builder = new StringBuilder();
@@ -645,6 +671,14 @@ private bool MatchesType(MediaTypeHeaderValue set)
set.Type.Equals(Type, StringComparison.OrdinalIgnoreCase);
}
+ private bool MatchesType(StringSegment mediaType)
+ {
+ var type = mediaType.Subsegment(0, mediaType.IndexOf(ForwardSlashCharacter));
+
+ return MatchesAllTypes ||
+ Type.Equals(type, StringComparison.OrdinalIgnoreCase);
+ }
+
private bool MatchesSubtype(MediaTypeHeaderValue set)
{
if (set.MatchesAllSubTypes)
@@ -672,18 +706,79 @@ private bool MatchesSubtype(MediaTypeHeaderValue set)
}
}
+ private bool MatchesSubtype(StringSegment mediaType)
+ {
+ if (MatchesAllSubTypes)
+ {
+ return true;
+ }
+
+ var subType = mediaType.Subsegment(mediaType.IndexOf(ForwardSlashCharacter) + 1);
+
+ StringSegment suffix;
+ var startOfSuffix = subType.LastIndexOf(PlusCharacter);
+ if (startOfSuffix == -1)
+ {
+ suffix = default(StringSegment);
+ }
+ else
+ {
+ suffix = subType.Subsegment(startOfSuffix + 1);
+ }
+
+ if (Suffix.HasValue)
+ {
+ if (suffix.HasValue)
+ {
+ return MatchesSubtypeWithoutSuffix(subType, startOfSuffix) && MatchesSubtypeSuffix(suffix);
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ // If this subtype or suffix matches the subtype of the mediaType,
+ // it is considered a subtype.
+ // Ex: application/json > application/val+json
+ return MatchesEitherSubtypeOrSuffix(subType, suffix);
+ }
+ }
+
private bool MatchesSubtypeWithoutSuffix(MediaTypeHeaderValue set)
{
return set.MatchesAllSubTypesWithoutSuffix ||
set.SubTypeWithoutSuffix.Equals(SubTypeWithoutSuffix, StringComparison.OrdinalIgnoreCase);
}
+ private bool MatchesSubtypeWithoutSuffix(StringSegment subType, int startOfSuffix)
+ {
+ StringSegment subTypeWithoutSuffix;
+ if (startOfSuffix == -1)
+ {
+ subTypeWithoutSuffix = subType;
+ }
+ else
+ {
+ subTypeWithoutSuffix = subType.Subsegment(0, startOfSuffix);
+ }
+ return SubTypeWithoutSuffix.Equals(WildcardString, StringComparison.OrdinalIgnoreCase) ||
+ SubTypeWithoutSuffix.Equals(subTypeWithoutSuffix, StringComparison.OrdinalIgnoreCase);
+ }
+
private bool MatchesEitherSubtypeOrSuffix(MediaTypeHeaderValue set)
{
return set.SubType.Equals(SubType, StringComparison.OrdinalIgnoreCase) ||
set.SubType.Equals(Suffix, StringComparison.OrdinalIgnoreCase);
}
+ private bool MatchesEitherSubtypeOrSuffix(StringSegment subType, StringSegment suffix)
+ {
+ return subType.Equals(SubType, StringComparison.OrdinalIgnoreCase) ||
+ SubType.Equals(suffix, StringComparison.OrdinalIgnoreCase);
+ }
+
private bool MatchesParameters(MediaTypeHeaderValue set)
{
if (set._parameters != null && set._parameters.Count != 0)
@@ -728,5 +823,12 @@ private bool MatchesSubtypeSuffix(MediaTypeHeaderValue set)
// because there's no clear use case for it.
return set.Suffix.Equals(Suffix, StringComparison.OrdinalIgnoreCase);
}
+
+ private bool MatchesSubtypeSuffix(StringSegment suffix)
+ {
+ // We don't have support for wildcards on suffixes alone (e.g., "application/entity+*")
+ // because there's no clear use case for it.
+ return Suffix.Equals(suffix, StringComparison.OrdinalIgnoreCase);
+ }
}
}
diff --git a/src/Http/Headers/src/PublicAPI.Unshipped.txt b/src/Http/Headers/src/PublicAPI.Unshipped.txt
index d79c9d7fba76..ec721101b5b4 100644
--- a/src/Http/Headers/src/PublicAPI.Unshipped.txt
+++ b/src/Http/Headers/src/PublicAPI.Unshipped.txt
@@ -94,6 +94,7 @@ Microsoft.Net.Http.Headers.MediaTypeHeaderValue.IsSubsetOf(Microsoft.Net.Http.He
Microsoft.Net.Http.Headers.MediaTypeHeaderValue.MatchesAllSubTypes.get -> bool
Microsoft.Net.Http.Headers.MediaTypeHeaderValue.MatchesAllSubTypesWithoutSuffix.get -> bool
Microsoft.Net.Http.Headers.MediaTypeHeaderValue.MatchesAllTypes.get -> bool
+Microsoft.Net.Http.Headers.MediaTypeHeaderValue.MatchesMediaType(Microsoft.Extensions.Primitives.StringSegment otherMediaType) -> bool
Microsoft.Net.Http.Headers.MediaTypeHeaderValue.MediaType.get -> Microsoft.Extensions.Primitives.StringSegment
Microsoft.Net.Http.Headers.MediaTypeHeaderValue.MediaType.set -> void
Microsoft.Net.Http.Headers.MediaTypeHeaderValue.MediaTypeHeaderValue(Microsoft.Extensions.Primitives.StringSegment mediaType) -> void
diff --git a/src/Http/Headers/src/SetCookieHeaderValue.cs b/src/Http/Headers/src/SetCookieHeaderValue.cs
index 1afee5760fb5..ba6acf5b6fc2 100644
--- a/src/Http/Headers/src/SetCookieHeaderValue.cs
+++ b/src/Http/Headers/src/SetCookieHeaderValue.cs
@@ -22,9 +22,9 @@ public class SetCookieHeaderValue
private const string SecureToken = "secure";
// RFC Draft: https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00
private const string SameSiteToken = "samesite";
- private static readonly string SameSiteNoneToken = SameSiteMode.None.ToString().ToLower();
- private static readonly string SameSiteLaxToken = SameSiteMode.Lax.ToString().ToLower();
- private static readonly string SameSiteStrictToken = SameSiteMode.Strict.ToString().ToLower();
+ private static readonly string SameSiteNoneToken = SameSiteMode.None.ToString().ToLowerInvariant();
+ private static readonly string SameSiteLaxToken = SameSiteMode.Lax.ToString().ToLowerInvariant();
+ private static readonly string SameSiteStrictToken = SameSiteMode.Strict.ToString().ToLowerInvariant();
private const string HttpOnlyToken = "httponly";
private const string SeparatorToken = "; ";
diff --git a/src/Http/Headers/test/ContentDispositionHeaderValueTest.cs b/src/Http/Headers/test/ContentDispositionHeaderValueTest.cs
index 4d0b1b7cf78f..7fe258e3de9c 100644
--- a/src/Http/Headers/test/ContentDispositionHeaderValueTest.cs
+++ b/src/Http/Headers/test/ContentDispositionHeaderValueTest.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using Xunit;
@@ -252,7 +253,7 @@ public void SetHttpFileName_ShouldSanitizeFileNameWhereNeeded(string httpFileNam
public void Dates_AddDateParameterThenUseProperty_ParametersEntryIsOverwritten()
{
string validDateString = "\"Tue, 15 Nov 1994 08:12:31 GMT\"";
- DateTimeOffset validDate = DateTimeOffset.Parse("Tue, 15 Nov 1994 08:12:31 GMT");
+ DateTimeOffset validDate = DateTimeOffset.Parse("Tue, 15 Nov 1994 08:12:31 GMT", CultureInfo.InvariantCulture);
var contentDisposition = new ContentDispositionHeaderValue("inline");
diff --git a/src/Http/Headers/test/MediaTypeHeaderValueTest.cs b/src/Http/Headers/test/MediaTypeHeaderValueTest.cs
index 025dcab4b1a7..8a67a2dec90d 100644
--- a/src/Http/Headers/test/MediaTypeHeaderValueTest.cs
+++ b/src/Http/Headers/test/MediaTypeHeaderValueTest.cs
@@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Primitives;
+using NuGet.Frameworks;
using Xunit;
namespace Microsoft.Net.Http.Headers
@@ -683,6 +684,115 @@ public void TryParseStrictList_WithSomeInvalidValues_ReturnsFalse()
Assert.False(MediaTypeHeaderValue.TryParseStrictList(inputs, out var results));
}
+ [Theory]
+ [InlineData("*/*;", "*/*")]
+ [InlineData("text/*", "text/*")]
+ [InlineData("text/*", "text/plain")]
+ [InlineData("*/*;", "text/plain")]
+ [InlineData("text/plain", "text/plain")]
+ [InlineData("text/plain;", "text/plain")]
+ [InlineData("text/plain;", "TEXT/PLAIN")]
+ public void MatchesMediaType_PositiveCases(string mediaType1, string mediaType2)
+ {
+ // Arrange
+ var parsedMediaType1 = MediaTypeHeaderValue.Parse(mediaType1);
+ var parsedMediaType2 = MediaTypeHeaderValue.Parse(mediaType2);
+
+ // Act
+ var matches = parsedMediaType1.MatchesMediaType(mediaType2);
+ var isSubsetOf = parsedMediaType2.IsSubsetOf(parsedMediaType1);
+
+ // Assert
+ Assert.True(matches);
+ //Make sure that MatchesMediaType produces consistent result with IsSubsetOf
+ Assert.Equal(matches, isSubsetOf);
+ }
+
+ [Theory]
+ [InlineData("application/html", "text/*")]
+ [InlineData("application/json", "application/html")]
+ [InlineData("text/plain;", "*/*")]
+ public void MatchesMediaType_NegativeCases(string mediaType1, string mediaType2)
+ {
+ // Arrange
+ var parsedMediaType1 = MediaTypeHeaderValue.Parse(mediaType1);
+ var parsedMediaType2 = MediaTypeHeaderValue.Parse(mediaType2);
+
+ // Act
+ var matches = parsedMediaType1.MatchesMediaType(mediaType2);
+ var isSubsetOf = parsedMediaType2.IsSubsetOf(parsedMediaType1);
+
+ // Assert
+ Assert.False(matches);
+ //Make sure that MatchesMediaType produces consistent result with IsSubsetOf
+ Assert.Equal(matches, isSubsetOf);
+ }
+
+ [Theory]
+ [InlineData("application/entity+json", "application/entity+json")]
+ [InlineData("application/json", "application/entity+json")]
+ [InlineData("application/*+json", "application/entity+json")]
+ [InlineData("application/*+json", "application/*+json")]
+ [InlineData("application/json", "application/problem+json")]
+ [InlineData("application/json", "application/vnd.restful+json")]
+ [InlineData("application/*", "application/*+JSON")]
+ [InlineData("application/*", "application/entity+JSON")]
+ [InlineData("*/*", "application/entity+json")]
+ public void MatchesMediaTypeWithSuffixes_PositiveCases(string mediaType1, string mediaType2)
+ {
+ // Arrange
+ var parsedMediaType1 = MediaTypeHeaderValue.Parse(mediaType1);
+ var parsedMediaType2 = MediaTypeHeaderValue.Parse(mediaType2);
+
+ // Act
+ var result = parsedMediaType1.MatchesMediaType(mediaType2);
+ var isSubsetOf = parsedMediaType2.IsSubsetOf(parsedMediaType1);
+
+ // Assert
+ Assert.True(result);
+ //Make sure that MatchesMediaType produces consistent result with IsSubsetOf
+ Assert.Equal(result, isSubsetOf);
+ }
+
+ [Theory]
+ [InlineData("application/entity+json", "application/entity+txt")]
+ [InlineData("application/entity+json", "application/json")]
+ [InlineData("application/entity+json", "application/entity.v2+json")]
+ [InlineData("application/*+json", "application/entity+txt")]
+ [InlineData("application/*+*", "application/json")]
+ [InlineData("application/entity", "application/entity+")]
+ [InlineData("application/entity+*", "application/entity+json")] // We don't allow suffixes to be wildcards
+ [InlineData("application/*+*", "application/entity+json")] // We don't allow suffixes to be wildcards
+ [InlineData("application/entity+json", "application/entity")]
+ public void MatchesMediaTypeWithSuffixes_NegativeCases(string mediaType1, string mediaType2)
+ {
+ // Arrange
+ var parsedMediaType1 = MediaTypeHeaderValue.Parse(mediaType1);
+ var parsedMediaType2 = MediaTypeHeaderValue.Parse(mediaType2);
+
+ // Arrange
+ var result = parsedMediaType1.MatchesMediaType(mediaType2);
+ var isSubsetOf = parsedMediaType2.IsSubsetOf(parsedMediaType1);
+
+ // Assert
+ Assert.False(result);
+ //Make sure that MatchesMediaType produces consistent result with IsSubsetOf
+ Assert.Equal(result, isSubsetOf);
+ }
+
+ [Fact]
+ public void MatchesMediaType_IgnoresParameters()
+ {
+ // Arrange
+ var parsedMediaType1 = MediaTypeHeaderValue.Parse("application/json;param=1");
+
+ // Arrange
+ var result = parsedMediaType1.MatchesMediaType("application/json;param2=1");
+
+ // Assert
+ Assert.True(result);
+ }
+
[Theory]
[InlineData("*/*;", "*/*")]
[InlineData("text/*", "text/*")]
diff --git a/src/Http/Http.Abstractions/src/Extensions/UseMiddlewareExtensions.cs b/src/Http/Http.Abstractions/src/Extensions/UseMiddlewareExtensions.cs
index 164b601d57f8..a4afef8b157a 100644
--- a/src/Http/Http.Abstractions/src/Extensions/UseMiddlewareExtensions.cs
+++ b/src/Http/Http.Abstractions/src/Extensions/UseMiddlewareExtensions.cs
@@ -33,7 +33,7 @@ public static class UseMiddlewareExtensions
/// The instance.
/// The arguments to pass to the middleware type instance's constructor.
/// The instance.
- public static IApplicationBuilder UseMiddleware<[DynamicallyAccessedMembers(MiddlewareAccessibility)]TMiddleware>(this IApplicationBuilder app, params object[] args)
+ public static IApplicationBuilder UseMiddleware<[DynamicallyAccessedMembers(MiddlewareAccessibility)]TMiddleware>(this IApplicationBuilder app, params object?[] args)
{
return app.UseMiddleware(typeof(TMiddleware), args);
}
@@ -45,7 +45,7 @@ public static class UseMiddlewareExtensions
/// The middleware type.
/// The arguments to pass to the middleware type instance's constructor.
/// The instance.
- public static IApplicationBuilder UseMiddleware(this IApplicationBuilder app, [DynamicallyAccessedMembers(MiddlewareAccessibility)] Type middleware, params object[] args)
+ public static IApplicationBuilder UseMiddleware(this IApplicationBuilder app, [DynamicallyAccessedMembers(MiddlewareAccessibility)] Type middleware, params object?[] args)
{
if (typeof(IMiddleware).GetTypeInfo().IsAssignableFrom(middleware.GetTypeInfo()))
{
diff --git a/src/Http/Http.Abstractions/src/PublicAPI.Unshipped.txt b/src/Http/Http.Abstractions/src/PublicAPI.Unshipped.txt
index 0ea10c72ef1b..b6e7a2ef4c86 100644
--- a/src/Http/Http.Abstractions/src/PublicAPI.Unshipped.txt
+++ b/src/Http/Http.Abstractions/src/PublicAPI.Unshipped.txt
@@ -340,8 +340,8 @@ static Microsoft.AspNetCore.Builder.MapExtensions.Map(this Microsoft.AspNetCore.
static Microsoft.AspNetCore.Builder.MapWhenExtensions.MapWhen(this Microsoft.AspNetCore.Builder.IApplicationBuilder! app, System.Func! predicate, System.Action! configuration) -> Microsoft.AspNetCore.Builder.IApplicationBuilder!
static Microsoft.AspNetCore.Builder.RunExtensions.Run(this Microsoft.AspNetCore.Builder.IApplicationBuilder! app, Microsoft.AspNetCore.Http.RequestDelegate! handler) -> void
static Microsoft.AspNetCore.Builder.UseExtensions.Use(this Microsoft.AspNetCore.Builder.IApplicationBuilder! app, System.Func!, System.Threading.Tasks.Task!>! middleware) -> Microsoft.AspNetCore.Builder.IApplicationBuilder!
-static Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.UseMiddleware(this Microsoft.AspNetCore.Builder.IApplicationBuilder! app, System.Type! middleware, params object![]! args) -> Microsoft.AspNetCore.Builder.IApplicationBuilder!
-static Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.UseMiddleware(this Microsoft.AspNetCore.Builder.IApplicationBuilder! app, params object![]! args) -> Microsoft.AspNetCore.Builder.IApplicationBuilder!
+static Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.UseMiddleware(this Microsoft.AspNetCore.Builder.IApplicationBuilder! app, System.Type! middleware, params object?[]! args) -> Microsoft.AspNetCore.Builder.IApplicationBuilder!
+static Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.UseMiddleware(this Microsoft.AspNetCore.Builder.IApplicationBuilder! app, params object?[]! args) -> Microsoft.AspNetCore.Builder.IApplicationBuilder!
static Microsoft.AspNetCore.Builder.UsePathBaseExtensions.UsePathBase(this Microsoft.AspNetCore.Builder.IApplicationBuilder! app, Microsoft.AspNetCore.Http.PathString pathBase) -> Microsoft.AspNetCore.Builder.IApplicationBuilder!
static Microsoft.AspNetCore.Builder.UseWhenExtensions.UseWhen(this Microsoft.AspNetCore.Builder.IApplicationBuilder! app, System.Func! predicate, System.Action! configuration) -> Microsoft.AspNetCore.Builder.IApplicationBuilder!
static Microsoft.AspNetCore.Http.EndpointHttpContextExtensions.GetEndpoint(this Microsoft.AspNetCore.Http.HttpContext! context) -> Microsoft.AspNetCore.Http.Endpoint?
diff --git a/src/Http/Http.Extensions/src/HeaderDictionaryTypeExtensions.cs b/src/Http/Http.Extensions/src/HeaderDictionaryTypeExtensions.cs
index 0b0c167aad64..8e9cb63cecc3 100644
--- a/src/Http/Http.Extensions/src/HeaderDictionaryTypeExtensions.cs
+++ b/src/Http/Http.Extensions/src/HeaderDictionaryTypeExtensions.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Http.Headers;
@@ -238,7 +239,9 @@ private static T GetViaReflection(string value)
if (method == null)
{
throw new NotSupportedException(string.Format(
- "The given type '{0}' does not have a TryParse method with the required signature 'public static bool TryParse(string, out {0}).", nameof(T)));
+ CultureInfo.CurrentCulture,
+ "The given type '{0}' does not have a TryParse method with the required signature 'public static bool TryParse(string, out {0}).",
+ nameof(T)));
}
var parameters = new object[] { value, null };
@@ -272,7 +275,9 @@ private static IList GetListViaReflection(StringValues values)
if (method == null)
{
throw new NotSupportedException(string.Format(
- "The given type '{0}' does not have a TryParseList method with the required signature 'public static bool TryParseList(IList, out IList<{0}>).", nameof(T)));
+ CultureInfo.CurrentCulture,
+ "The given type '{0}' does not have a TryParseList method with the required signature 'public static bool TryParseList(IList, out IList<{0}>).",
+ nameof(T)));
}
var parameters = new object[] { values, null };
diff --git a/src/Http/Http/src/Internal/ReferenceReadStream.cs b/src/Http/Http/src/Internal/ReferenceReadStream.cs
index cee967d0cc22..c6afdc9dca19 100644
--- a/src/Http/Http/src/Internal/ReferenceReadStream.cs
+++ b/src/Http/Http/src/Internal/ReferenceReadStream.cs
@@ -61,7 +61,7 @@ public override long Position
ThrowIfDisposed();
if (value < 0 || value > Length)
{
- throw new ArgumentOutOfRangeException(nameof(value), value, "The Position must be within the length of the Stream: " + Length.ToString());
+ throw new ArgumentOutOfRangeException(nameof(value), value, $"The Position must be within the length of the Stream: {Length}");
}
VerifyPosition();
_position = value;
diff --git a/src/Http/Http/test/ResponseCookiesTest.cs b/src/Http/Http/test/ResponseCookiesTest.cs
index 2c73a75ec1f3..5acf74b09464 100644
--- a/src/Http/Http/test/ResponseCookiesTest.cs
+++ b/src/Http/Http/test/ResponseCookiesTest.cs
@@ -137,7 +137,7 @@ public void ProvidesMaxAgeWithCookieOptionsArgumentExpectMaxAgeToBeSet()
var cookieHeaderValues = headers[HeaderNames.SetCookie];
Assert.Single(cookieHeaderValues);
- Assert.Contains($"max-age={maxAgeTime.TotalSeconds.ToString()}", cookieHeaderValues[0]);
+ Assert.Contains($"max-age={maxAgeTime.TotalSeconds}", cookieHeaderValues[0]);
}
[Theory]
diff --git a/src/Http/Owin/src/OwinEnvironment.cs b/src/Http/Owin/src/OwinEnvironment.cs
index 046022de45dc..938d366bf722 100644
--- a/src/Http/Owin/src/OwinEnvironment.cs
+++ b/src/Http/Owin/src/OwinEnvironment.cs
@@ -47,19 +47,19 @@ public OwinEnvironment(HttpContext context)
_context = context;
_entries = new Dictionary()
{
- { OwinConstants.RequestProtocol, new FeatureMap(feature => feature.Protocol, () => string.Empty, (feature, value) => feature.Protocol = Convert.ToString(value)) },
- { OwinConstants.RequestScheme, new FeatureMap(feature => feature.Scheme, () => string.Empty, (feature, value) => feature.Scheme = Convert.ToString(value)) },
- { OwinConstants.RequestMethod, new FeatureMap(feature => feature.Method, () => string.Empty, (feature, value) => feature.Method = Convert.ToString(value)) },
- { OwinConstants.RequestPathBase, new FeatureMap(feature => feature.PathBase, () => string.Empty, (feature, value) => feature.PathBase = Convert.ToString(value)) },
- { OwinConstants.RequestPath, new FeatureMap(feature => feature.Path, () => string.Empty, (feature, value) => feature.Path = Convert.ToString(value)) },
+ { OwinConstants.RequestProtocol, new FeatureMap(feature => feature.Protocol, () => string.Empty, (feature, value) => feature.Protocol = Convert.ToString(value, CultureInfo.InvariantCulture)) },
+ { OwinConstants.RequestScheme, new FeatureMap(feature => feature.Scheme, () => string.Empty, (feature, value) => feature.Scheme = Convert.ToString(value, CultureInfo.InvariantCulture)) },
+ { OwinConstants.RequestMethod, new FeatureMap(feature => feature.Method, () => string.Empty, (feature, value) => feature.Method = Convert.ToString(value, CultureInfo.InvariantCulture)) },
+ { OwinConstants.RequestPathBase, new FeatureMap(feature => feature.PathBase, () => string.Empty, (feature, value) => feature.PathBase = Convert.ToString(value, CultureInfo.InvariantCulture)) },
+ { OwinConstants.RequestPath, new FeatureMap(feature => feature.Path, () => string.Empty, (feature, value) => feature.Path = Convert.ToString(value, CultureInfo.InvariantCulture)) },
{ OwinConstants.RequestQueryString, new FeatureMap(feature => Utilities.RemoveQuestionMark(feature.QueryString), () => string.Empty,
- (feature, value) => feature.QueryString = Utilities.AddQuestionMark(Convert.ToString(value))) },
+ (feature, value) => feature.QueryString = Utilities.AddQuestionMark(Convert.ToString(value, CultureInfo.InvariantCulture))) },
{ OwinConstants.RequestHeaders, new FeatureMap(feature => Utilities.MakeDictionaryStringArray(feature.Headers), (feature, value) => feature.Headers = Utilities.MakeHeaderDictionary((IDictionary)value)) },
{ OwinConstants.RequestBody, new FeatureMap(feature => feature.Body, () => Stream.Null, (feature, value) => feature.Body = (Stream)value) },
{ OwinConstants.RequestUser, new FeatureMap(feature => feature.User, () => null, (feature, value) => feature.User = (ClaimsPrincipal)value) },
- { OwinConstants.ResponseStatusCode, new FeatureMap(feature => feature.StatusCode, () => 200, (feature, value) => feature.StatusCode = Convert.ToInt32(value)) },
- { OwinConstants.ResponseReasonPhrase, new FeatureMap(feature => feature.ReasonPhrase, (feature, value) => feature.ReasonPhrase = Convert.ToString(value)) },
+ { OwinConstants.ResponseStatusCode, new FeatureMap(feature => feature.StatusCode, () => 200, (feature, value) => feature.StatusCode = Convert.ToInt32(value, CultureInfo.InvariantCulture)) },
+ { OwinConstants.ResponseReasonPhrase, new FeatureMap(feature => feature.ReasonPhrase, (feature, value) => feature.ReasonPhrase = Convert.ToString(value, CultureInfo.InvariantCulture)) },
{ OwinConstants.ResponseHeaders, new FeatureMap(feature => Utilities.MakeDictionaryStringArray(feature.Headers), (feature, value) => feature.Headers = Utilities.MakeHeaderDictionary((IDictionary)value)) },
{ OwinConstants.ResponseBody, new FeatureMap(feature => feature.Stream, () => Stream.Null, (feature, value) => context.Response.Body = (Stream)value) }, // DefaultHttpResponse.Body.Set has built in logic to handle replacing the feature.
{ OwinConstants.CommonKeys.OnSendingHeaders, new FeatureMap(
@@ -81,9 +81,9 @@ public OwinEnvironment(HttpContext context)
(feature, value) => feature.RemotePort = Convert.ToInt32(value, CultureInfo.InvariantCulture)) },
{ OwinConstants.CommonKeys.LocalIpAddress, new FeatureMap(feature => feature.LocalIpAddress.ToString(),
- (feature, value) => feature.LocalIpAddress = IPAddress.Parse(Convert.ToString(value))) },
+ (feature, value) => feature.LocalIpAddress = IPAddress.Parse(Convert.ToString(value, CultureInfo.InvariantCulture))) },
{ OwinConstants.CommonKeys.RemoteIpAddress, new FeatureMap(feature => feature.RemoteIpAddress.ToString(),
- (feature, value) => feature.RemoteIpAddress = IPAddress.Parse(Convert.ToString(value))) },
+ (feature, value) => feature.RemoteIpAddress = IPAddress.Parse(Convert.ToString(value, CultureInfo.InvariantCulture))) },
{ OwinConstants.SendFiles.SendAsync, new FeatureMap(feature => new SendFileFunc(feature.SendFileAsync)) },
@@ -157,7 +157,7 @@ ICollection IDictionary.Keys
{
object value;
return _entries.Where(pair => pair.Value.TryGet(_context, out value))
- .Select(pair => pair.Key).Concat(_context.Items.Keys.Select(key => Convert.ToString(key))).ToList();
+ .Select(pair => pair.Key).Concat(_context.Items.Keys.Select(key => Convert.ToString(key, CultureInfo.InvariantCulture))).ToList();
}
}
@@ -281,7 +281,7 @@ public IEnumerator> GetEnumerator()
}
foreach (var entryPair in _context.Items)
{
- yield return new KeyValuePair(Convert.ToString(entryPair.Key), entryPair.Value);
+ yield return new KeyValuePair(Convert.ToString(entryPair.Key, CultureInfo.InvariantCulture), entryPair.Value);
}
}
diff --git a/src/Http/Owin/src/OwinFeatureCollection.cs b/src/Http/Owin/src/OwinFeatureCollection.cs
index 5f39c765b4b8..9149e0d2d214 100644
--- a/src/Http/Owin/src/OwinFeatureCollection.cs
+++ b/src/Http/Owin/src/OwinFeatureCollection.cs
@@ -206,13 +206,13 @@ IPAddress IHttpConnectionFeature.LocalIpAddress
int IHttpConnectionFeature.RemotePort
{
- get { return int.Parse(Prop(OwinConstants.CommonKeys.RemotePort)); }
+ get { return int.Parse(Prop(OwinConstants.CommonKeys.RemotePort), CultureInfo.InvariantCulture); }
set { Prop(OwinConstants.CommonKeys.RemotePort, value.ToString(CultureInfo.InvariantCulture)); }
}
int IHttpConnectionFeature.LocalPort
{
- get { return int.Parse(Prop(OwinConstants.CommonKeys.LocalPort)); }
+ get { return int.Parse(Prop(OwinConstants.CommonKeys.LocalPort), CultureInfo.InvariantCulture); }
set { Prop(OwinConstants.CommonKeys.LocalPort, value.ToString(CultureInfo.InvariantCulture)); }
}
diff --git a/src/Http/Routing/src/Constraints/HttpMethodRouteConstraint.cs b/src/Http/Routing/src/Constraints/HttpMethodRouteConstraint.cs
index b2ad0eff33a2..696f8084017a 100644
--- a/src/Http/Routing/src/Constraints/HttpMethodRouteConstraint.cs
+++ b/src/Http/Routing/src/Constraints/HttpMethodRouteConstraint.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using Microsoft.AspNetCore.Http;
@@ -81,7 +82,7 @@ public virtual bool Match(
return true;
}
- return AllowedMethods.Contains(Convert.ToString(obj), StringComparer.OrdinalIgnoreCase);
+ return AllowedMethods.Contains(Convert.ToString(obj, CultureInfo.InvariantCulture), StringComparer.OrdinalIgnoreCase);
default:
throw new ArgumentOutOfRangeException(nameof(routeDirection));
diff --git a/src/Http/Routing/src/Matching/HostMatcherPolicy.cs b/src/Http/Routing/src/Matching/HostMatcherPolicy.cs
index 842670f9ddf2..e79715bd7ad3 100644
--- a/src/Http/Routing/src/Matching/HostMatcherPolicy.cs
+++ b/src/Http/Routing/src/Matching/HostMatcherPolicy.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
@@ -471,7 +472,7 @@ public override bool Equals(object? obj)
public override string ToString()
{
- return $"{Host}:{Port?.ToString() ?? WildcardHost}";
+ return $"{Host}:{Port?.ToString(CultureInfo.InvariantCulture) ?? WildcardHost}";
}
}
}
diff --git a/src/Http/Routing/src/Matching/HttpMethodMatcherPolicy.cs b/src/Http/Routing/src/Matching/HttpMethodMatcherPolicy.cs
index 9ffa13fa91fa..2560e2408a23 100644
--- a/src/Http/Routing/src/Matching/HttpMethodMatcherPolicy.cs
+++ b/src/Http/Routing/src/Matching/HttpMethodMatcherPolicy.cs
@@ -484,7 +484,7 @@ public EdgeKey(string httpMethod, bool isCorsPreflightRequest)
// These are comparable so they can be sorted in tests.
public int CompareTo(EdgeKey other)
{
- var compare = HttpMethod.CompareTo(other.HttpMethod);
+ var compare = string.Compare(HttpMethod, other.HttpMethod, StringComparison.Ordinal);
if (compare != 0)
{
return compare;
diff --git a/src/Http/Routing/src/Patterns/RoutePatternParser.cs b/src/Http/Routing/src/Patterns/RoutePatternParser.cs
index 8b8f181f52c1..d59f6779cfe6 100644
--- a/src/Http/Routing/src/Patterns/RoutePatternParser.cs
+++ b/src/Http/Routing/src/Patterns/RoutePatternParser.cs
@@ -6,6 +6,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Globalization;
namespace Microsoft.AspNetCore.Routing.Patterns
{
@@ -180,7 +181,7 @@ private static bool ParseParameter(Context context, List parts
}
else if (context.Current == CloseBrace)
{
- // When we encounter Closed brace here, it either means end of the parameter or it is a closed
+ // When we encounter Closed brace here, it either means end of the parameter or it is a closed
// brace in the parameter, in that case it needs to be escaped.
// Example: {p1:regex(([}}])\w+}. First pair is escaped one and last marks end of the parameter
if (!context.MoveNext())
@@ -357,8 +358,8 @@ private static bool IsSegmentValid(Context context, List parts
}
}
- // if a segment has multiple parts, then only the last one parameter can be optional
- // if it is following a optional seperator.
+ // if a segment has multiple parts, then only the last one parameter can be optional
+ // if it is following a optional seperator.
for (var i = 0; i < parts.Count; i++)
{
var part = parts[i];
@@ -376,8 +377,7 @@ private static bool IsSegmentValid(Context context, List parts
// Example of error message:
// "In the segment '{RouteValue}{param?}', the optional parameter 'param' is preceded
// by an invalid segment '{RouteValue}'. Only a period (.) can precede an optional parameter.
- context.Error = string.Format(
- Resources.TemplateRoute_OptionalParameterCanbBePrecededByPeriod,
+ context.Error = Resources.FormatTemplateRoute_OptionalParameterCanbBePrecededByPeriod(
RoutePatternPathSegment.DebuggerToString(parts),
parameter.Name,
parts[i - 1].DebuggerToString());
@@ -390,8 +390,7 @@ private static bool IsSegmentValid(Context context, List parts
// Example of error message:
// "In the segment '{RouteValue}-{param?}', the optional parameter 'param' is preceded
// by an invalid segment '-'. Only a period (.) can precede an optional parameter.
- context.Error = string.Format(
- Resources.TemplateRoute_OptionalParameterCanbBePrecededByPeriod,
+ context.Error = Resources.FormatTemplateRoute_OptionalParameterCanbBePrecededByPeriod(
RoutePatternPathSegment.DebuggerToString(parts),
parameter.Name,
parts[i - 1].DebuggerToString());
@@ -405,10 +404,9 @@ private static bool IsSegmentValid(Context context, List parts
{
// This optional parameter is not the last one in the segment
// Example:
- // An optional parameter must be at the end of the segment. In the segment '{RouteValue?})',
+ // An optional parameter must be at the end of the segment. In the segment '{RouteValue?})',
// optional parameter 'RouteValue' is followed by ')'
- context.Error = string.Format(
- Resources.TemplateRoute_OptionalParameterHasTobeTheLast,
+ context.Error = Resources.FormatTemplateRoute_OptionalParameterHasTobeTheLast(
RoutePatternPathSegment.DebuggerToString(parts),
parameter.Name,
parts[i + 1].DebuggerToString());
diff --git a/src/Http/Routing/src/Tree/UrlMatchingTree.cs b/src/Http/Routing/src/Tree/UrlMatchingTree.cs
index 3dec2b54bd21..0798f70da878 100644
--- a/src/Http/Routing/src/Tree/UrlMatchingTree.cs
+++ b/src/Http/Routing/src/Tree/UrlMatchingTree.cs
@@ -1,6 +1,7 @@
// 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.Diagnostics;
using System.Linq;
@@ -158,7 +159,7 @@ internal void AddEntry(InboundRouteEntry entry)
current.Matches.Sort((x, y) =>
{
var result = x.Entry.Precedence.CompareTo(y.Entry.Precedence);
- return result == 0 ? x.Entry.RouteTemplate.TemplateText!.CompareTo(y.Entry.RouteTemplate.TemplateText) : result;
+ return result == 0 ? string.Compare(x.Entry.RouteTemplate.TemplateText, y.Entry.RouteTemplate.TemplateText, StringComparison.Ordinal) : result;
});
}
diff --git a/src/Http/Routing/src/UriBuildingContext.cs b/src/Http/Routing/src/UriBuildingContext.cs
index 5bc974d5465d..f5089018006c 100644
--- a/src/Http/Routing/src/UriBuildingContext.cs
+++ b/src/Http/Routing/src/UriBuildingContext.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Diagnostics;
+using System.Globalization;
using System.IO;
using System.Text;
using System.Text.Encodings.Web;
@@ -319,7 +320,7 @@ internal void EncodeValue(string value, int start, int characterCount, bool enco
private string DebuggerToString()
{
- return string.Format("{{Accepted: '{0}' Buffered: '{1}'}}", _path, string.Join("", _buffer));
+ return string.Format(CultureInfo.InvariantCulture, "{{Accepted: '{0}' Buffered: '{1}'}}", _path, string.Join("", _buffer));
}
private readonly struct BufferValue
diff --git a/src/Http/Routing/test/UnitTests/TestObjects/SlugifyParameterTransformer.cs b/src/Http/Routing/test/UnitTests/TestObjects/SlugifyParameterTransformer.cs
index 625a5c313766..5b3a80086120 100644
--- a/src/Http/Routing/test/UnitTests/TestObjects/SlugifyParameterTransformer.cs
+++ b/src/Http/Routing/test/UnitTests/TestObjects/SlugifyParameterTransformer.cs
@@ -1,4 +1,4 @@
-// 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.
using System.Text.RegularExpressions;
@@ -10,7 +10,7 @@ public class SlugifyParameterTransformer : IOutboundParameterTransformer
public string TransformOutbound(object value)
{
// Slugify value
- return value == null ? null : Regex.Replace(value.ToString(), "([a-z])([A-Z])", "$1-$2").ToLower();
+ return value == null ? null : Regex.Replace(value.ToString(), "([a-z])([A-Z])", "$1-$2").ToLowerInvariant();
}
}
}
diff --git a/src/Http/Routing/test/UnitTests/Tree/TreeRouterTest.cs b/src/Http/Routing/test/UnitTests/Tree/TreeRouterTest.cs
index 0f9a2a7feb2b..517abedaad93 100644
--- a/src/Http/Routing/test/UnitTests/Tree/TreeRouterTest.cs
+++ b/src/Http/Routing/test/UnitTests/Tree/TreeRouterTest.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
@@ -2059,7 +2060,7 @@ private static OutboundRouteEntry MapOutboundEntry(
private static string CreateRouteGroup(int order, string template)
{
- return string.Format("{0}&{1}", order, template);
+ return string.Format(CultureInfo.InvariantCulture, "{0}&{1}", order, template);
}
private static DefaultInlineConstraintResolver CreateConstraintResolver()
diff --git a/src/Http/Routing/test/testassets/Benchmarks/Program.cs b/src/Http/Routing/test/testassets/Benchmarks/Program.cs
index b4b29acb0304..49f9b41ee246 100644
--- a/src/Http/Routing/test/testassets/Benchmarks/Program.cs
+++ b/src/Http/Routing/test/testassets/Benchmarks/Program.cs
@@ -36,7 +36,7 @@ public static IHostBuilder GetHostBuilder(string[] args)
.UseConfiguration(config);
});
- var scenario = config["scenarios"]?.ToLower();
+ var scenario = config["scenarios"]?.ToLowerInvariant();
if (scenario == "plaintextdispatcher" || scenario == "plaintextendpointrouting")
{
hostBuilder.ConfigureWebHost(webHostBuilder =>
diff --git a/src/Http/Routing/test/testassets/RoutingSandbox/SlugifyParameterTransformer.cs b/src/Http/Routing/test/testassets/RoutingSandbox/SlugifyParameterTransformer.cs
index 4838fcc89eaf..3eb0c89e7375 100644
--- a/src/Http/Routing/test/testassets/RoutingSandbox/SlugifyParameterTransformer.cs
+++ b/src/Http/Routing/test/testassets/RoutingSandbox/SlugifyParameterTransformer.cs
@@ -1,7 +1,8 @@
-// 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.
using System;
+using System.Globalization;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Routing;
@@ -12,7 +13,7 @@ public class SlugifyParameterTransformer : IOutboundParameterTransformer
public string TransformOutbound(object value)
{
// Slugify value
- return value == null ? null : Regex.Replace(value.ToString(), "([a-z])([A-Z])", "$1-$2", RegexOptions.None, TimeSpan.FromMilliseconds(100)).ToLower();
+ return value == null ? null : Regex.Replace(value.ToString(), "([a-z])([A-Z])", "$1-$2", RegexOptions.None, TimeSpan.FromMilliseconds(100)).ToLowerInvariant();
}
}
}
diff --git a/src/Http/Routing/tools/Swaggatherer/SwaggathererApplication.cs b/src/Http/Routing/tools/Swaggatherer/SwaggathererApplication.cs
index 5cebbf96a22a..06cecdc14b72 100644
--- a/src/Http/Routing/tools/Swaggatherer/SwaggathererApplication.cs
+++ b/src/Http/Routing/tools/Swaggatherer/SwaggathererApplication.cs
@@ -199,7 +199,7 @@ private bool IsDuplicateTemplate(RouteEntry entry, List others)
break;
}
- if (HttpMethods.HasValue() &&
+ if (HttpMethods.HasValue() &&
!string.Equals(entry.Method, other.Method, StringComparison.OrdinalIgnoreCase))
{
isSame = false;
@@ -227,7 +227,7 @@ private static void Sort(List entries)
return comparison;
}
- return x.Template.TemplateText.CompareTo(y.Template.TemplateText);
+ return string.Compare(x.Template.TemplateText, y.Template.TemplateText, StringComparison.Ordinal);
});
}
diff --git a/src/Http/Routing/tools/Swaggatherer/Template.cs b/src/Http/Routing/tools/Swaggatherer/Template.cs
index 955ec658b194..cce5de2062dc 100644
--- a/src/Http/Routing/tools/Swaggatherer/Template.cs
+++ b/src/Http/Routing/tools/Swaggatherer/Template.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
namespace Swaggatherer
{
@@ -61,7 +62,9 @@ public static string Execute(IReadOnlyList entries)
setupMatcherLines.Add($" builder.AddEndpoint(Endpoints[{i}]);");
}
- return string.Format(@"
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ @"
// 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.
@@ -118,10 +121,10 @@ private RouteEndpoint CreateEndpoint(string template, string controllerName, str
}}
return CreateEndpoint(
- template,
- defaults: defaults,
- requiredValues: requiredValues,
- metadata: metadata,
+ template,
+ defaults: defaults,
+ requiredValues: requiredValues,
+ metadata: metadata,
routeName: controllerName);
}}
}}
diff --git a/src/Http/WebUtilities/src/BufferedReadStream.cs b/src/Http/WebUtilities/src/BufferedReadStream.cs
index 10f1465f3a2e..f34c31e51edf 100644
--- a/src/Http/WebUtilities/src/BufferedReadStream.cs
+++ b/src/Http/WebUtilities/src/BufferedReadStream.cs
@@ -277,7 +277,7 @@ public bool EnsureBuffered(int minCount)
{
if (minCount > _buffer.Length)
{
- throw new ArgumentOutOfRangeException(nameof(minCount), minCount, "The value must be smaller than the buffer size: " + _buffer.Length.ToString());
+ throw new ArgumentOutOfRangeException(nameof(minCount), minCount, "The value must be smaller than the buffer size: " + _buffer.Length);
}
while (_bufferCount < minCount)
{
@@ -310,7 +310,7 @@ public async Task EnsureBufferedAsync(int minCount, CancellationToken canc
{
if (minCount > _buffer.Length)
{
- throw new ArgumentOutOfRangeException(nameof(minCount), minCount, "The value must be smaller than the buffer size: " + _buffer.Length.ToString());
+ throw new ArgumentOutOfRangeException(nameof(minCount), minCount, "The value must be smaller than the buffer size: " + _buffer.Length);
}
while (_bufferCount < minCount)
{
diff --git a/src/Identity/ApiAuthorization.IdentityServer/test/Configuration/ConfigureSigningCredentialsTests.cs b/src/Identity/ApiAuthorization.IdentityServer/test/Configuration/ConfigureSigningCredentialsTests.cs
index 2ec53f7a53f5..b14fb61d15c2 100644
--- a/src/Identity/ApiAuthorization.IdentityServer/test/Configuration/ConfigureSigningCredentialsTests.cs
+++ b/src/Identity/ApiAuthorization.IdentityServer/test/Configuration/ConfigureSigningCredentialsTests.cs
@@ -99,7 +99,7 @@ public void Configure_AddsDevelopmentKeyFromConfiguration()
}
[ConditionalFact]
- [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720", Queues = "OSX.1014.Amd64;OSX.1014.Amd64.Open")]
+ [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720", Queues = "All.OSX")]
public void Configure_LoadsPfxCertificateCredentialFromConfiguration()
{
// Arrange
@@ -129,7 +129,7 @@ public void Configure_LoadsPfxCertificateCredentialFromConfiguration()
}
[ConditionalFact]
- [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720", Queues = "OSX.1014.Amd64;OSX.1014.Amd64.Open")]
+ [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720", Queues = "All.OSX")]
public void Configure_LoadsCertificateStoreCertificateCredentialFromConfiguration()
{
try
diff --git a/src/Identity/ApiAuthorization.IdentityServer/test/Configuration/SigningKeysLoaderTests.cs b/src/Identity/ApiAuthorization.IdentityServer/test/Configuration/SigningKeysLoaderTests.cs
index 893be873abe1..96a3bf74b764 100644
--- a/src/Identity/ApiAuthorization.IdentityServer/test/Configuration/SigningKeysLoaderTests.cs
+++ b/src/Identity/ApiAuthorization.IdentityServer/test/Configuration/SigningKeysLoaderTests.cs
@@ -59,7 +59,7 @@ public static void LoadFromStoreCert_ThrowsIfThereIsNoCertificateAvailable()
}
[ConditionalFact]
- [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720", Queues = "OSX.1014.Amd64;OSX.1014.Amd64.Open")]
+ [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720", Queues = "All.OSX")]
public static void LoadFromStoreCert_SkipsCertificatesNotYetValid()
{
try
@@ -82,7 +82,7 @@ public static void LoadFromStoreCert_SkipsCertificatesNotYetValid()
}
[ConditionalFact]
- [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720", Queues = "OSX.1014.Amd64;OSX.1014.Amd64.Open")]
+ [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720", Queues = "All.OSX")]
public static void LoadFromStoreCert_PrefersCertificatesCloserToExpirationDate()
{
try
@@ -105,7 +105,7 @@ public static void LoadFromStoreCert_PrefersCertificatesCloserToExpirationDate()
}
[ConditionalFact]
- [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720", Queues = "OSX.1014.Amd64;OSX.1014.Amd64.Open")]
+ [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720", Queues = "All.OSX")]
public static void LoadFromStoreCert_SkipsExpiredCertificates()
{
try
diff --git a/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryEFOnlyUsersTest.cs b/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryEFOnlyUsersTest.cs
index e2a074f92b0d..4672d4f061f7 100644
--- a/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryEFOnlyUsersTest.cs
+++ b/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryEFOnlyUsersTest.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Globalization;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Identity.Test;
using Microsoft.EntityFrameworkCore;
@@ -32,7 +33,7 @@ protected override IdentityUser CreateTestUser(string namePrefix = "", string em
{
return new IdentityUser
{
- UserName = useNamePrefixAsUserName ? namePrefix : string.Format("{0}{1}", namePrefix, Guid.NewGuid()),
+ UserName = useNamePrefixAsUserName ? namePrefix : string.Format(CultureInfo.InvariantCulture, "{0}{1}", namePrefix, Guid.NewGuid()),
Email = email,
PhoneNumber = phoneNumber,
LockoutEnabled = lockoutEnabled,
@@ -47,6 +48,8 @@ protected override void SetUserPasswordHash(IdentityUser user, string hashedPass
protected override Expression> UserNameEqualsPredicate(string userName) => u => u.UserName == userName;
+#pragma warning disable CA1310 // Specify StringComparison for correctness
protected override Expression> UserNameStartsWithPredicate(string userName) => u => u.UserName.StartsWith(userName);
+#pragma warning restore CA1310 // Specify StringComparison for correctness
}
}
diff --git a/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryEFUserStoreTest.cs b/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryEFUserStoreTest.cs
index 0c5b39779cb0..ac16664e77f9 100644
--- a/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryEFUserStoreTest.cs
+++ b/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryEFUserStoreTest.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Globalization;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Identity.Test;
using Microsoft.Extensions.DependencyInjection;
@@ -37,7 +38,7 @@ protected override IdentityUser CreateTestUser(string namePrefix = "", string em
{
return new IdentityUser
{
- UserName = useNamePrefixAsUserName ? namePrefix : string.Format("{0}{1}", namePrefix, Guid.NewGuid()),
+ UserName = useNamePrefixAsUserName ? namePrefix : string.Format(CultureInfo.InvariantCulture, "{0}{1}", namePrefix, Guid.NewGuid()),
Email = email,
PhoneNumber = phoneNumber,
LockoutEnabled = lockoutEnabled,
@@ -47,7 +48,7 @@ protected override IdentityUser CreateTestUser(string namePrefix = "", string em
protected override IdentityRole CreateTestRole(string roleNamePrefix = "", bool useRoleNamePrefixAsRoleName = false)
{
- var roleName = useRoleNamePrefixAsRoleName ? roleNamePrefix : string.Format("{0}{1}", roleNamePrefix, Guid.NewGuid());
+ var roleName = useRoleNamePrefixAsRoleName ? roleNamePrefix : string.Format(CultureInfo.InvariantCulture, "{0}{1}", roleNamePrefix, Guid.NewGuid());
return new IdentityRole(roleName);
}
@@ -60,8 +61,10 @@ protected override void SetUserPasswordHash(IdentityUser user, string hashedPass
protected override Expression> RoleNameEqualsPredicate(string roleName) => r => r.Name == roleName;
+#pragma warning disable CA1310 // Specify StringComparison for correctness
protected override Expression> UserNameStartsWithPredicate(string userName) => u => u.UserName.StartsWith(userName);
protected override Expression> RoleNameStartsWithPredicate(string roleName) => r => r.Name.StartsWith(roleName);
+#pragma warning restore CA1310 // Specify StringComparison for correctness
}
}
diff --git a/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryStoreWithGenericsTest.cs b/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryStoreWithGenericsTest.cs
index 7c6a73b8a613..90750dd002be 100644
--- a/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryStoreWithGenericsTest.cs
+++ b/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryStoreWithGenericsTest.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Data.Common;
+using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Claims;
@@ -60,7 +61,7 @@ protected override IdentityUserWithGenerics CreateTestUser(string namePrefix = "
{
return new IdentityUserWithGenerics
{
- UserName = useNamePrefixAsUserName ? namePrefix : string.Format("{0}{1}", namePrefix, Guid.NewGuid()),
+ UserName = useNamePrefixAsUserName ? namePrefix : string.Format(CultureInfo.InvariantCulture, "{0}{1}", namePrefix, Guid.NewGuid()),
Email = email,
PhoneNumber = phoneNumber,
LockoutEnabled = lockoutEnabled,
@@ -70,7 +71,7 @@ protected override IdentityUserWithGenerics CreateTestUser(string namePrefix = "
protected override MyIdentityRole CreateTestRole(string roleNamePrefix = "", bool useRoleNamePrefixAsRoleName = false)
{
- var roleName = useRoleNamePrefixAsRoleName ? roleNamePrefix : string.Format("{0}{1}", roleNamePrefix, Guid.NewGuid());
+ var roleName = useRoleNamePrefixAsRoleName ? roleNamePrefix : string.Format(CultureInfo.InvariantCulture, "{0}{1}", roleNamePrefix, Guid.NewGuid());
return new MyIdentityRole(roleName);
}
@@ -83,9 +84,11 @@ protected override void SetUserPasswordHash(IdentityUserWithGenerics user, strin
protected override Expression> RoleNameEqualsPredicate(string roleName) => r => r.Name == roleName;
+#pragma warning disable CA1310 // Specify StringComparison for correctness
protected override Expression> UserNameStartsWithPredicate(string userName) => u => u.UserName.StartsWith(userName);
protected override Expression> RoleNameStartsWithPredicate(string roleName) => r => r.Name.StartsWith(roleName);
+#pragma warning restore CA1310 // Specify StringComparison for correctness
[Fact]
public async Task CanAddRemoveUserClaimWithIssuer()
diff --git a/src/Identity/EntityFrameworkCore/test/EF.Test/SqlStoreOnlyUsersTestBase.cs b/src/Identity/EntityFrameworkCore/test/EF.Test/SqlStoreOnlyUsersTestBase.cs
index 25136f3f94f9..dfcc50a99eab 100644
--- a/src/Identity/EntityFrameworkCore/test/EF.Test/SqlStoreOnlyUsersTestBase.cs
+++ b/src/Identity/EntityFrameworkCore/test/EF.Test/SqlStoreOnlyUsersTestBase.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Claims;
@@ -36,7 +37,7 @@ protected override TUser CreateTestUser(string namePrefix = "", string email = "
{
return new TUser
{
- UserName = useNamePrefixAsUserName ? namePrefix : string.Format("{0}{1}", namePrefix, Guid.NewGuid()),
+ UserName = useNamePrefixAsUserName ? namePrefix : string.Format(CultureInfo.InvariantCulture, "{0}{1}", namePrefix, Guid.NewGuid()),
Email = email,
PhoneNumber = phoneNumber,
LockoutEnabled = lockoutEnabled,
@@ -46,7 +47,9 @@ protected override TUser CreateTestUser(string namePrefix = "", string email = "
protected override Expression> UserNameEqualsPredicate(string userName) => u => u.UserName == userName;
+#pragma warning disable CA1310 // Specify StringComparison for correctness
protected override Expression> UserNameStartsWithPredicate(string userName) => u => u.UserName.StartsWith(userName);
+#pragma warning restore CA1310 // Specify StringComparison for correctness
private TestUserDbContext CreateContext()
{
diff --git a/src/Identity/EntityFrameworkCore/test/EF.Test/SqlStoreTestBase.cs b/src/Identity/EntityFrameworkCore/test/EF.Test/SqlStoreTestBase.cs
index 09dbe0b9b17e..51802dd42f6e 100644
--- a/src/Identity/EntityFrameworkCore/test/EF.Test/SqlStoreTestBase.cs
+++ b/src/Identity/EntityFrameworkCore/test/EF.Test/SqlStoreTestBase.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Claims;
@@ -66,7 +67,7 @@ protected override TUser CreateTestUser(string namePrefix = "", string email = "
{
return new TUser
{
- UserName = useNamePrefixAsUserName ? namePrefix : string.Format("{0}{1}", namePrefix, Guid.NewGuid()),
+ UserName = useNamePrefixAsUserName ? namePrefix : string.Format(CultureInfo.InvariantCulture, "{0}{1}", namePrefix, Guid.NewGuid()),
Email = email,
PhoneNumber = phoneNumber,
LockoutEnabled = lockoutEnabled,
@@ -76,7 +77,7 @@ protected override TUser CreateTestUser(string namePrefix = "", string email = "
protected override TRole CreateTestRole(string roleNamePrefix = "", bool useRoleNamePrefixAsRoleName = false)
{
- var roleName = useRoleNamePrefixAsRoleName ? roleNamePrefix : string.Format("{0}{1}", roleNamePrefix, Guid.NewGuid());
+ var roleName = useRoleNamePrefixAsRoleName ? roleNamePrefix : string.Format(CultureInfo.InvariantCulture, "{0}{1}", roleNamePrefix, Guid.NewGuid());
return new TRole() { Name = roleName };
}
@@ -84,9 +85,11 @@ protected override TRole CreateTestRole(string roleNamePrefix = "", bool useRole
protected override Expression> UserNameEqualsPredicate(string userName) => u => u.UserName == userName;
+#pragma warning disable CA1310 // Specify StringComparison for correctness
protected override Expression> RoleNameStartsWithPredicate(string roleName) => r => r.Name.StartsWith(roleName);
protected override Expression> UserNameStartsWithPredicate(string userName) => u => u.UserName.StartsWith(userName);
+#pragma warning restore CA1310 // Specify StringComparison for correctness
protected virtual TestDbContext CreateContext()
{
diff --git a/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreEncryptPersonalDataTest.cs b/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreEncryptPersonalDataTest.cs
index 62ec33914117..6f9efbe48f60 100644
--- a/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreEncryptPersonalDataTest.cs
+++ b/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreEncryptPersonalDataTest.cs
@@ -58,7 +58,7 @@ private class SillyEncryptor : ILookupProtector
public string Unprotect(string keyId, string data)
{
var pad = _keyRing[keyId];
- if (!data.StartsWith(pad))
+ if (!data.StartsWith(pad, StringComparison.Ordinal))
{
throw new InvalidOperationException("Didn't find pad.");
}
@@ -135,7 +135,7 @@ private bool FindInk(DbConnection conn, string column, string id)
if (reader.Read())
{
var value = reader.GetString(0);
- return value.StartsWith("Default:ink:");
+ return value.StartsWith("Default:ink:", StringComparison.Ordinal);
}
}
}
@@ -157,7 +157,7 @@ private bool FindTokenInk(DbConnection conn, string id, string loginProvider, st
if (reader.Read())
{
var value = reader.GetString(0);
- return value.StartsWith("Default:ink:");
+ return value.StartsWith("Default:ink:", StringComparison.Ordinal);
}
}
}
@@ -198,7 +198,7 @@ private async Task CustomPersonalDataPropertiesAreProtected(bool prote
var applicationServiceProvider = services.BuildServiceProvider();
using (var scope = applicationServiceProvider.CreateScope())
- {
+ {
var dbContext = scope.ServiceProvider.GetRequiredService();
dbContext.Database.EnsureCreated();
diff --git a/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreTest.cs b/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreTest.cs
index 022e54b77836..63d9cfda9d36 100644
--- a/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreTest.cs
+++ b/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreTest.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
@@ -394,7 +395,7 @@ protected override IdentityUser CreateTestUser(string namePrefix = "", string em
{
return new IdentityUser
{
- UserName = useNamePrefixAsUserName ? namePrefix : string.Format("{0}{1}", namePrefix, Guid.NewGuid()),
+ UserName = useNamePrefixAsUserName ? namePrefix : string.Format(CultureInfo.InvariantCulture, "{0}{1}", namePrefix, Guid.NewGuid()),
Email = email,
PhoneNumber = phoneNumber,
LockoutEnabled = lockoutEnabled,
@@ -404,7 +405,7 @@ protected override IdentityUser CreateTestUser(string namePrefix = "", string em
protected override IdentityRole CreateTestRole(string roleNamePrefix = "", bool useRoleNamePrefixAsRoleName = false)
{
- var roleName = useRoleNamePrefixAsRoleName ? roleNamePrefix : string.Format("{0}{1}", roleNamePrefix, Guid.NewGuid());
+ var roleName = useRoleNamePrefixAsRoleName ? roleNamePrefix : string.Format(CultureInfo.InvariantCulture, "{0}{1}", roleNamePrefix, Guid.NewGuid());
return new IdentityRole(roleName);
}
@@ -417,9 +418,11 @@ protected override void SetUserPasswordHash(IdentityUser user, string hashedPass
protected override Expression> RoleNameEqualsPredicate(string roleName) => r => r.Name == roleName;
+#pragma warning disable CA1310 // Specify StringComparison for correctness
protected override Expression> RoleNameStartsWithPredicate(string roleName) => r => r.Name.StartsWith(roleName);
protected override Expression> UserNameStartsWithPredicate(string userName) => u => u.UserName.StartsWith(userName);
+#pragma warning restore CA1310 // Specify StringComparison for correctness
}
public class ApplicationUser : IdentityUser { }
diff --git a/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreWithGenericsTest.cs b/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreWithGenericsTest.cs
index 8e07a8dc8e2e..ba4329b495bd 100644
--- a/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreWithGenericsTest.cs
+++ b/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreWithGenericsTest.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Claims;
@@ -50,7 +51,7 @@ protected override IdentityUserWithGenerics CreateTestUser(string namePrefix = "
{
return new IdentityUserWithGenerics
{
- UserName = useNamePrefixAsUserName ? namePrefix : string.Format("{0}{1}", namePrefix, Guid.NewGuid()),
+ UserName = useNamePrefixAsUserName ? namePrefix : string.Format(CultureInfo.InvariantCulture, "{0}{1}", namePrefix, Guid.NewGuid()),
Email = email,
PhoneNumber = phoneNumber,
LockoutEnabled = lockoutEnabled,
@@ -60,7 +61,7 @@ protected override IdentityUserWithGenerics CreateTestUser(string namePrefix = "
protected override MyIdentityRole CreateTestRole(string roleNamePrefix = "", bool useRoleNamePrefixAsRoleName = false)
{
- var roleName = useRoleNamePrefixAsRoleName ? roleNamePrefix : string.Format("{0}{1}", roleNamePrefix, Guid.NewGuid());
+ var roleName = useRoleNamePrefixAsRoleName ? roleNamePrefix : string.Format(CultureInfo.InvariantCulture, "{0}{1}", roleNamePrefix, Guid.NewGuid());
return new MyIdentityRole(roleName);
}
@@ -73,9 +74,11 @@ protected override void SetUserPasswordHash(IdentityUserWithGenerics user, strin
protected override Expression> RoleNameEqualsPredicate(string roleName) => r => r.Name == roleName;
+#pragma warning disable CA1310 // Specify StringComparison for correctness
protected override Expression> UserNameStartsWithPredicate(string userName) => u => u.UserName.StartsWith(userName);
protected override Expression> RoleNameStartsWithPredicate(string roleName) => r => r.Name.StartsWith(roleName);
+#pragma warning restore CA1310 // Specify StringComparison for correctness
[Fact]
public void AddEntityFrameworkStoresWithInvalidUserThrows()
diff --git a/src/Identity/Extensions.Core/src/IdentityResult.cs b/src/Identity/Extensions.Core/src/IdentityResult.cs
index 8a525fb54aa7..5315340d9f0a 100644
--- a/src/Identity/Extensions.Core/src/IdentityResult.cs
+++ b/src/Identity/Extensions.Core/src/IdentityResult.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using Microsoft.Extensions.Logging;
@@ -14,7 +15,7 @@ public class IdentityResult
{
private static readonly IdentityResult _success = new IdentityResult { Succeeded = true };
private List _errors = new List();
-
+
///
/// Flag indicating whether if the operation succeeded or not.
///
@@ -54,14 +55,14 @@ public static IdentityResult Failed(params IdentityError[] errors)
///
/// A string representation of the current object.
///
- /// If the operation was successful the ToString() will return "Succeeded" otherwise it returned
+ /// If the operation was successful the ToString() will return "Succeeded" otherwise it returned
/// "Failed : " followed by a comma delimited list of error codes from its collection, if any.
///
public override string ToString()
{
- return Succeeded ?
- "Succeeded" :
- string.Format("{0} : {1}", "Failed", string.Join(",", Errors.Select(x => x.Code).ToList()));
+ return Succeeded ?
+ "Succeeded" :
+ string.Format(CultureInfo.InvariantCulture, "{0} : {1}", "Failed", string.Join(",", Errors.Select(x => x.Code).ToList()));
}
}
}
\ No newline at end of file
diff --git a/src/Identity/Specification.Tests/src/UserManagerSpecificationTests.cs b/src/Identity/Specification.Tests/src/UserManagerSpecificationTests.cs
index 73d48be2f8ba..9b8fbef7da96 100644
--- a/src/Identity/Specification.Tests/src/UserManagerSpecificationTests.cs
+++ b/src/Identity/Specification.Tests/src/UserManagerSpecificationTests.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Claims;
@@ -1906,8 +1907,9 @@ public async Task NullableDateTimeOperationTest()
Assert.Null(await userMgr.GetLockoutEndDateAsync(user));
// set to a valid value
- await userMgr.SetLockoutEndDateAsync(user, DateTimeOffset.Parse("01/01/2014"));
- Assert.Equal(DateTimeOffset.Parse("01/01/2014"), await userMgr.GetLockoutEndDateAsync(user));
+ var lockoutEndDate = new DateTimeOffset(new DateTime(2014, 01, 01));
+ await userMgr.SetLockoutEndDateAsync(user, lockoutEndDate);
+ Assert.Equal(lockoutEndDate, await userMgr.GetLockoutEndDateAsync(user));
}
///
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/EnableAuthenticator.cshtml.cs b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/EnableAuthenticator.cshtml.cs
index 66cab7ef9b2e..3d3d193e4260 100644
--- a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/EnableAuthenticator.cshtml.cs
+++ b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/EnableAuthenticator.cshtml.cs
@@ -3,6 +3,7 @@
using System;
using System.ComponentModel.DataAnnotations;
+using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
@@ -195,6 +196,7 @@ private string FormatKey(string unformattedKey)
private string GenerateQrCodeUri(string email, string unformattedKey)
{
return string.Format(
+ CultureInfo.InvariantCulture,
AuthenticatorUriFormat,
_urlEncoder.Encode("Microsoft.AspNetCore.Identity.UI"),
_urlEncoder.Encode(email),
diff --git a/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj b/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj
index 1c054fcbcf84..112434a637e8 100644
--- a/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj
+++ b/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj
@@ -43,7 +43,7 @@
-
+
diff --git a/src/Identity/test/Identity.FunctionalTests/Pages/Account/Manage/EnableAuthenticator.cs b/src/Identity/test/Identity.FunctionalTests/Pages/Account/Manage/EnableAuthenticator.cs
index 53003d7c8e2f..4d9d765acc32 100644
--- a/src/Identity/test/Identity.FunctionalTests/Pages/Account/Manage/EnableAuthenticator.cs
+++ b/src/Identity/test/Identity.FunctionalTests/Pages/Account/Manage/EnableAuthenticator.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Net.Http;
using System.Security.Cryptography;
using System.Threading.Tasks;
@@ -53,7 +54,7 @@ public static string ComputeCode(string key)
var unixTimestamp = Convert.ToInt64(Math.Round((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds));
var timestep = Convert.ToInt64(unixTimestamp / 30);
var topt = Rfc6238AuthenticationService.ComputeTotp(hash, (ulong)timestep, modifier: null);
- return topt.ToString("D6");
+ return topt.ToString("D6", CultureInfo.InvariantCulture);
}
}
}
\ No newline at end of file
diff --git a/src/Identity/test/Identity.Test/IdentityUIScriptsTest.cs b/src/Identity/test/Identity.Test/IdentityUIScriptsTest.cs
index d8b16ff741e6..71712b382bb1 100644
--- a/src/Identity/test/Identity.Test/IdentityUIScriptsTest.cs
+++ b/src/Identity/test/Identity.Test/IdentityUIScriptsTest.cs
@@ -48,7 +48,7 @@ public async Task IdentityUI_ScriptTags_SubresourceIntegrityCheck(ScriptTag scri
private async Task GetShaIntegrity(ScriptTag scriptTag)
{
- var isSha256 = scriptTag.Integrity.StartsWith("sha256");
+ var isSha256 = scriptTag.Integrity.StartsWith("sha256", StringComparison.Ordinal);
var prefix = isSha256 ? "sha256" : "sha384";
using (var respStream = await _httpClient.GetStreamAsync(scriptTag.Src))
using (var alg256 = SHA256.Create())
diff --git a/src/Identity/test/Identity.Test/PasswordValidatorTest.cs b/src/Identity/test/Identity.Test/PasswordValidatorTest.cs
index 89ac413a44c0..8271f5b608d9 100644
--- a/src/Identity/test/Identity.Test/PasswordValidatorTest.cs
+++ b/src/Identity/test/Identity.Test/PasswordValidatorTest.cs
@@ -112,7 +112,7 @@ public async Task FailsWithoutRequiredUniqueCharsTests(string input, int uniqueC
manager.Options.Password.RequiredLength = 0;
manager.Options.Password.RequiredUniqueChars = uniqueChars;
IdentityResultAssert.IsFailure(await valid.ValidateAsync(manager, null, input),
- String.Format("Passwords must use at least {0} different characters.", uniqueChars));
+ $"Passwords must use at least {uniqueChars} different characters.");
}
[Theory]
diff --git a/src/Identity/test/Identity.Test/UserManagerTest.cs b/src/Identity/test/Identity.Test/UserManagerTest.cs
index 37cecb047c76..c12a34083f28 100644
--- a/src/Identity/test/Identity.Test/UserManagerTest.cs
+++ b/src/Identity/test/Identity.Test/UserManagerTest.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Security.Claims;
using System.Threading;
@@ -1779,7 +1780,7 @@ public class TestErrorDescriber : IdentityErrorDescriber
public override IdentityError DuplicateEmail(string email)
{
- return new IdentityError { Code = Code, Description = string.Format(FormatError, email) };
+ return new IdentityError { Code = Code, Description = string.Format(CultureInfo.InvariantCulture, FormatError, email) };
}
}
diff --git a/src/Identity/test/InMemory.Test/InMemoryStoreTest.cs b/src/Identity/test/InMemory.Test/InMemoryStoreTest.cs
index 6bb7507d2488..d19fc8a62d71 100644
--- a/src/Identity/test/InMemory.Test/InMemoryStoreTest.cs
+++ b/src/Identity/test/InMemory.Test/InMemoryStoreTest.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Globalization;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Identity.Test;
using Microsoft.Extensions.DependencyInjection;
@@ -35,7 +36,7 @@ protected override PocoUser CreateTestUser(string namePrefix = "", string email
{
return new PocoUser
{
- UserName = useNamePrefixAsUserName ? namePrefix : string.Format("{0}{1}", namePrefix, Guid.NewGuid()),
+ UserName = useNamePrefixAsUserName ? namePrefix : string.Format(CultureInfo.InvariantCulture, "{0}{1}", namePrefix, Guid.NewGuid()),
Email = email,
PhoneNumber = phoneNumber,
LockoutEnabled = lockoutEnabled,
@@ -45,7 +46,7 @@ protected override PocoUser CreateTestUser(string namePrefix = "", string email
protected override PocoRole CreateTestRole(string roleNamePrefix = "", bool useRoleNamePrefixAsRoleName = false)
{
- var roleName = useRoleNamePrefixAsRoleName ? roleNamePrefix : string.Format("{0}{1}", roleNamePrefix, Guid.NewGuid());
+ var roleName = useRoleNamePrefixAsRoleName ? roleNamePrefix : string.Format(CultureInfo.InvariantCulture, "{0}{1}", roleNamePrefix, Guid.NewGuid());
return new PocoRole(roleName);
}
@@ -53,8 +54,8 @@ protected override PocoRole CreateTestRole(string roleNamePrefix = "", bool useR
protected override Expression> RoleNameEqualsPredicate(string roleName) => r => r.Name == roleName;
- protected override Expression> UserNameStartsWithPredicate(string userName) => u => u.UserName.StartsWith(userName);
+ protected override Expression> UserNameStartsWithPredicate(string userName) => u => u.UserName.StartsWith(userName, StringComparison.Ordinal);
- protected override Expression> RoleNameStartsWithPredicate(string roleName) => r => r.Name.StartsWith(roleName);
+ protected override Expression> RoleNameStartsWithPredicate(string roleName) => r => r.Name.StartsWith(roleName, StringComparison.Ordinal);
}
}
\ No newline at end of file
diff --git a/src/Identity/test/InMemory.Test/InMemoryUserStoreTest.cs b/src/Identity/test/InMemory.Test/InMemoryUserStoreTest.cs
index ac7a08caa6dd..1862e66c2855 100644
--- a/src/Identity/test/InMemory.Test/InMemoryUserStoreTest.cs
+++ b/src/Identity/test/InMemory.Test/InMemoryUserStoreTest.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Globalization;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Identity.Test;
using Microsoft.Data.Sqlite;
@@ -32,7 +33,7 @@ protected override PocoUser CreateTestUser(string namePrefix = "", string email
{
return new PocoUser
{
- UserName = useNamePrefixAsUserName ? namePrefix : string.Format("{0}{1}", namePrefix, Guid.NewGuid()),
+ UserName = useNamePrefixAsUserName ? namePrefix : string.Format(CultureInfo.InvariantCulture, "{0}{1}", namePrefix, Guid.NewGuid()),
Email = email,
PhoneNumber = phoneNumber,
LockoutEnabled = lockoutEnabled,
@@ -42,7 +43,7 @@ protected override PocoUser CreateTestUser(string namePrefix = "", string email
protected override Expression> UserNameEqualsPredicate(string userName) => u => u.UserName == userName;
- protected override Expression> UserNameStartsWithPredicate(string userName) => u => u.UserName.StartsWith(userName);
+ protected override Expression> UserNameStartsWithPredicate(string userName) => u => u.UserName.StartsWith(userName, StringComparison.Ordinal);
public class Fixture : IDisposable
{
diff --git a/src/Identity/test/Shared/ApiConsistencyTestBase.cs b/src/Identity/test/Shared/ApiConsistencyTestBase.cs
index 29d75df9bb31..162259c5ef2e 100644
--- a/src/Identity/test/Shared/ApiConsistencyTestBase.cs
+++ b/src/Identity/test/Shared/ApiConsistencyTestBase.cs
@@ -21,12 +21,12 @@ where type.IsVisible
&& !type.IsSealed
&& type.DeclaredConstructors.Any(c => c.IsPublic || c.IsFamily || c.IsFamilyOrAssembly)
&& type.Namespace != null
- && !type.Namespace.EndsWith(".Compiled")
+ && !type.Namespace.EndsWith(".Compiled", StringComparison.Ordinal)
from method in type.DeclaredMethods.Where(m => m.IsPublic && !m.IsStatic)
where GetBasestTypeInAssembly(method.DeclaringType) == type
- && !(method.IsVirtual && !method.IsFinal)
- && !method.Name.StartsWith("get_")
- && !method.Name.StartsWith("set_")
+ && !(method.IsVirtual && !method.IsFinal)
+ && !method.Name.StartsWith("get_", StringComparison.Ordinal)
+ && !method.Name.StartsWith("set_", StringComparison.Ordinal)
&& !method.Name.Equals("Dispose")
select type.Name + "." + method.Name)
.ToList();
@@ -49,7 +49,7 @@ where typeof(Task).IsAssignableFrom(method.ReturnType)
var missingSuffixMethods
= asyncMethods
- .Where(method => !method.Name.EndsWith("Async"))
+ .Where(method => !method.Name.EndsWith("Async", StringComparison.Ordinal))
.Select(method => method.DeclaringType.Name + "." + method.Name)
.Except(GetAsyncSuffixExceptions())
.ToList();
diff --git a/src/Installers/Debian/Runtime/Debian.Runtime.debproj b/src/Installers/Debian/Runtime/Debian.Runtime.debproj
index 70931ff3a4ed..20cdfd1699fe 100644
--- a/src/Installers/Debian/Runtime/Debian.Runtime.debproj
+++ b/src/Installers/Debian/Runtime/Debian.Runtime.debproj
@@ -8,15 +8,17 @@
$(SharedFrameworkLayoutRoot)
- $(RuntimeInstallerBaseName)-$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion)
+ $(RuntimeInstallerBaseName)-$(AspNetCoreMajorMinorVersion)$(MicrosoftNETCoreAppRuntimeVersion)$(DotnetRuntimeDependencyVersion.Substring(0, $(DotnetRuntimeDependencyVersion.IndexOf('-'))))~$(DotnetRuntimeDependencyVersion.Substring($([MSBuild]::Add($(DotnetRuntimeDependencyVersion.IndexOf('-')), 1))))
+ $(MicrosoftNETCoreAppRuntimeVersion.Split('.')[0]).$(MicrosoftNETCoreAppRuntimeVersion.Split('.')[1])$(SharedFxProductName)$(SharedFxDescription)
+ DotnetRuntimeDependencyMajorMinorVersion=$(DotnetRuntimeDependencyMajorMinorVersion);
DotnetRuntimeDependencyVersion=$(DotnetRuntimeDependencyVersion);
diff --git a/src/Installers/Debian/Runtime/debian_config.json.in b/src/Installers/Debian/Runtime/debian_config.json.in
index d9c36fb33d1d..3efa7f5381d3 100644
--- a/src/Installers/Debian/Runtime/debian_config.json.in
+++ b/src/Installers/Debian/Runtime/debian_config.json.in
@@ -29,7 +29,7 @@
},
"debian_dependencies": {
- "dotnet-runtime-${AspNetCoreMajorVersion}.${AspNetCoreMinorVersion}": {
+ "dotnet-runtime-${DotnetRuntimeDependencyMajorMinorVersion}": {
"package_version": "${DotnetRuntimeDependencyVersion}"
}
}
diff --git a/src/Installers/Debian/TargetingPack/Debian.TargetingPack.debproj b/src/Installers/Debian/TargetingPack/Debian.TargetingPack.debproj
index 43eba9135887..373149c92fc6 100644
--- a/src/Installers/Debian/TargetingPack/Debian.TargetingPack.debproj
+++ b/src/Installers/Debian/TargetingPack/Debian.TargetingPack.debproj
@@ -8,18 +8,20 @@
$(TargetingPackLayoutRoot)
- $(TargetingPackInstallerBaseName)-$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion)
+ $(TargetingPackInstallerBaseName)-$(AspNetCoreMajorMinorVersion)ASP.NET Core Targeting Pack
- Provides a default set of APIs for building an ASP.NET Core $(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion) application. Contains reference assemblies, documentation, and other design-time assets.
+ Provides a default set of APIs for building an ASP.NET Core $(AspNetCoreMajorMinorVersion) application. Contains reference assemblies, documentation, and other design-time assets.$(MicrosoftNETCoreAppRefPackageVersion)$(DotnetTargetingPackDependencyVersion.Substring(0, $(DotnetTargetingPackDependencyVersion.IndexOf('-'))))~$(DotnetTargetingPackDependencyVersion.Substring($([MSBuild]::Add($(DotnetTargetingPackDependencyVersion.IndexOf('-')), 1))))
+ $(MicrosoftNETCoreAppRefPackageVersion.Split('.')[0]).$(MicrosoftNETCoreAppRefPackageVersion.Split('.')[1])$(SharedFxProductName)$(SharedFxDescription)
+ DotnetTargetingPackDependencyMajorMinorVersion=$(DotnetTargetingPackDependencyMajorMinorVersion);
DotnetTargetingPackDependencyVersion=$(DotnetTargetingPackDependencyVersion);
diff --git a/src/Installers/Debian/TargetingPack/debian_config.json.in b/src/Installers/Debian/TargetingPack/debian_config.json.in
index 74b38efff5a4..4df3587a0951 100644
--- a/src/Installers/Debian/TargetingPack/debian_config.json.in
+++ b/src/Installers/Debian/TargetingPack/debian_config.json.in
@@ -29,7 +29,7 @@
},
"debian_dependencies": {
- "dotnet-targeting-pack-${AspNetCoreMajorVersion}.${AspNetCoreMinorVersion}": {
+ "dotnet-targeting-pack-${DotnetTargetingPackDependencyMajorMinorVersion}": {
"package_version": "${DotnetTargetingPackDependencyVersion}"
}
}
diff --git a/src/Installers/Rpm/Rpm.Runtime.Common.targets b/src/Installers/Rpm/Rpm.Runtime.Common.targets
index dea8c0148d67..c2013eca0f7a 100644
--- a/src/Installers/Rpm/Rpm.Runtime.Common.targets
+++ b/src/Installers/Rpm/Rpm.Runtime.Common.targets
@@ -4,8 +4,8 @@
- $(RuntimeInstallerBaseName)-$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion)
- $(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion).$(AspNetCorePatchVersion)
+ $(RuntimeInstallerBaseName)-$(AspNetCoreMajorMinorVersion)
+ $(AspNetCoreMajorMinorVersion).$(AspNetCorePatchVersion)1
@@ -15,6 +15,8 @@
$(SharedFxDescription)$(SharedFrameworkLayoutRoot)
+
+ $(MicrosoftNETCoreAppRuntimeVersion.Split('.')[0]).$(MicrosoftNETCoreAppRuntimeVersion.Split('.')[1])
@@ -24,6 +26,6 @@
-
+
diff --git a/src/Installers/Rpm/TargetingPack/Rpm.TargetingPack.rpmproj b/src/Installers/Rpm/TargetingPack/Rpm.TargetingPack.rpmproj
index 38f5fbf78bb6..aa0af5374884 100644
--- a/src/Installers/Rpm/TargetingPack/Rpm.TargetingPack.rpmproj
+++ b/src/Installers/Rpm/TargetingPack/Rpm.TargetingPack.rpmproj
@@ -8,10 +8,12 @@
- $(TargetingPackInstallerBaseName)-$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion)
+ $(TargetingPackInstallerBaseName)-$(AspNetCoreMajorMinorVersion)ASP.NET Core Targeting Pack
- Provides a default set of APIs for building an ASP.NET Core $(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion) application. Contains reference assemblies, documentation, and other design-time assets.
+ Provides a default set of APIs for building an ASP.NET Core $(AspNetCoreMajorMinorVersion) application. Contains reference assemblies, documentation, and other design-time assets.
+
+ $(MicrosoftNETCoreAppRefPackageVersion.Split('.')[0]).$(MicrosoftNETCoreAppRefPackageVersion.Split('.')[1])
@@ -21,7 +23,7 @@
-
+
diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/Directory.Build.props b/src/Installers/Windows/AspNetCoreModule-Setup/Directory.Build.props
index d08b147e4ae5..cf5ef5f48827 100644
--- a/src/Installers/Windows/AspNetCoreModule-Setup/Directory.Build.props
+++ b/src/Installers/Windows/AspNetCoreModule-Setup/Directory.Build.props
@@ -15,7 +15,7 @@
$(BUILD_MINOR)
- 1$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion).$(BUILD_MAJOR)
+ 1$(AspNetCoreMajorMinorVersion).$(BUILD_MAJOR)$(ANCMFolderVersion).0
diff --git a/src/Middleware/SpaServices.Extensions/src/Proxying/ConditionalProxyMiddleware.cs b/src/Middleware/SpaServices.Extensions/src/Proxying/ConditionalProxyMiddleware.cs
index 99cc8c4ca85a..d1bb2d36986c 100644
--- a/src/Middleware/SpaServices.Extensions/src/Proxying/ConditionalProxyMiddleware.cs
+++ b/src/Middleware/SpaServices.Extensions/src/Proxying/ConditionalProxyMiddleware.cs
@@ -30,7 +30,7 @@ public ConditionalProxyMiddleware(
Task baseUriTask,
IHostApplicationLifetime applicationLifetime)
{
- if (!pathPrefix.StartsWith("/"))
+ if (!pathPrefix.StartsWith('/'))
{
pathPrefix = "/" + pathPrefix;
}
diff --git a/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddleware.cs b/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddleware.cs
index eb103f03f97d..1a420dad7da8 100644
--- a/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddleware.cs
+++ b/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddleware.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
@@ -79,7 +80,7 @@ private static async Task StartCreateReactAppServerAsync(
var envVars = new Dictionary
{
- { "PORT", portNumber.ToString() },
+ { "PORT", portNumber.ToString(CultureInfo.InvariantCulture) },
{ "BROWSER", "none" }, // We don't want create-react-app to open its own extra browser window pointing to the internal dev server port
};
var scriptRunner = new NodeScriptRunner(
diff --git a/src/Middleware/StaticFiles/src/HtmlDirectoryFormatter.cs b/src/Middleware/StaticFiles/src/HtmlDirectoryFormatter.cs
index a4d0f4a3c5e4..19b384d2f683 100644
--- a/src/Middleware/StaticFiles/src/HtmlDirectoryFormatter.cs
+++ b/src/Middleware/StaticFiles/src/HtmlDirectoryFormatter.cs
@@ -63,10 +63,13 @@ public virtual Task GenerateContentAsync(HttpContext context, IEnumerable
", CultureInfo.CurrentUICulture.TwoLetterISOLanguageName);
- builder.AppendFormat(@"
+ builder.AppendFormat(
+ CultureInfo.InvariantCulture,
+@"
{0} {1}", HtmlEncode(Resources.HtmlDir_IndexOf), HtmlEncode(requestPath.Value));
@@ -107,18 +110,23 @@ header h1 {
");
- builder.AppendFormat(@"
+ builder.AppendFormat(
+ CultureInfo.InvariantCulture,
+ @"