diff --git a/eng/PatchConfig.props b/eng/PatchConfig.props index bf1e94ff22..efc05a36c7 100644 --- a/eng/PatchConfig.props +++ b/eng/PatchConfig.props @@ -56,5 +56,10 @@ Later on, this will be checked using this condition: Microsoft.AspNetCore.AzureAppServices.SiteExtension; + + + Microsoft.AspNetCore.Mvc.Api.Analyzers; + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 5e06dbf685..10edfb8486 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -57,340 +57,340 @@ https://github.com/aspnet/EntityFrameworkCore b9c9b57de1ba41f75427db0a51b2e897d0354656 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 - + https://github.com/dotnet/corefx - e23119d577e644d2c2a25419c88c1181681358e0 + d47cae744ddfb625db8e391cecb261e4c3d7bb1c - + https://github.com/dotnet/corefx - e23119d577e644d2c2a25419c88c1181681358e0 + d47cae744ddfb625db8e391cecb261e4c3d7bb1c - + https://github.com/dotnet/corefx - e23119d577e644d2c2a25419c88c1181681358e0 + d47cae744ddfb625db8e391cecb261e4c3d7bb1c https://github.com/dotnet/corefx a28176b5ec68b6da1472934fe9493790d1665cae - + https://github.com/dotnet/corefx - e23119d577e644d2c2a25419c88c1181681358e0 + d47cae744ddfb625db8e391cecb261e4c3d7bb1c - + https://github.com/dotnet/corefx - e23119d577e644d2c2a25419c88c1181681358e0 + d47cae744ddfb625db8e391cecb261e4c3d7bb1c - + https://github.com/dotnet/corefx - e23119d577e644d2c2a25419c88c1181681358e0 + d47cae744ddfb625db8e391cecb261e4c3d7bb1c - + https://github.com/dotnet/corefx - e23119d577e644d2c2a25419c88c1181681358e0 + d47cae744ddfb625db8e391cecb261e4c3d7bb1c - + https://github.com/dotnet/corefx - e23119d577e644d2c2a25419c88c1181681358e0 + d47cae744ddfb625db8e391cecb261e4c3d7bb1c - + https://github.com/dotnet/corefx - e23119d577e644d2c2a25419c88c1181681358e0 + d47cae744ddfb625db8e391cecb261e4c3d7bb1c - + https://github.com/dotnet/corefx - e23119d577e644d2c2a25419c88c1181681358e0 + d47cae744ddfb625db8e391cecb261e4c3d7bb1c - + https://github.com/dotnet/corefx - e23119d577e644d2c2a25419c88c1181681358e0 + d47cae744ddfb625db8e391cecb261e4c3d7bb1c - + https://github.com/dotnet/corefx - e23119d577e644d2c2a25419c88c1181681358e0 + d47cae744ddfb625db8e391cecb261e4c3d7bb1c - + https://github.com/dotnet/corefx - e23119d577e644d2c2a25419c88c1181681358e0 + d47cae744ddfb625db8e391cecb261e4c3d7bb1c - + https://github.com/dotnet/corefx - e23119d577e644d2c2a25419c88c1181681358e0 + d47cae744ddfb625db8e391cecb261e4c3d7bb1c - + https://github.com/dotnet/corefx - e23119d577e644d2c2a25419c88c1181681358e0 + d47cae744ddfb625db8e391cecb261e4c3d7bb1c - + https://github.com/dotnet/corefx - e23119d577e644d2c2a25419c88c1181681358e0 + d47cae744ddfb625db8e391cecb261e4c3d7bb1c - + https://github.com/dotnet/corefx - e23119d577e644d2c2a25419c88c1181681358e0 + d47cae744ddfb625db8e391cecb261e4c3d7bb1c - + https://github.com/dotnet/corefx - e23119d577e644d2c2a25419c88c1181681358e0 + d47cae744ddfb625db8e391cecb261e4c3d7bb1c - + https://github.com/dotnet/core-setup - 63abc77da6d99470caa5bfa0465afe244105e595 + 372355272004e08c035c61077f5d6ca4d8f9cd22 - + https://github.com/dotnet/core-setup - 63abc77da6d99470caa5bfa0465afe244105e595 + 372355272004e08c035c61077f5d6ca4d8f9cd22 - + https://github.com/dotnet/core-setup - 63abc77da6d99470caa5bfa0465afe244105e595 + 372355272004e08c035c61077f5d6ca4d8f9cd22 - + https://github.com/dotnet/corefx - e23119d577e644d2c2a25419c88c1181681358e0 + d47cae744ddfb625db8e391cecb261e4c3d7bb1c - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 https://github.com/dotnet/arcade @@ -404,9 +404,9 @@ https://github.com/dotnet/arcade e6a5d5f970bb872451c6310ae34eda31041fb552 - + https://github.com/aspnet/Extensions - 6e92fcad99b6a6e882ac8dc5ad817b558f603597 + 04a5ac947976fc17e701ffd4cd406b589e14b1e5 diff --git a/eng/Versions.props b/eng/Versions.props index 1755801069..3ff25c6135 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -23,95 +23,95 @@ 1.0.0-beta.19302.2 - 3.0.0-preview6-27730-01 - 3.0.0-preview6-27730-01 - 2.1.0-preview6-27730-01 + 3.0.0-preview6-27803-13 + 3.0.0-preview6-27803-13 + 2.1.0-preview6-27803-13 - 4.6.0-preview6.19279.8 - 4.6.0-preview6.19279.8 - 4.6.0-preview6.19279.8 + 4.6.0-preview6.19303.8 + 4.6.0-preview6.19303.8 + 4.6.0-preview6.19303.8 4.7.0-preview6.19264.9 - 4.6.0-preview6.19279.8 - 4.6.0-preview6.19279.8 - 4.6.0-preview6.19279.8 - 4.6.0-preview6.19279.8 - 1.7.0-preview6.19279.8 - 4.6.0-preview6.19279.8 - 4.6.0-preview6.19279.8 - 4.6.0-preview6.19279.8 - 4.6.0-preview6.19279.8 - 4.6.0-preview6.19279.8 - 4.6.0-preview6.19279.8 - 4.6.0-preview6.19279.8 - 4.6.0-preview6.19279.8 - 4.6.0-preview6.19279.8 - 4.6.0-preview6.19279.8 + 4.6.0-preview6.19303.8 + 4.6.0-preview6.19303.8 + 4.6.0-preview6.19303.8 + 4.6.0-preview6.19303.8 + 1.7.0-preview6.19303.8 + 4.6.0-preview6.19303.8 + 4.6.0-preview6.19303.8 + 4.6.0-preview6.19303.8 + 4.6.0-preview6.19303.8 + 4.6.0-preview6.19303.8 + 4.6.0-preview6.19303.8 + 4.6.0-preview6.19303.8 + 4.6.0-preview6.19303.8 + 4.6.0-preview6.19303.8 + 4.6.0-preview6.19303.8 - 3.0.0-preview6.19279.8 + 3.0.0-preview6.19303.8 0.10.0-preview7.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 - 3.0.0-preview6.19303.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 + 3.0.0-preview6.19304.2 3.0.0-preview7.19303.12 3.0.0-preview7.19303.12 @@ -180,9 +180,9 @@ 0.10.13 4.2.1 4.2.1 - 3.7.0 - 0.1.21-dev201905010701 - 1.20.0-pre3 + 3.8.0 + 0.1.21-pre1 + 1.21.0 3.0.0-preview3.4 3.0.0-preview3.4 3.0.0-preview3.4 diff --git a/src/Components/Blazor/Build/src/targets/BuiltInBclLinkerDescriptor.xml b/src/Components/Blazor/Build/src/targets/BuiltInBclLinkerDescriptor.xml index 4b442b1bb8..32533df8ca 100644 --- a/src/Components/Blazor/Build/src/targets/BuiltInBclLinkerDescriptor.xml +++ b/src/Components/Blazor/Build/src/targets/BuiltInBclLinkerDescriptor.xml @@ -13,5 +13,9 @@ + + + + diff --git a/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs b/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs index 382346efce..7bdacfbc4b 100644 --- a/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs +++ b/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs @@ -155,6 +155,7 @@ namespace Microsoft.AspNetCore.Components public static Microsoft.AspNetCore.Components.EventCallback CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory factory, object receiver, System.Action setter, int existingValue) { throw null; } public static Microsoft.AspNetCore.Components.EventCallback CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory factory, object receiver, System.Action setter, long existingValue) { throw null; } public static Microsoft.AspNetCore.Components.EventCallback CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory factory, object receiver, System.Action setter, bool? existingValue) { throw null; } + public static Microsoft.AspNetCore.Components.EventCallback CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory factory, object receiver, System.Action setter, System.DateTime? existingValue) { throw null; } public static Microsoft.AspNetCore.Components.EventCallback CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory factory, object receiver, System.Action setter, decimal? existingValue) { throw null; } public static Microsoft.AspNetCore.Components.EventCallback CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory factory, object receiver, System.Action setter, double? existingValue) { throw null; } public static Microsoft.AspNetCore.Components.EventCallback CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory factory, object receiver, System.Action setter, int? existingValue) { throw null; } @@ -162,7 +163,7 @@ namespace Microsoft.AspNetCore.Components public static Microsoft.AspNetCore.Components.EventCallback CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory factory, object receiver, System.Action setter, float? existingValue) { throw null; } public static Microsoft.AspNetCore.Components.EventCallback CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory factory, object receiver, System.Action setter, float existingValue) { throw null; } public static Microsoft.AspNetCore.Components.EventCallback CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory factory, object receiver, System.Action setter, string existingValue) { throw null; } - public static Microsoft.AspNetCore.Components.EventCallback CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory factory, object receiver, System.Action setter, T existingValue) where T : struct, System.Enum { throw null; } + public static Microsoft.AspNetCore.Components.EventCallback CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory factory, object receiver, System.Action setter, T existingValue) { throw null; } } public static partial class EventCallbackFactoryUIEventArgsExtensions { diff --git a/src/Components/Components/src/EventCallbackFactoryBinderExtensions.cs b/src/Components/Components/src/EventCallbackFactoryBinderExtensions.cs index ba0a23dd0a..16fe53ad26 100644 --- a/src/Components/Components/src/EventCallbackFactoryBinderExtensions.cs +++ b/src/Components/Components/src/EventCallbackFactoryBinderExtensions.cs @@ -2,13 +2,27 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Concurrent; +using System.ComponentModel; +using System.Diagnostics; using System.Globalization; +using System.Reflection; namespace Microsoft.AspNetCore.Components { /// /// Contains extension methods for two-way binding using . For internal use only. /// + // + // NOTE: for number parsing, the HTML5 spec dictates that the DOM will represent + // number values as floating point numbers using `.` as the period separator. This is NOT culture senstive. + // Put another way, the user might see `,` as their decimal separator, but the value available in events + // to JS code is always simpilar to what .NET parses with InvariantCulture. + // + // See: https://www.w3.org/TR/html5/sec-forms.html#number-state-typenumber + // See: https://www.w3.org/TR/html5/infrastructure.html#valid-floating-point-number + // + // For now we're not necessarily handling this correctly since we parse the same way for number and text. public static class EventCallbackFactoryBinderExtensions { private delegate bool BindConverter(object obj, out T value); @@ -53,7 +67,7 @@ namespace Microsoft.AspNetCore.Components return false; } - if (!int.TryParse(text, out var converted)) + if (!int.TryParse(text, NumberStyles.Integer, CultureInfo.CurrentCulture, out var converted)) { value = default; return false; @@ -72,7 +86,7 @@ namespace Microsoft.AspNetCore.Components return true; } - if (!int.TryParse(text, out var converted)) + if (!int.TryParse(text, NumberStyles.Integer, CultureInfo.CurrentCulture, out var converted)) { value = default; return false; @@ -94,7 +108,7 @@ namespace Microsoft.AspNetCore.Components return false; } - if (!long.TryParse(text, out var converted)) + if (!long.TryParse(text, NumberStyles.Integer, CultureInfo.CurrentCulture, out var converted)) { value = default; return false; @@ -113,7 +127,7 @@ namespace Microsoft.AspNetCore.Components return true; } - if (!long.TryParse(text, out var converted)) + if (!long.TryParse(text, NumberStyles.Integer, CultureInfo.CurrentCulture, out var converted)) { value = default; return false; @@ -135,7 +149,7 @@ namespace Microsoft.AspNetCore.Components return false; } - if (!float.TryParse(text, out var converted)) + if (!float.TryParse(text, NumberStyles.Number, CultureInfo.CurrentCulture, out var converted)) { value = default; return false; @@ -154,7 +168,7 @@ namespace Microsoft.AspNetCore.Components return true; } - if (!float.TryParse(text, out var converted)) + if (!float.TryParse(text, NumberStyles.Number, CultureInfo.CurrentCulture, out var converted)) { value = default; return false; @@ -176,7 +190,7 @@ namespace Microsoft.AspNetCore.Components return false; } - if (!double.TryParse(text, out var converted)) + if (!double.TryParse(text, NumberStyles.Number, CultureInfo.CurrentCulture, out var converted)) { value = default; return false; @@ -195,7 +209,7 @@ namespace Microsoft.AspNetCore.Components return true; } - if (!double.TryParse(text, out var converted)) + if (!double.TryParse(text, NumberStyles.Number, CultureInfo.CurrentCulture, out var converted)) { value = default; return false; @@ -217,7 +231,7 @@ namespace Microsoft.AspNetCore.Components return false; } - if (!decimal.TryParse(text, out var converted)) + if (!decimal.TryParse(text, NumberStyles.Number, CultureInfo.CurrentCulture, out var converted)) { value = default; return false; @@ -236,7 +250,7 @@ namespace Microsoft.AspNetCore.Components return true; } - if (!decimal.TryParse(text, out var converted)) + if (!decimal.TryParse(text, NumberStyles.Number, CultureInfo.CurrentCulture, out var converted)) { value = default; return false; @@ -246,28 +260,83 @@ namespace Microsoft.AspNetCore.Components return true; } - private static class EnumConverter where T : struct, Enum + private static BindConverter ConvertToDateTime = ConvertToDateTimeCore; + private static BindConverter ConvertToNullableDateTime = ConvertToNullableDateTimeCore; + + private static bool ConvertToDateTimeCore(object obj, out DateTime value) { - public static readonly BindConverter Convert = ConvertCore; - - public static bool ConvertCore(object obj, out T value) + var text = (string)obj; + if (string.IsNullOrEmpty(text)) { - var text = (string)obj; - if (string.IsNullOrEmpty(text)) - { - value = default; - return true; - } + value = default; + return false; + } - if (!Enum.TryParse(text, out var converted)) - { - value = default; - return false; - } + if (!DateTime.TryParse(text, CultureInfo.CurrentCulture, DateTimeStyles.None, out var converted)) + { + value = default; + return false; + } - value = converted; + value = converted; + return true; + } + + private static bool ConvertToNullableDateTimeCore(object obj, out DateTime? value) + { + var text = (string)obj; + if (string.IsNullOrEmpty(text)) + { + value = default; return true; } + + if (!DateTime.TryParse(text, CultureInfo.CurrentCulture, DateTimeStyles.None, out var converted)) + { + value = default; + return false; + } + + value = converted; + return true; + } + + private static bool ConvertToEnum(object obj, out T value) where T : struct, Enum + { + var text = (string)obj; + if (string.IsNullOrEmpty(text)) + { + value = default; + return true; + } + + if (!Enum.TryParse(text, out var converted)) + { + value = default; + return false; + } + + value = converted; + return true; + } + + private static bool ConvertToNullableEnum(object obj, out Nullable value) where T : struct, Enum + { + var text = (string)obj; + if (string.IsNullOrEmpty(text)) + { + value = default; + return true; + } + + if (!Enum.TryParse(text, out var converted)) + { + value = default; + return false; + } + + value = converted; + return true; } /// @@ -284,7 +353,6 @@ namespace Microsoft.AspNetCore.Components Action setter, string existingValue) { - ; return CreateBinderCore(factory, receiver, setter, ConvertToString); } @@ -489,15 +557,6 @@ namespace Microsoft.AspNetCore.Components Action setter, decimal? existingValue) { - Func converter = (obj) => - { - if (decimal.TryParse((string)obj, out var value)) - { - return value; - } - - return null; - }; return CreateBinderCore(factory, receiver, setter, ConvertToNullableDecimal); } @@ -515,28 +574,24 @@ namespace Microsoft.AspNetCore.Components Action setter, DateTime existingValue) { - // Avoiding CreateBinderCore so we can avoid an extra allocating lambda - // when a format is used. - Action callback = (e) => - { - DateTime value = default; - var converted = false; - try - { - value = ConvertDateTime(e.Value, format: null); - converted = true; - } - catch - { - } + return CreateBinderCore(factory, receiver, setter, ConvertToDateTime); + } - // See comments in CreateBinderCore - if (converted) - { - setter(value); - } - }; - return factory.Create(receiver, callback); + /// + /// For internal use only. + /// + /// + /// + /// + /// + /// + public static EventCallback CreateBinder( + this EventCallbackFactory factory, + object receiver, + Action setter, + DateTime? existingValue) + { + return CreateBinderCore(factory, receiver, setter, ConvertToNullableDateTime); } /// @@ -577,6 +632,23 @@ namespace Microsoft.AspNetCore.Components } }; return factory.Create(receiver, callback); + + static DateTime ConvertDateTime(object obj, string format) + { + var text = (string)obj; + if (string.IsNullOrEmpty(text)) + { + return default; + } + else if (format != null && DateTime.TryParseExact(text, format, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var value)) + { + return value; + } + else + { + return DateTime.Parse(text); + } + } } /// @@ -592,26 +664,9 @@ namespace Microsoft.AspNetCore.Components this EventCallbackFactory factory, object receiver, Action setter, - T existingValue) where T : struct, Enum + T existingValue) { - return CreateBinderCore(factory, receiver, setter, EnumConverter.Convert); - } - - private static DateTime ConvertDateTime(object obj, string format) - { - var text = (string)obj; - if (string.IsNullOrEmpty(text)) - { - return default; - } - else if (format != null && DateTime.TryParseExact(text, format, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var value)) - { - return value; - } - else - { - return DateTime.Parse(text); - } + return CreateBinderCore(factory, receiver, setter, BinderConverterCache.Get()); } private static EventCallback CreateBinderCore( @@ -642,5 +697,139 @@ namespace Microsoft.AspNetCore.Components }; return factory.Create(receiver, callback); } + + // We can't rely on generics + static to cache here unfortunately. That would require us to overload + // CreateBinder on T : struct AND T : class, which is not allowed. + private static class BinderConverterCache + { + private readonly static ConcurrentDictionary _cache = new ConcurrentDictionary(); + + private static MethodInfo _convertToEnum; + private static MethodInfo _convertToNullableEnum; + + public static BindConverter Get() + { + if (!_cache.TryGetValue(typeof(T), out var converter)) + { + // We need to replicate all of the primitive cases that we handle here so that they will behave the same way. + // The result will be cached. + if (typeof(T) == typeof(string)) + { + converter = ConvertToString; + } + else if (typeof(T) == typeof(bool)) + { + converter = ConvertToBool; + } + else if (typeof(T) == typeof(bool?)) + { + converter = ConvertToNullableBool; + } + else if (typeof(T) == typeof(int)) + { + converter = ConvertToInt; + } + else if (typeof(T) == typeof(int?)) + { + converter = ConvertToNullableInt; + } + else if (typeof(T) == typeof(long)) + { + converter = ConvertToLong; + } + else if (typeof(T) == typeof(long?)) + { + converter = ConvertToNullableLong; + } + else if (typeof(T) == typeof(float)) + { + converter = ConvertToFloat; + } + else if (typeof(T) == typeof(float?)) + { + converter = ConvertToNullableFloat; + } + else if (typeof(T) == typeof(double)) + { + converter = ConvertToDouble; + } + else if (typeof(T) == typeof(double?)) + { + converter = ConvertToNullableDouble; + } + else if (typeof(T) == typeof(decimal)) + { + converter = ConvertToDecimal; + } + else if (typeof(T) == typeof(decimal?)) + { + converter = ConvertToNullableDecimal; + } + else if (typeof(T) == typeof(DateTime)) + { + converter = ConvertToDateTime; + } + else if (typeof(T) == typeof(DateTime?)) + { + converter = ConvertToNullableDateTime; + } + else if (typeof(T).IsEnum) + { + // We have to deal invoke this dynamically to work around the type constraint on Enum.TryParse. + var method = _convertToEnum ??= typeof(EventCallbackFactoryBinderExtensions).GetMethod(nameof(ConvertToEnum), BindingFlags.NonPublic | BindingFlags.Static); + converter = method.MakeGenericMethod(typeof(T)).CreateDelegate(typeof(BindConverter), target: null); + } + else if (Nullable.GetUnderlyingType(typeof(T)) is Type innerType && innerType.IsEnum) + { + // We have to deal invoke this dynamically to work around the type constraint on Enum.TryParse. + var method = _convertToNullableEnum ??= typeof(EventCallbackFactoryBinderExtensions).GetMethod(nameof(ConvertToNullableEnum), BindingFlags.NonPublic | BindingFlags.Static); + converter = method.MakeGenericMethod(innerType).CreateDelegate(typeof(BindConverter), target: null); + } + else + { + converter = MakeTypeConverterConverter(); + } + + _cache.TryAdd(typeof(T), converter); + } + + return (BindConverter)converter; + } + + private static BindConverter MakeTypeConverterConverter() + { + var typeConverter = TypeDescriptor.GetConverter(typeof(T)); + if (typeConverter == null || !typeConverter.CanConvertFrom(typeof(string))) + { + throw new InvalidOperationException( + $"The type '{typeof(T).FullName}' does not have an associated {typeof(TypeConverter).Name} that supports " + + $"conversion from a string. " + + $"Apply '{typeof(TypeConverterAttribute).Name}' to the type to register a converter."); + } + + return ConvertWithTypeConverter; + + bool ConvertWithTypeConverter(object obj, out T value) + { + var text = (string)obj; + if (string.IsNullOrEmpty(text)) + { + value = default; + return true; + } + + // We intentionally close-over the TypeConverter to cache it. The TypeDescriptor infrastructure is slow. + var converted = typeConverter.ConvertFromString(context: null, CultureInfo.CurrentCulture, text); + if (converted == null) + { + value = default; + return false; + } + + value = (T)converted; + return true; + } + } + } } } diff --git a/src/Components/Components/test/EventCallbackFactoryBinderExtensionsTest.cs b/src/Components/Components/test/EventCallbackFactoryBinderExtensionsTest.cs index 6779401282..84bfc72507 100644 --- a/src/Components/Components/test/EventCallbackFactoryBinderExtensionsTest.cs +++ b/src/Components/Components/test/EventCallbackFactoryBinderExtensionsTest.cs @@ -2,6 +2,8 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.ComponentModel; +using System.Globalization; using System.Threading.Tasks; using Xunit; @@ -344,6 +346,25 @@ namespace Microsoft.AspNetCore.Components Assert.Equal(1, component.Count); } + [Fact] + public async Task CreateBinder_NullableEnum() + { + // Arrange + var value = (AttributeTargets?)AttributeTargets.All; + var component = new EventCountingComponent(); + Action setter = (_) => value = _; + + var binder = EventCallback.Factory.CreateBinder(component, setter, value); + + var expectedValue = AttributeTargets.Class; + + // Act + await binder.InvokeAsync(new UIChangeEventArgs() { Value = expectedValue.ToString(), }); + + Assert.Equal(expectedValue, value); + Assert.Equal(1, component.Count); + } + [Fact] public async Task CreateBinder_DateTime() { @@ -363,6 +384,26 @@ namespace Microsoft.AspNetCore.Components Assert.Equal(1, component.Count); } + [Fact] + public async Task CreateBinder_NullableDateTime() + { + // Arrange + var value = (DateTime?)DateTime.Now; + var component = new EventCountingComponent(); + Action setter = (_) => value = _; + + var binder = EventCallback.Factory.CreateBinder(component, setter, value); + + var expectedValue = new DateTime(2018, 3, 4, 1, 2, 3); + + // Act + await binder.InvokeAsync(new UIChangeEventArgs() { Value = expectedValue.ToString(), }); + + Assert.Equal(expectedValue, value); + Assert.Equal(1, component.Count); + } + + // For now format is only supported by this specific method. [Fact] public async Task CreateBinder_DateTime_Format() { @@ -383,6 +424,80 @@ namespace Microsoft.AspNetCore.Components Assert.Equal(1, component.Count); } + // This uses a type converter + [Fact] + public async Task CreateBinder_Guid() + { + // Arrange + var value = Guid.NewGuid(); + var component = new EventCountingComponent(); + Action setter = (_) => value = _; + + var binder = EventCallback.Factory.CreateBinder(component, setter, value); + + var expectedValue = Guid.NewGuid(); + + // Act + await binder.InvokeAsync(new UIChangeEventArgs() { Value = expectedValue.ToString(), }); + + Assert.Equal(expectedValue, value); + Assert.Equal(1, component.Count); + } + + // This uses a type converter + [Fact] + public async Task CreateBinder_NullableGuid() + { + // Arrange + var value = (Guid?)Guid.NewGuid(); + var component = new EventCountingComponent(); + Action setter = (_) => value = _; + + var binder = EventCallback.Factory.CreateBinder(component, setter, value); + + var expectedValue = Guid.NewGuid(); + + // Act + await binder.InvokeAsync(new UIChangeEventArgs() { Value = expectedValue.ToString(), }); + + Assert.Equal(expectedValue, value); + Assert.Equal(1, component.Count); + } + + [Fact] + public async Task CreateBinder_CustomTypeConverter() + { + // Arrange + var value = new SecretMessage() { Message = "A message", }; + var component = new EventCountingComponent(); + Action setter = (_) => value = _; + + var binder = EventCallback.Factory.CreateBinder(component, setter, value); + + var expectedValue = new SecretMessage() { Message = "TypeConverter may be old, but it still works!", }; + + // Act + await binder.InvokeAsync(new UIChangeEventArgs() { Value = expectedValue.ToString(), }); + + Assert.Equal(expectedValue.Message, value.Message); + Assert.Equal(1, component.Count); + } + + [Fact] + public void CreateBinder_GenericWithoutTypeConverter_Throws() + { + var value = new ClassWithoutTypeConverter(); + var component = new EventCountingComponent(); + Action setter = (_) => value = _; + + var ex = Assert.Throws(() => EventCallback.Factory.CreateBinder(component, setter, value)); + + Assert.Equal( + $"The type '{typeof(ClassWithoutTypeConverter).FullName}' does not have an associated TypeConverter that supports conversion from a string. " + + $"Apply 'TypeConverterAttribute' to the type to register a converter.", + ex.Message); + } + private class EventCountingComponent : IComponent, IHandleEvent { public int Count; @@ -403,5 +518,42 @@ namespace Microsoft.AspNetCore.Components throw new System.NotImplementedException(); } } + + private class ClassWithoutTypeConverter + { + } + + [TypeConverter(typeof(SecretMessageTypeConverter))] + private class SecretMessage + { + public string Message { get; set; } + + public override string ToString() + { + return Message; + } + } + + private class SecretMessageTypeConverter : TypeConverter + { + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof(string)) + { + return true; + } + + return false; + } + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value is string message) + { + return new SecretMessage() { Message = message, }; + } + + return null; + } + } } } diff --git a/src/Components/test/E2ETest/Tests/BindTest.cs b/src/Components/test/E2ETest/Tests/BindTest.cs index 51fcc9ea9d..4931dd786e 100644 --- a/src/Components/test/E2ETest/Tests/BindTest.cs +++ b/src/Components/test/E2ETest/Tests/BindTest.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 BasicTestApp; using Microsoft.AspNetCore.Components.E2ETest.Infrastructure; using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures; @@ -538,5 +539,48 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests Browser.Equal("0.011", () => boundValue.Text); Assert.Equal("0.011", mirrorValue.GetAttribute("value")); } + + [Fact] + public void CanBindTextboxGenericInt() + { + var target = Browser.FindElement(By.Id("textbox-generic-int")); + var boundValue = Browser.FindElement(By.Id("textbox-generic-int-value")); + var mirrorValue = Browser.FindElement(By.Id("textbox-generic-int-mirror")); + Assert.Equal("-42", target.GetAttribute("value")); + Assert.Equal("-42", boundValue.Text); + Assert.Equal("-42", mirrorValue.GetAttribute("value")); + + // Modify target; value is not updated because it's not convertable. + target.Clear(); + Browser.Equal("-42", () => boundValue.Text); + Assert.Equal("-42", mirrorValue.GetAttribute("value")); + + // Modify target; verify value is updated and that textboxes linked to the same data are updated + target.SendKeys("42\t"); + Browser.Equal("42", () => boundValue.Text); + Assert.Equal("42", mirrorValue.GetAttribute("value")); + } + + [Fact] + public void CanBindTextboxGenericGuid() + { + var target = Browser.FindElement(By.Id("textbox-generic-guid")); + var boundValue = Browser.FindElement(By.Id("textbox-generic-guid-value")); + var mirrorValue = Browser.FindElement(By.Id("textbox-generic-guid-mirror")); + Assert.Equal("00000000-0000-0000-0000-000000000000", target.GetAttribute("value")); + Assert.Equal("00000000-0000-0000-0000-000000000000", boundValue.Text); + Assert.Equal("00000000-0000-0000-0000-000000000000", mirrorValue.GetAttribute("value")); + + // Modify target; value is not updated because it's not convertable. + target.Clear(); + Browser.Equal("00000000-0000-0000-0000-000000000000", () => boundValue.Text); + Assert.Equal("00000000-0000-0000-0000-000000000000", mirrorValue.GetAttribute("value")); + + // Modify target; verify value is updated and that textboxes linked to the same data are updated + var newValue = Guid.NewGuid().ToString(); + target.SendKeys(newValue + "\t"); + Browser.Equal(newValue, () => boundValue.Text); + Assert.Equal(newValue, mirrorValue.GetAttribute("value")); + } } } diff --git a/src/Components/test/testassets/BasicTestApp/BindCasesComponent.razor b/src/Components/test/testassets/BasicTestApp/BindCasesComponent.razor index 362db2936f..a8b393660b 100644 --- a/src/Components/test/testassets/BasicTestApp/BindCasesComponent.razor +++ b/src/Components/test/testassets/BasicTestApp/BindCasesComponent.razor @@ -90,6 +90,19 @@

+

+ Generic bind (int): + + @textboxGenericIntValue + +

+

+ Generic bind (guid): + + @textboxGenericGuidValue + +

+

Text Area

Initially blank: @@ -138,36 +151,39 @@

@code { - string textboxInitiallyBlankValue = null; - string textboxInitiallyPopulatedValue = "Hello"; +string textboxInitiallyBlankValue = null; +string textboxInitiallyPopulatedValue = "Hello"; - string textAreaInitiallyBlankValue = null; - string textAreaInitiallyPopulatedValue = "Hello"; +string textAreaInitiallyBlankValue = null; +string textAreaInitiallyPopulatedValue = "Hello"; - bool? checkboxInitiallyNullValue = null; - bool checkboxInitiallyUncheckedValue = false; - bool checkboxInitiallyCheckedValue = true; +bool? checkboxInitiallyNullValue = null; +bool checkboxInitiallyUncheckedValue = false; +bool checkboxInitiallyCheckedValue = true; - int textboxIntValue = -42; - int? textboxNullableIntValue = null; - long textboxLongValue = 3_000_000_000; - long? textboxNullableLongValue = null; - float textboxFloatValue = 3.141f; - float? textboxNullableFloatValue = null; - double textboxDoubleValue = 3.14159265359d; - double? textboxNullableDoubleValue = null; - decimal textboxDecimalValue = 0.0000000000000000000000000001M; - decimal? textboxNullableDecimalValue = null; - decimal textboxDecimalInvalidValue = 0.0000000000000000000000000001M; - decimal? textboxNullableDecimalInvalidValue = null; +int textboxIntValue = -42; +int? textboxNullableIntValue = null; +long textboxLongValue = 3_000_000_000; +long? textboxNullableLongValue = null; +float textboxFloatValue = 3.141f; +float? textboxNullableFloatValue = null; +double textboxDoubleValue = 3.14159265359d; +double? textboxNullableDoubleValue = null; +decimal textboxDecimalValue = 0.0000000000000000000000000001M; +decimal? textboxNullableDecimalValue = null; +decimal textboxDecimalInvalidValue = 0.0000000000000000000000000001M; +decimal? textboxNullableDecimalInvalidValue = null; - bool includeFourthOption = false; - enum SelectableValue { First, Second, Third, Fourth } - SelectableValue selectValue = SelectableValue.Second; +int textboxGenericIntValue = -42; +Guid textboxGenericGuidValue = Guid.Empty; - void AddAndSelectNewSelectOption() - { - includeFourthOption = true; - selectValue = SelectableValue.Fourth; - } +bool includeFourthOption = false; +enum SelectableValue { First, Second, Third, Fourth } +SelectableValue selectValue = SelectableValue.Second; + +void AddAndSelectNewSelectOption() +{ + includeFourthOption = true; + selectValue = SelectableValue.Fourth; +} } diff --git a/src/Components/test/testassets/BasicTestApp/BindGenericComponent.razor b/src/Components/test/testassets/BasicTestApp/BindGenericComponent.razor new file mode 100644 index 0000000000..54072b918e --- /dev/null +++ b/src/Components/test/testassets/BasicTestApp/BindGenericComponent.razor @@ -0,0 +1,9 @@ +@typeparam TValue + + + +@code { + [Parameter] string Id { get; set; } + [Parameter] TValue Value { get; set; } + [Parameter] EventCallback ValueChanged { get; set; } +} diff --git a/src/Hosting/test/FunctionalTests/ShutdownTests.cs b/src/Hosting/test/FunctionalTests/ShutdownTests.cs index 82e707487d..4c94b289a7 100644 --- a/src/Hosting/test/FunctionalTests/ShutdownTests.cs +++ b/src/Hosting/test/FunctionalTests/ShutdownTests.cs @@ -28,6 +28,7 @@ namespace Microsoft.AspNetCore.Hosting.FunctionalTests [ConditionalFact] [OSSkipCondition(OperatingSystems.Windows)] [OSSkipCondition(OperatingSystems.MacOSX)] + [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2577", FlakyOn.All)] public async Task ShutdownTestRun() { await ExecuteShutdownTest(nameof(ShutdownTestRun), "Run"); diff --git a/src/Mvc/Mvc.Core/test/ModelBinding/Binders/FloatingPointTypeModelBinderTestOfT.cs b/src/Mvc/Mvc.Core/test/ModelBinding/Binders/FloatingPointTypeModelBinderTestOfT.cs index 0a8f69b60f..ab30a8005b 100644 --- a/src/Mvc/Mvc.Core/test/ModelBinding/Binders/FloatingPointTypeModelBinderTestOfT.cs +++ b/src/Mvc/Mvc.Core/test/ModelBinding/Binders/FloatingPointTypeModelBinderTestOfT.cs @@ -5,6 +5,7 @@ using System; using System.Globalization; using System.Threading.Tasks; using Microsoft.AspNetCore.Testing; +using Microsoft.AspNetCore.Testing.xunit; using Xunit; namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders @@ -343,6 +344,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders [Theory] [MemberData(nameof(ConvertibleTypeData))] + [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2626", FlakyOn.AzP.Linux)] public async Task BindModel_ReturnsModel_IfAttemptedValueIsValid_FrenchThirtyTwoThousandPointOne(Type destinationType) { // Arrange diff --git a/src/Mvc/Mvc.ViewFeatures/test/Rendering/JsonHelperTestBase.cs b/src/Mvc/Mvc.ViewFeatures/test/Rendering/JsonHelperTestBase.cs index 90d994af41..cfbabe735b 100644 --- a/src/Mvc/Mvc.ViewFeatures/test/Rendering/JsonHelperTestBase.cs +++ b/src/Mvc/Mvc.ViewFeatures/test/Rendering/JsonHelperTestBase.cs @@ -10,7 +10,7 @@ namespace Microsoft.AspNetCore.Mvc.Rendering protected abstract IJsonHelper GetJsonHelper(); [Fact] - public void Serialize_EscapesHtmlByDefault() + public virtual void Serialize_EscapesHtmlByDefault() { // Arrange var helper = GetJsonHelper(); diff --git a/src/Mvc/Mvc.ViewFeatures/test/Rendering/SystemTextJsonHelperTest.cs b/src/Mvc/Mvc.ViewFeatures/test/Rendering/SystemTextJsonHelperTest.cs index 4550976a40..e754844dec 100644 --- a/src/Mvc/Mvc.ViewFeatures/test/Rendering/SystemTextJsonHelperTest.cs +++ b/src/Mvc/Mvc.ViewFeatures/test/Rendering/SystemTextJsonHelperTest.cs @@ -2,7 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Text.Json.Serialization; +using Microsoft.AspNetCore.Html; using Microsoft.Extensions.Options; +using Xunit; namespace Microsoft.AspNetCore.Mvc.Rendering { @@ -13,5 +15,24 @@ namespace Microsoft.AspNetCore.Mvc.Rendering var options = new JsonOptions() { JsonSerializerOptions = { PropertyNamingPolicy = JsonNamingPolicy.CamelCase } }; return new SystemTextJsonHelper(Options.Create(options)); } + + [Fact] + public override void Serialize_EscapesHtmlByDefault() + { + // Arrange + var helper = GetJsonHelper(); + var obj = new + { + HTML = "John Doe" + }; + var expectedOutput = "{\"html\":\"\\u003cb\\u003eJohn Doe\\u003c\\u002fb\\u003e\"}"; + + // Act + var result = helper.Serialize(obj); + + // Assert + var htmlString = Assert.IsType(result); + Assert.Equal(expectedOutput, htmlString.ToString()); + } } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Pages/Shared/_CookieConsentPartial.cshtml b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Pages/Shared/_CookieConsentPartial.cshtml deleted file mode 100644 index 999a0ed5bf..0000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Pages/Shared/_CookieConsentPartial.cshtml +++ /dev/null @@ -1,25 +0,0 @@ -@using Microsoft.AspNetCore.Http.Features - -@{ - var consentFeature = Context.Features.Get(); - var showBanner = !consentFeature?.CanTrack ?? false; - var cookieString = consentFeature?.CreateConsentCookie(); -} - -@if (showBanner) -{ - - -} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Pages/Shared/_Layout.cshtml b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Pages/Shared/_Layout.cshtml index a02915b198..198a48ef80 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Pages/Shared/_Layout.cshtml +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Pages/Shared/_Layout.cshtml @@ -34,13 +34,9 @@ -
- -
+
@RenderBody() -
-
- +