diff --git a/.github/workflows/runtime-sync.yml b/.github/workflows/runtime-sync.yml index 41044d30ee..03e7e8f9d6 100644 --- a/.github/workflows/runtime-sync.yml +++ b/.github/workflows/runtime-sync.yml @@ -28,7 +28,7 @@ jobs: # Test this script using changes in a fork repository: 'dotnet/runtime' path: runtime - ref: release/5.0-rc1 + ref: release/5.0 - name: Copy shell: cmd working-directory: .\runtime\src\libraries\Common\src\System\Net\Http\aspnetcore\ diff --git a/AspNetCore.sln b/AspNetCore.sln index f0f0fe4031..968ff850f8 100644 --- a/AspNetCore.sln +++ b/AspNetCore.sln @@ -1397,14 +1397,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sockets.BindTests", "src\Se EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "http2cat", "src\Servers\Kestrel\samples\http2cat\http2cat.csproj", "{8BDEC645-73BD-453B-8A5C-D616BC4EA08D}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QuicSampleApp", "src\Servers\Kestrel\samples\QuicSampleApp\QuicSampleApp.csproj", "{CBCD6AC2-72D3-4E82-9E78-12E3A9C68E1D}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Transport.Quic", "Transport.Quic", "{EE9D0952-6060-4723-B329-94A2950A6762}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.Kestrel.Transport.Experimental.Quic", "src\Servers\Kestrel\Transport.Quic\src\Microsoft.AspNetCore.Server.Kestrel.Transport.Experimental.Quic.csproj", "{132D43A2-067A-4E24-A520-45B9F14DCB8E}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QuicSampleClient", "src\Servers\Kestrel\samples\QuicSampleClient\QuicSampleClient.csproj", "{FA8D7CA4-C33B-4409-865F-54192BAC59A4}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Http3SampleApp", "src\Servers\Kestrel\samples\Http3SampleApp\Http3SampleApp.csproj", "{2EC4E939-513F-44CD-A956-498966EAC929}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HttpStress", "src\Servers\Kestrel\stress\HttpStress.csproj", "{987E1C29-F124-40C8-8E6F-1B2B6A4CB62A}" @@ -1423,13 +1419,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Compon EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sdk", "Sdk", "{FED4267E-E5E4-49C5-98DB-8B3F203596EE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.NET.Sdk.BlazorWebAssembly", "src\Components\WebAssembly\Sdk\src\Microsoft.NET.Sdk.BlazorWebAssembly.csproj", "{6B2734BF-C61D-4889-ABBF-456A4075D59B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.NET.Sdk.BlazorWebAssembly", "src\Components\WebAssembly\Sdk\src\Microsoft.NET.Sdk.BlazorWebAssembly.csproj", "{6B2734BF-C61D-4889-ABBF-456A4075D59B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.NET.Sdk.BlazorWebAssembly.Tests", "src\Components\WebAssembly\Sdk\test\Microsoft.NET.Sdk.BlazorWebAssembly.Tests.csproj", "{83371889-9A3E-4D16-AE77-EB4F83BC6374}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.NET.Sdk.BlazorWebAssembly.Tests", "src\Components\WebAssembly\Sdk\test\Microsoft.NET.Sdk.BlazorWebAssembly.Tests.csproj", "{83371889-9A3E-4D16-AE77-EB4F83BC6374}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.NET.Sdk.BlazorWebAssembly.IntegrationTests", "src\Components\WebAssembly\Sdk\integrationtests\Microsoft.NET.Sdk.BlazorWebAssembly.IntegrationTests.csproj", "{525EBCB4-A870-470B-BC90-845306C337D1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.NET.Sdk.BlazorWebAssembly.IntegrationTests", "src\Components\WebAssembly\Sdk\integrationtests\Microsoft.NET.Sdk.BlazorWebAssembly.IntegrationTests.csproj", "{525EBCB4-A870-470B-BC90-845306C337D1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.NET.Sdk.BlazorWebAssembly.Tools", "src\Components\WebAssembly\Sdk\tools\Microsoft.NET.Sdk.BlazorWebAssembly.Tools.csproj", "{175E5CD8-92D4-46BB-882E-3A930D3302D4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.NET.Sdk.BlazorWebAssembly.Tools", "src\Components\WebAssembly\Sdk\tools\Microsoft.NET.Sdk.BlazorWebAssembly.Tools.csproj", "{175E5CD8-92D4-46BB-882E-3A930D3302D4}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testassets", "testassets", "{6126DCE4-9692-4EE2-B240-C65743572995}" EndProject @@ -1455,7 +1451,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InteropClient", "src\Grpc\t EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InteropWebsite", "src\Grpc\test\testassets\InteropWebsite\InteropWebsite.csproj", "{19189670-E206-471D-94F8-7D3D545E5020}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wasm.Performance.ConsoleHost", "src\Components\benchmarkapps\Wasm.Performance\ConsoleHost\Wasm.Performance.ConsoleHost.csproj", "{E9408723-E6A9-4715-B906-3B25B0238ABA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wasm.Performance.ConsoleHost", "src\Components\benchmarkapps\Wasm.Performance\ConsoleHost\Wasm.Performance.ConsoleHost.csproj", "{E9408723-E6A9-4715-B906-3B25B0238ABA}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InProcessWebSite", "src\Servers\IIS\IIS\test\testassets\InProcessWebSite\InProcessWebSite.csproj", "{8DA61885-B95E-4BA1-A752-C79B6597FC44}" EndProject @@ -1483,6 +1479,36 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Watch. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Watch.BrowserRefresh.Tests", "src\Tools\dotnet-watch\BrowserRefresh\test\Microsoft.AspNetCore.Watch.BrowserRefresh.Tests.csproj", "{E6A23627-8D63-4DF1-A4F2-8881172C1FE6}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testassets", "testassets", "{7D2B0799-A634-42AC-AE77-5D167BA51389}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HostedInAspNet.Client", "src\Components\WebAssembly\testassets\HostedInAspNet.Client\HostedInAspNet.Client.csproj", "{9788C76F-658B-4441-88F8-22C6B86FAD27}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HostedInAspNet.Server", "src\Components\WebAssembly\testassets\HostedInAspNet.Server\HostedInAspNet.Server.csproj", "{1970D5CD-D9A4-4673-A297-179BB04199F4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StandaloneApp", "src\Components\WebAssembly\testassets\StandaloneApp\StandaloneApp.csproj", "{A40350FE-4334-4007-B1C3-6BEB1B070309}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wasm.Authentication.Client", "src\Components\WebAssembly\testassets\Wasm.Authentication.Client\Wasm.Authentication.Client.csproj", "{C26965A9-EAC6-4E5A-B8C1-D161260EFE4F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wasm.Authentication.Server", "src\Components\WebAssembly\testassets\Wasm.Authentication.Server\Wasm.Authentication.Server.csproj", "{FE5290C7-45DA-46F8-BD74-698E7A161DD6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wasm.Authentication.Shared", "src\Components\WebAssembly\testassets\Wasm.Authentication.Shared\Wasm.Authentication.Shared.csproj", "{ED66DC0E-FD6A-477A-BA8A-5273AA64F580}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HealthChecks", "HealthChecks", "{C1E7F837-6988-43E2-9E1C-7302DB484F99}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{2A91479A-4ABE-4BB7-9A5E-CA3B9CCFC69E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{7CB09412-C9B0-47E8-A8C3-311AA4CFDE04}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Abstractions", "Abstractions", "{22D7D74B-565D-4047-97B4-F149B1A13350}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions", "src\HealthChecks\Abstractions\src\Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions.csproj", "{B06040BC-DA28-4923-8CAC-20EB517D471B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Diagnostics.HealthChecks", "src\HealthChecks\HealthChecks\src\Microsoft.Extensions.Diagnostics.HealthChecks.csproj", "{55CACC1F-FE96-47C8-8073-91F4CAA55C75}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Diagnostics.HealthChecks.Tests", "src\HealthChecks\HealthChecks\test\Microsoft.Extensions.Diagnostics.HealthChecks.Tests.csproj", "{7509AA1E-3093-4BEE-984F-E11579E98A11}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.JSInterop.Tests", "src\JSInterop\Microsoft.JSInterop\test\Microsoft.JSInterop.Tests.csproj", "{DAAB6B35-CBD2-4573-B633-CDD42F583A0E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -6653,18 +6679,6 @@ Global {8BDEC645-73BD-453B-8A5C-D616BC4EA08D}.Release|x64.Build.0 = Release|Any CPU {8BDEC645-73BD-453B-8A5C-D616BC4EA08D}.Release|x86.ActiveCfg = Release|Any CPU {8BDEC645-73BD-453B-8A5C-D616BC4EA08D}.Release|x86.Build.0 = Release|Any CPU - {CBCD6AC2-72D3-4E82-9E78-12E3A9C68E1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CBCD6AC2-72D3-4E82-9E78-12E3A9C68E1D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CBCD6AC2-72D3-4E82-9E78-12E3A9C68E1D}.Debug|x64.ActiveCfg = Debug|Any CPU - {CBCD6AC2-72D3-4E82-9E78-12E3A9C68E1D}.Debug|x64.Build.0 = Debug|Any CPU - {CBCD6AC2-72D3-4E82-9E78-12E3A9C68E1D}.Debug|x86.ActiveCfg = Debug|Any CPU - {CBCD6AC2-72D3-4E82-9E78-12E3A9C68E1D}.Debug|x86.Build.0 = Debug|Any CPU - {CBCD6AC2-72D3-4E82-9E78-12E3A9C68E1D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CBCD6AC2-72D3-4E82-9E78-12E3A9C68E1D}.Release|Any CPU.Build.0 = Release|Any CPU - {CBCD6AC2-72D3-4E82-9E78-12E3A9C68E1D}.Release|x64.ActiveCfg = Release|Any CPU - {CBCD6AC2-72D3-4E82-9E78-12E3A9C68E1D}.Release|x64.Build.0 = Release|Any CPU - {CBCD6AC2-72D3-4E82-9E78-12E3A9C68E1D}.Release|x86.ActiveCfg = Release|Any CPU - {CBCD6AC2-72D3-4E82-9E78-12E3A9C68E1D}.Release|x86.Build.0 = Release|Any CPU {132D43A2-067A-4E24-A520-45B9F14DCB8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {132D43A2-067A-4E24-A520-45B9F14DCB8E}.Debug|Any CPU.Build.0 = Debug|Any CPU {132D43A2-067A-4E24-A520-45B9F14DCB8E}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -6677,18 +6691,6 @@ Global {132D43A2-067A-4E24-A520-45B9F14DCB8E}.Release|x64.Build.0 = Release|Any CPU {132D43A2-067A-4E24-A520-45B9F14DCB8E}.Release|x86.ActiveCfg = Release|Any CPU {132D43A2-067A-4E24-A520-45B9F14DCB8E}.Release|x86.Build.0 = Release|Any CPU - {FA8D7CA4-C33B-4409-865F-54192BAC59A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FA8D7CA4-C33B-4409-865F-54192BAC59A4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FA8D7CA4-C33B-4409-865F-54192BAC59A4}.Debug|x64.ActiveCfg = Debug|Any CPU - {FA8D7CA4-C33B-4409-865F-54192BAC59A4}.Debug|x64.Build.0 = Debug|Any CPU - {FA8D7CA4-C33B-4409-865F-54192BAC59A4}.Debug|x86.ActiveCfg = Debug|Any CPU - {FA8D7CA4-C33B-4409-865F-54192BAC59A4}.Debug|x86.Build.0 = Debug|Any CPU - {FA8D7CA4-C33B-4409-865F-54192BAC59A4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FA8D7CA4-C33B-4409-865F-54192BAC59A4}.Release|Any CPU.Build.0 = Release|Any CPU - {FA8D7CA4-C33B-4409-865F-54192BAC59A4}.Release|x64.ActiveCfg = Release|Any CPU - {FA8D7CA4-C33B-4409-865F-54192BAC59A4}.Release|x64.Build.0 = Release|Any CPU - {FA8D7CA4-C33B-4409-865F-54192BAC59A4}.Release|x86.ActiveCfg = Release|Any CPU - {FA8D7CA4-C33B-4409-865F-54192BAC59A4}.Release|x86.Build.0 = Release|Any CPU {2EC4E939-513F-44CD-A956-498966EAC929}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2EC4E939-513F-44CD-A956-498966EAC929}.Debug|Any CPU.Build.0 = Debug|Any CPU {2EC4E939-513F-44CD-A956-498966EAC929}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -6809,30 +6811,6 @@ Global {175E5CD8-92D4-46BB-882E-3A930D3302D4}.Release|x64.Build.0 = Release|Any CPU {175E5CD8-92D4-46BB-882E-3A930D3302D4}.Release|x86.ActiveCfg = Release|Any CPU {175E5CD8-92D4-46BB-882E-3A930D3302D4}.Release|x86.Build.0 = Release|Any CPU - {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Debug|x64.ActiveCfg = Debug|Any CPU - {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Debug|x64.Build.0 = Debug|Any CPU - {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Debug|x86.ActiveCfg = Debug|Any CPU - {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Debug|x86.Build.0 = Debug|Any CPU - {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Release|Any CPU.Build.0 = Release|Any CPU - {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Release|x64.ActiveCfg = Release|Any CPU - {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Release|x64.Build.0 = Release|Any CPU - {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Release|x86.ActiveCfg = Release|Any CPU - {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Release|x86.Build.0 = Release|Any CPU - {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Debug|x64.ActiveCfg = Debug|Any CPU - {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Debug|x64.Build.0 = Debug|Any CPU - {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Debug|x86.ActiveCfg = Debug|Any CPU - {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Debug|x86.Build.0 = Debug|Any CPU - {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Release|Any CPU.Build.0 = Release|Any CPU - {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Release|x64.ActiveCfg = Release|Any CPU - {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Release|x64.Build.0 = Release|Any CPU - {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Release|x86.ActiveCfg = Release|Any CPU - {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Release|x86.Build.0 = Release|Any CPU {46FB7E93-1294-4068-B80A-D4864F78277A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {46FB7E93-1294-4068-B80A-D4864F78277A}.Debug|Any CPU.Build.0 = Debug|Any CPU {46FB7E93-1294-4068-B80A-D4864F78277A}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -7071,6 +7049,150 @@ Global {7E268085-1046-4362-80CB-2977FF826DCA}.Release|x64.Build.0 = Release|Any CPU {7E268085-1046-4362-80CB-2977FF826DCA}.Release|x86.ActiveCfg = Release|Any CPU {7E268085-1046-4362-80CB-2977FF826DCA}.Release|x86.Build.0 = Release|Any CPU + {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Debug|x64.ActiveCfg = Debug|Any CPU + {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Debug|x64.Build.0 = Debug|Any CPU + {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Debug|x86.ActiveCfg = Debug|Any CPU + {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Debug|x86.Build.0 = Debug|Any CPU + {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Release|Any CPU.Build.0 = Release|Any CPU + {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Release|x64.ActiveCfg = Release|Any CPU + {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Release|x64.Build.0 = Release|Any CPU + {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Release|x86.ActiveCfg = Release|Any CPU + {A5CE25E9-89E1-4F2C-9B89-0C161707E700}.Release|x86.Build.0 = Release|Any CPU + {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Debug|x64.ActiveCfg = Debug|Any CPU + {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Debug|x64.Build.0 = Debug|Any CPU + {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Debug|x86.ActiveCfg = Debug|Any CPU + {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Debug|x86.Build.0 = Debug|Any CPU + {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Release|Any CPU.Build.0 = Release|Any CPU + {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Release|x64.ActiveCfg = Release|Any CPU + {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Release|x64.Build.0 = Release|Any CPU + {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Release|x86.ActiveCfg = Release|Any CPU + {E6A23627-8D63-4DF1-A4F2-8881172C1FE6}.Release|x86.Build.0 = Release|Any CPU + {9788C76F-658B-4441-88F8-22C6B86FAD27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9788C76F-658B-4441-88F8-22C6B86FAD27}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9788C76F-658B-4441-88F8-22C6B86FAD27}.Debug|x64.ActiveCfg = Debug|Any CPU + {9788C76F-658B-4441-88F8-22C6B86FAD27}.Debug|x64.Build.0 = Debug|Any CPU + {9788C76F-658B-4441-88F8-22C6B86FAD27}.Debug|x86.ActiveCfg = Debug|Any CPU + {9788C76F-658B-4441-88F8-22C6B86FAD27}.Debug|x86.Build.0 = Debug|Any CPU + {9788C76F-658B-4441-88F8-22C6B86FAD27}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9788C76F-658B-4441-88F8-22C6B86FAD27}.Release|Any CPU.Build.0 = Release|Any CPU + {9788C76F-658B-4441-88F8-22C6B86FAD27}.Release|x64.ActiveCfg = Release|Any CPU + {9788C76F-658B-4441-88F8-22C6B86FAD27}.Release|x64.Build.0 = Release|Any CPU + {9788C76F-658B-4441-88F8-22C6B86FAD27}.Release|x86.ActiveCfg = Release|Any CPU + {9788C76F-658B-4441-88F8-22C6B86FAD27}.Release|x86.Build.0 = Release|Any CPU + {1970D5CD-D9A4-4673-A297-179BB04199F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1970D5CD-D9A4-4673-A297-179BB04199F4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1970D5CD-D9A4-4673-A297-179BB04199F4}.Debug|x64.ActiveCfg = Debug|Any CPU + {1970D5CD-D9A4-4673-A297-179BB04199F4}.Debug|x64.Build.0 = Debug|Any CPU + {1970D5CD-D9A4-4673-A297-179BB04199F4}.Debug|x86.ActiveCfg = Debug|Any CPU + {1970D5CD-D9A4-4673-A297-179BB04199F4}.Debug|x86.Build.0 = Debug|Any CPU + {1970D5CD-D9A4-4673-A297-179BB04199F4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1970D5CD-D9A4-4673-A297-179BB04199F4}.Release|Any CPU.Build.0 = Release|Any CPU + {1970D5CD-D9A4-4673-A297-179BB04199F4}.Release|x64.ActiveCfg = Release|Any CPU + {1970D5CD-D9A4-4673-A297-179BB04199F4}.Release|x64.Build.0 = Release|Any CPU + {1970D5CD-D9A4-4673-A297-179BB04199F4}.Release|x86.ActiveCfg = Release|Any CPU + {1970D5CD-D9A4-4673-A297-179BB04199F4}.Release|x86.Build.0 = Release|Any CPU + {A40350FE-4334-4007-B1C3-6BEB1B070309}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A40350FE-4334-4007-B1C3-6BEB1B070309}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A40350FE-4334-4007-B1C3-6BEB1B070309}.Debug|x64.ActiveCfg = Debug|Any CPU + {A40350FE-4334-4007-B1C3-6BEB1B070309}.Debug|x64.Build.0 = Debug|Any CPU + {A40350FE-4334-4007-B1C3-6BEB1B070309}.Debug|x86.ActiveCfg = Debug|Any CPU + {A40350FE-4334-4007-B1C3-6BEB1B070309}.Debug|x86.Build.0 = Debug|Any CPU + {A40350FE-4334-4007-B1C3-6BEB1B070309}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A40350FE-4334-4007-B1C3-6BEB1B070309}.Release|Any CPU.Build.0 = Release|Any CPU + {A40350FE-4334-4007-B1C3-6BEB1B070309}.Release|x64.ActiveCfg = Release|Any CPU + {A40350FE-4334-4007-B1C3-6BEB1B070309}.Release|x64.Build.0 = Release|Any CPU + {A40350FE-4334-4007-B1C3-6BEB1B070309}.Release|x86.ActiveCfg = Release|Any CPU + {A40350FE-4334-4007-B1C3-6BEB1B070309}.Release|x86.Build.0 = Release|Any CPU + {C26965A9-EAC6-4E5A-B8C1-D161260EFE4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C26965A9-EAC6-4E5A-B8C1-D161260EFE4F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C26965A9-EAC6-4E5A-B8C1-D161260EFE4F}.Debug|x64.ActiveCfg = Debug|Any CPU + {C26965A9-EAC6-4E5A-B8C1-D161260EFE4F}.Debug|x64.Build.0 = Debug|Any CPU + {C26965A9-EAC6-4E5A-B8C1-D161260EFE4F}.Debug|x86.ActiveCfg = Debug|Any CPU + {C26965A9-EAC6-4E5A-B8C1-D161260EFE4F}.Debug|x86.Build.0 = Debug|Any CPU + {C26965A9-EAC6-4E5A-B8C1-D161260EFE4F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C26965A9-EAC6-4E5A-B8C1-D161260EFE4F}.Release|Any CPU.Build.0 = Release|Any CPU + {C26965A9-EAC6-4E5A-B8C1-D161260EFE4F}.Release|x64.ActiveCfg = Release|Any CPU + {C26965A9-EAC6-4E5A-B8C1-D161260EFE4F}.Release|x64.Build.0 = Release|Any CPU + {C26965A9-EAC6-4E5A-B8C1-D161260EFE4F}.Release|x86.ActiveCfg = Release|Any CPU + {C26965A9-EAC6-4E5A-B8C1-D161260EFE4F}.Release|x86.Build.0 = Release|Any CPU + {FE5290C7-45DA-46F8-BD74-698E7A161DD6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FE5290C7-45DA-46F8-BD74-698E7A161DD6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FE5290C7-45DA-46F8-BD74-698E7A161DD6}.Debug|x64.ActiveCfg = Debug|Any CPU + {FE5290C7-45DA-46F8-BD74-698E7A161DD6}.Debug|x64.Build.0 = Debug|Any CPU + {FE5290C7-45DA-46F8-BD74-698E7A161DD6}.Debug|x86.ActiveCfg = Debug|Any CPU + {FE5290C7-45DA-46F8-BD74-698E7A161DD6}.Debug|x86.Build.0 = Debug|Any CPU + {FE5290C7-45DA-46F8-BD74-698E7A161DD6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FE5290C7-45DA-46F8-BD74-698E7A161DD6}.Release|Any CPU.Build.0 = Release|Any CPU + {FE5290C7-45DA-46F8-BD74-698E7A161DD6}.Release|x64.ActiveCfg = Release|Any CPU + {FE5290C7-45DA-46F8-BD74-698E7A161DD6}.Release|x64.Build.0 = Release|Any CPU + {FE5290C7-45DA-46F8-BD74-698E7A161DD6}.Release|x86.ActiveCfg = Release|Any CPU + {FE5290C7-45DA-46F8-BD74-698E7A161DD6}.Release|x86.Build.0 = Release|Any CPU + {ED66DC0E-FD6A-477A-BA8A-5273AA64F580}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ED66DC0E-FD6A-477A-BA8A-5273AA64F580}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ED66DC0E-FD6A-477A-BA8A-5273AA64F580}.Debug|x64.ActiveCfg = Debug|Any CPU + {ED66DC0E-FD6A-477A-BA8A-5273AA64F580}.Debug|x64.Build.0 = Debug|Any CPU + {ED66DC0E-FD6A-477A-BA8A-5273AA64F580}.Debug|x86.ActiveCfg = Debug|Any CPU + {ED66DC0E-FD6A-477A-BA8A-5273AA64F580}.Debug|x86.Build.0 = Debug|Any CPU + {ED66DC0E-FD6A-477A-BA8A-5273AA64F580}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ED66DC0E-FD6A-477A-BA8A-5273AA64F580}.Release|Any CPU.Build.0 = Release|Any CPU + {ED66DC0E-FD6A-477A-BA8A-5273AA64F580}.Release|x64.ActiveCfg = Release|Any CPU + {ED66DC0E-FD6A-477A-BA8A-5273AA64F580}.Release|x64.Build.0 = Release|Any CPU + {ED66DC0E-FD6A-477A-BA8A-5273AA64F580}.Release|x86.ActiveCfg = Release|Any CPU + {ED66DC0E-FD6A-477A-BA8A-5273AA64F580}.Release|x86.Build.0 = Release|Any CPU + {B06040BC-DA28-4923-8CAC-20EB517D471B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B06040BC-DA28-4923-8CAC-20EB517D471B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B06040BC-DA28-4923-8CAC-20EB517D471B}.Debug|x64.ActiveCfg = Debug|Any CPU + {B06040BC-DA28-4923-8CAC-20EB517D471B}.Debug|x64.Build.0 = Debug|Any CPU + {B06040BC-DA28-4923-8CAC-20EB517D471B}.Debug|x86.ActiveCfg = Debug|Any CPU + {B06040BC-DA28-4923-8CAC-20EB517D471B}.Debug|x86.Build.0 = Debug|Any CPU + {B06040BC-DA28-4923-8CAC-20EB517D471B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B06040BC-DA28-4923-8CAC-20EB517D471B}.Release|Any CPU.Build.0 = Release|Any CPU + {B06040BC-DA28-4923-8CAC-20EB517D471B}.Release|x64.ActiveCfg = Release|Any CPU + {B06040BC-DA28-4923-8CAC-20EB517D471B}.Release|x64.Build.0 = Release|Any CPU + {B06040BC-DA28-4923-8CAC-20EB517D471B}.Release|x86.ActiveCfg = Release|Any CPU + {B06040BC-DA28-4923-8CAC-20EB517D471B}.Release|x86.Build.0 = Release|Any CPU + {55CACC1F-FE96-47C8-8073-91F4CAA55C75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {55CACC1F-FE96-47C8-8073-91F4CAA55C75}.Debug|Any CPU.Build.0 = Debug|Any CPU + {55CACC1F-FE96-47C8-8073-91F4CAA55C75}.Debug|x64.ActiveCfg = Debug|Any CPU + {55CACC1F-FE96-47C8-8073-91F4CAA55C75}.Debug|x64.Build.0 = Debug|Any CPU + {55CACC1F-FE96-47C8-8073-91F4CAA55C75}.Debug|x86.ActiveCfg = Debug|Any CPU + {55CACC1F-FE96-47C8-8073-91F4CAA55C75}.Debug|x86.Build.0 = Debug|Any CPU + {55CACC1F-FE96-47C8-8073-91F4CAA55C75}.Release|Any CPU.ActiveCfg = Release|Any CPU + {55CACC1F-FE96-47C8-8073-91F4CAA55C75}.Release|Any CPU.Build.0 = Release|Any CPU + {55CACC1F-FE96-47C8-8073-91F4CAA55C75}.Release|x64.ActiveCfg = Release|Any CPU + {55CACC1F-FE96-47C8-8073-91F4CAA55C75}.Release|x64.Build.0 = Release|Any CPU + {55CACC1F-FE96-47C8-8073-91F4CAA55C75}.Release|x86.ActiveCfg = Release|Any CPU + {55CACC1F-FE96-47C8-8073-91F4CAA55C75}.Release|x86.Build.0 = Release|Any CPU + {7509AA1E-3093-4BEE-984F-E11579E98A11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7509AA1E-3093-4BEE-984F-E11579E98A11}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7509AA1E-3093-4BEE-984F-E11579E98A11}.Debug|x64.ActiveCfg = Debug|Any CPU + {7509AA1E-3093-4BEE-984F-E11579E98A11}.Debug|x64.Build.0 = Debug|Any CPU + {7509AA1E-3093-4BEE-984F-E11579E98A11}.Debug|x86.ActiveCfg = Debug|Any CPU + {7509AA1E-3093-4BEE-984F-E11579E98A11}.Debug|x86.Build.0 = Debug|Any CPU + {7509AA1E-3093-4BEE-984F-E11579E98A11}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7509AA1E-3093-4BEE-984F-E11579E98A11}.Release|Any CPU.Build.0 = Release|Any CPU + {7509AA1E-3093-4BEE-984F-E11579E98A11}.Release|x64.ActiveCfg = Release|Any CPU + {7509AA1E-3093-4BEE-984F-E11579E98A11}.Release|x64.Build.0 = Release|Any CPU + {7509AA1E-3093-4BEE-984F-E11579E98A11}.Release|x86.ActiveCfg = Release|Any CPU + {7509AA1E-3093-4BEE-984F-E11579E98A11}.Release|x86.Build.0 = Release|Any CPU + {DAAB6B35-CBD2-4573-B633-CDD42F583A0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DAAB6B35-CBD2-4573-B633-CDD42F583A0E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DAAB6B35-CBD2-4573-B633-CDD42F583A0E}.Debug|x64.ActiveCfg = Debug|Any CPU + {DAAB6B35-CBD2-4573-B633-CDD42F583A0E}.Debug|x64.Build.0 = Debug|Any CPU + {DAAB6B35-CBD2-4573-B633-CDD42F583A0E}.Debug|x86.ActiveCfg = Debug|Any CPU + {DAAB6B35-CBD2-4573-B633-CDD42F583A0E}.Debug|x86.Build.0 = Debug|Any CPU + {DAAB6B35-CBD2-4573-B633-CDD42F583A0E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DAAB6B35-CBD2-4573-B633-CDD42F583A0E}.Release|Any CPU.Build.0 = Release|Any CPU + {DAAB6B35-CBD2-4573-B633-CDD42F583A0E}.Release|x64.ActiveCfg = Release|Any CPU + {DAAB6B35-CBD2-4573-B633-CDD42F583A0E}.Release|x64.Build.0 = Release|Any CPU + {DAAB6B35-CBD2-4573-B633-CDD42F583A0E}.Release|x86.ActiveCfg = Release|Any CPU + {DAAB6B35-CBD2-4573-B633-CDD42F583A0E}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -7771,10 +7893,8 @@ Global {8550A02D-BA13-411A-AAD3-6124D33D669F} = {47EF1A9F-89DB-4EBA-9BC1-1D4E0E12DE44} {EDE77D0C-321A-49FD-95D7-56ED41242A93} = {47EF1A9F-89DB-4EBA-9BC1-1D4E0E12DE44} {8BDEC645-73BD-453B-8A5C-D616BC4EA08D} = {7B976D8F-EA31-4C0B-97BD-DFD9B3CC86FB} - {CBCD6AC2-72D3-4E82-9E78-12E3A9C68E1D} = {7B976D8F-EA31-4C0B-97BD-DFD9B3CC86FB} {EE9D0952-6060-4723-B329-94A2950A6762} = {4FDDC525-4E60-4CAF-83A3-261C5B43721F} {132D43A2-067A-4E24-A520-45B9F14DCB8E} = {EE9D0952-6060-4723-B329-94A2950A6762} - {FA8D7CA4-C33B-4409-865F-54192BAC59A4} = {7B976D8F-EA31-4C0B-97BD-DFD9B3CC86FB} {2EC4E939-513F-44CD-A956-498966EAC929} = {7B976D8F-EA31-4C0B-97BD-DFD9B3CC86FB} {987E1C29-F124-40C8-8E6F-1B2B6A4CB62A} = {4FDDC525-4E60-4CAF-83A3-261C5B43721F} {3CBC4802-E9B8-48B7-BC8C-B0AFB9EEC643} = {0ACCEDA7-339C-4B4D-8DD4-1AC271F31C04} @@ -7788,8 +7908,6 @@ Global {83371889-9A3E-4D16-AE77-EB4F83BC6374} = {FED4267E-E5E4-49C5-98DB-8B3F203596EE} {525EBCB4-A870-470B-BC90-845306C337D1} = {FED4267E-E5E4-49C5-98DB-8B3F203596EE} {175E5CD8-92D4-46BB-882E-3A930D3302D4} = {FED4267E-E5E4-49C5-98DB-8B3F203596EE} - {A5CE25E9-89E1-4F2C-9B89-0C161707E700} = {B6118E15-C37A-4B05-B4DF-97FE99790417} - {E6A23627-8D63-4DF1-A4F2-8881172C1FE6} = {B6118E15-C37A-4B05-B4DF-97FE99790417} {6126DCE4-9692-4EE2-B240-C65743572995} = {0508E463-0269-40C9-B5C2-3B600FB2A28B} {46FB7E93-1294-4068-B80A-D4864F78277A} = {6126DCE4-9692-4EE2-B240-C65743572995} {25FA84DB-EEA7-4068-8E2D-F3D48B281C16} = {6126DCE4-9692-4EE2-B240-C65743572995} @@ -7814,6 +7932,23 @@ Global {7F87406C-A3C8-4139-A68D-E4C344294A67} = {D62AF49B-F9FE-4794-AC39-A473FF13CA81} {1533E271-F61B-441B-8B74-59FB61DF0552} = {D62AF49B-F9FE-4794-AC39-A473FF13CA81} {7E268085-1046-4362-80CB-2977FF826DCA} = {D62AF49B-F9FE-4794-AC39-A473FF13CA81} + {A5CE25E9-89E1-4F2C-9B89-0C161707E700} = {B6118E15-C37A-4B05-B4DF-97FE99790417} + {E6A23627-8D63-4DF1-A4F2-8881172C1FE6} = {B6118E15-C37A-4B05-B4DF-97FE99790417} + {7D2B0799-A634-42AC-AE77-5D167BA51389} = {562D5067-8CD8-4F19-BCBB-873204932C61} + {9788C76F-658B-4441-88F8-22C6B86FAD27} = {7D2B0799-A634-42AC-AE77-5D167BA51389} + {1970D5CD-D9A4-4673-A297-179BB04199F4} = {7D2B0799-A634-42AC-AE77-5D167BA51389} + {A40350FE-4334-4007-B1C3-6BEB1B070309} = {7D2B0799-A634-42AC-AE77-5D167BA51389} + {C26965A9-EAC6-4E5A-B8C1-D161260EFE4F} = {7D2B0799-A634-42AC-AE77-5D167BA51389} + {FE5290C7-45DA-46F8-BD74-698E7A161DD6} = {7D2B0799-A634-42AC-AE77-5D167BA51389} + {ED66DC0E-FD6A-477A-BA8A-5273AA64F580} = {7D2B0799-A634-42AC-AE77-5D167BA51389} + {C1E7F837-6988-43E2-9E1C-7302DB484F99} = {017429CC-C5FB-48B4-9C46-034E29EE2F06} + {2A91479A-4ABE-4BB7-9A5E-CA3B9CCFC69E} = {C1E7F837-6988-43E2-9E1C-7302DB484F99} + {7CB09412-C9B0-47E8-A8C3-311AA4CFDE04} = {C1E7F837-6988-43E2-9E1C-7302DB484F99} + {22D7D74B-565D-4047-97B4-F149B1A13350} = {2A91479A-4ABE-4BB7-9A5E-CA3B9CCFC69E} + {B06040BC-DA28-4923-8CAC-20EB517D471B} = {22D7D74B-565D-4047-97B4-F149B1A13350} + {55CACC1F-FE96-47C8-8073-91F4CAA55C75} = {2A91479A-4ABE-4BB7-9A5E-CA3B9CCFC69E} + {7509AA1E-3093-4BEE-984F-E11579E98A11} = {7CB09412-C9B0-47E8-A8C3-311AA4CFDE04} + {DAAB6B35-CBD2-4573-B633-CDD42F583A0E} = {16898702-3E33-41C1-B8D8-4CE3F1D46BD9} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3E8720B3-DBDD-498C-B383-2CC32A054E8F} diff --git a/THIRD-PARTY-NOTICES.txt b/THIRD-PARTY-NOTICES.txt index 45f0a37b30..2a600a4d6d 100644 --- a/THIRD-PARTY-NOTICES.txt +++ b/THIRD-PARTY-NOTICES.txt @@ -267,4 +267,29 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. + +License notice for BedrockFramework +=================================== + +MIT License + +Copyright (c) 2019 David Fowler + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/eng/Dependencies.props b/eng/Dependencies.props index 35853a5024..68e1f6149c 100644 --- a/eng/Dependencies.props +++ b/eng/Dependencies.props @@ -64,6 +64,7 @@ and are generated based on the last package release. + @@ -107,6 +108,7 @@ and are generated based on the last package release. + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e98ae62047..db9cc55f62 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -13,305 +13,313 @@ https://github.com/dotnet/blazor cc449601d638ffaab58ae9487f0fd010bb178a12 - + https://github.com/dotnet/efcore - 5099d918192f5df031e1ff5e3beea9cb361c605a + 9638c0cda4bfb2eb8b70a047baefc982ffa7dade - + https://github.com/dotnet/efcore - 5099d918192f5df031e1ff5e3beea9cb361c605a + 9638c0cda4bfb2eb8b70a047baefc982ffa7dade - + https://github.com/dotnet/efcore - 5099d918192f5df031e1ff5e3beea9cb361c605a + 9638c0cda4bfb2eb8b70a047baefc982ffa7dade - + https://github.com/dotnet/efcore - 5099d918192f5df031e1ff5e3beea9cb361c605a + 9638c0cda4bfb2eb8b70a047baefc982ffa7dade - + https://github.com/dotnet/efcore - 5099d918192f5df031e1ff5e3beea9cb361c605a + 9638c0cda4bfb2eb8b70a047baefc982ffa7dade - + https://github.com/dotnet/efcore - 5099d918192f5df031e1ff5e3beea9cb361c605a + 9638c0cda4bfb2eb8b70a047baefc982ffa7dade - + https://github.com/dotnet/efcore - 5099d918192f5df031e1ff5e3beea9cb361c605a + 9638c0cda4bfb2eb8b70a047baefc982ffa7dade - - https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + + https://github.com/dotnet/efcore + 9638c0cda4bfb2eb8b70a047baefc982ffa7dade - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db + + + https://github.com/dotnet/runtime + f4e99f4afa445b519abcd7c5c87cbf54771614db + + + https://github.com/dotnet/runtime + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/runtime - 0862d48a9c9fbda879206b194a16d8e607deac42 + f4e99f4afa445b519abcd7c5c87cbf54771614db - + https://github.com/dotnet/arcade - ecec08a0eebbd92bb9538e351d475582551d9092 + 56a95cc477558c1ccdf16d7abe962849ea970ba4 - + https://github.com/dotnet/arcade - ecec08a0eebbd92bb9538e351d475582551d9092 + 56a95cc477558c1ccdf16d7abe962849ea970ba4 https://github.com/dotnet/roslyn diff --git a/eng/Versions.props b/eng/Versions.props index d5dfb4a496..9c2fd0000e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -64,82 +64,84 @@ 3.8.0-2.20407.3 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 - 5.0.0-rc.1.20416.7 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20416.7 + 5.0.0-rc.1.20425.1 3.2.0 - 5.0.0-rc.1.20417.2 - 5.0.0-rc.1.20417.2 - 5.0.0-rc.1.20417.2 - 5.0.0-rc.1.20417.2 - 5.0.0-rc.1.20417.2 - 5.0.0-rc.1.20417.2 - 5.0.0-rc.1.20417.2 + 5.0.0-rc.1.20425.4 + 5.0.0-rc.1.20425.4 + 5.0.0-rc.1.20425.4 + 5.0.0-rc.1.20425.4 + 5.0.0-rc.1.20425.4 + 5.0.0-rc.1.20425.4 + 5.0.0-rc.1.20425.4 + 5.0.0-rc.1.20425.4 false + + + true + true - - - - - + + + + - @@ -36,19 +45,5 @@ - - - <_RuntimeFramework Include="@(RuntimeFramework)" /> - - - - - - - - - - - diff --git a/src/Components/WebAssembly/JSInterop/src/InternalCalls.cs b/src/Components/WebAssembly/JSInterop/src/InternalCalls.cs index a28e45c410..6f9141ee7a 100644 --- a/src/Components/WebAssembly/JSInterop/src/InternalCalls.cs +++ b/src/Components/WebAssembly/JSInterop/src/InternalCalls.cs @@ -16,12 +16,7 @@ namespace WebAssembly.JSInterop // in driver.c in the Mono distribution /// See: https://github.com/mono/mono/blob/90574987940959fe386008a850982ea18236a533/sdks/wasm/src/driver.c#L318-L319 - // We're passing asyncHandle by ref not because we want it to be writable, but so it gets - // passed as a pointer (4 bytes). We can pass 4-byte values, but not 8-byte ones. [MethodImpl(MethodImplOptions.InternalCall)] - public static extern string InvokeJSMarshalled(out string exception, ref long asyncHandle, string functionIdentifier, string argsJson); - - [MethodImpl(MethodImplOptions.InternalCall)] - public static extern TRes InvokeJSUnmarshalled(out string exception, string functionIdentifier, [AllowNull] T0 arg0, [AllowNull] T1 arg1, [AllowNull] T2 arg2); + public static extern TRes InvokeJS(out string exception, ref JSCallInfo callInfo, [AllowNull] T0 arg0, [AllowNull] T1 arg1, [AllowNull] T2 arg2); } } diff --git a/src/Components/WebAssembly/JSInterop/src/JSCallInfo.cs b/src/Components/WebAssembly/JSInterop/src/JSCallInfo.cs new file mode 100644 index 0000000000..5053a35bfd --- /dev/null +++ b/src/Components/WebAssembly/JSInterop/src/JSCallInfo.cs @@ -0,0 +1,27 @@ +// 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.Runtime.InteropServices; +using Microsoft.JSInterop; + +namespace WebAssembly.JSInterop +{ + [StructLayout(LayoutKind.Explicit, Pack = 4)] + internal struct JSCallInfo + { + [FieldOffset(0)] + public string FunctionIdentifier; + + [FieldOffset(4)] + public JSCallResultType ResultType; + + [FieldOffset(8)] + public string MarshalledCallArgsJson; + + [FieldOffset(12)] + public long MarshalledCallAsyncHandle; + + [FieldOffset(20)] + public long TargetInstanceId; + } +} diff --git a/src/Components/WebAssembly/JSInterop/src/WebAssemblyJSRuntime.cs b/src/Components/WebAssembly/JSInterop/src/WebAssemblyJSRuntime.cs index 77cd0bac8d..14e1600b9f 100644 --- a/src/Components/WebAssembly/JSInterop/src/WebAssemblyJSRuntime.cs +++ b/src/Components/WebAssembly/JSInterop/src/WebAssemblyJSRuntime.cs @@ -11,22 +11,40 @@ namespace Microsoft.JSInterop.WebAssembly /// Provides methods for invoking JavaScript functions for applications running /// on the Mono WebAssembly runtime. /// - public abstract class WebAssemblyJSRuntime : JSInProcessRuntime + public abstract class WebAssemblyJSRuntime : JSInProcessRuntime, IJSUnmarshalledRuntime { /// - protected override string InvokeJS(string identifier, string argsJson) + protected override string InvokeJS(string identifier, string argsJson, JSCallResultType resultType, long targetInstanceId) { - var noAsyncHandle = default(long); - var result = InternalCalls.InvokeJSMarshalled(out var exception, ref noAsyncHandle, identifier, argsJson); + var callInfo = new JSCallInfo + { + FunctionIdentifier = identifier, + TargetInstanceId = targetInstanceId, + ResultType = resultType, + MarshalledCallArgsJson = argsJson ?? "[]", + MarshalledCallAsyncHandle = default + }; + + var result = InternalCalls.InvokeJS(out var exception, ref callInfo, null, null, null); + return exception != null ? throw new JSException(exception) : result; } /// - protected override void BeginInvokeJS(long asyncHandle, string identifier, string argsJson) + protected override void BeginInvokeJS(long asyncHandle, string identifier, string argsJson, JSCallResultType resultType, long targetInstanceId) { - InternalCalls.InvokeJSMarshalled(out _, ref asyncHandle, identifier, argsJson); + var callInfo = new JSCallInfo + { + FunctionIdentifier = identifier, + TargetInstanceId = targetInstanceId, + ResultType = resultType, + MarshalledCallArgsJson = argsJson ?? "[]", + MarshalledCallAsyncHandle = asyncHandle + }; + + InternalCalls.InvokeJS(out _, ref callInfo, null, null, null); } protected override void EndInvokeDotNet(DotNetInvocationInfo callInfo, in DotNetInvocationResult dispatchResult) @@ -39,57 +57,32 @@ namespace Microsoft.JSInterop.WebAssembly // We pass 0 as the async handle because we don't want the JS-side code to // send back any notification (we're just providing a result for an existing async call) var args = JsonSerializer.Serialize(new[] { callInfo.CallId, dispatchResult.Success, resultOrError }, JsonSerializerOptions); - BeginInvokeJS(0, "DotNet.jsCallDispatcher.endInvokeDotNetFromJS", args); + BeginInvokeJS(0, "DotNet.jsCallDispatcher.endInvokeDotNetFromJS", args, JSCallResultType.Default, 0); } - /// - /// Invokes the JavaScript function registered with the specified identifier. - /// - /// The .NET type corresponding to the function's return value type. - /// The identifier used when registering the target function. - /// The result of the function invocation. - public TResult InvokeUnmarshalled(string identifier) - => InvokeUnmarshalled(identifier, null, null, null); + /// + TResult IJSUnmarshalledRuntime.InvokeUnmarshalled(string identifier) + => ((IJSUnmarshalledRuntime)this).InvokeUnmarshalled(identifier, null, null, null); - /// - /// Invokes the JavaScript function registered with the specified identifier. - /// - /// The type of the first argument. - /// The .NET type corresponding to the function's return value type. - /// The identifier used when registering the target function. - /// The first argument. - /// The result of the function invocation. - public TResult InvokeUnmarshalled(string identifier, T0 arg0) - => InvokeUnmarshalled(identifier, arg0, null, null); + /// + TResult IJSUnmarshalledRuntime.InvokeUnmarshalled(string identifier, T0 arg0) + => ((IJSUnmarshalledRuntime)this).InvokeUnmarshalled(identifier, arg0, null, null); - /// - /// Invokes the JavaScript function registered with the specified identifier. - /// - /// The type of the first argument. - /// The type of the second argument. - /// The .NET type corresponding to the function's return value type. - /// The identifier used when registering the target function. - /// The first argument. - /// The second argument. - /// The result of the function invocation. - public TResult InvokeUnmarshalled(string identifier, T0 arg0, T1 arg1) - => InvokeUnmarshalled(identifier, arg0, arg1, null); + /// + TResult IJSUnmarshalledRuntime.InvokeUnmarshalled(string identifier, T0 arg0, T1 arg1) + => ((IJSUnmarshalledRuntime)this).InvokeUnmarshalled(identifier, arg0, arg1, null); - /// - /// Invokes the JavaScript function registered with the specified identifier. - /// - /// The type of the first argument. - /// The type of the second argument. - /// The type of the third argument. - /// The .NET type corresponding to the function's return value type. - /// The identifier used when registering the target function. - /// The first argument. - /// The second argument. - /// The third argument. - /// The result of the function invocation. - public TResult InvokeUnmarshalled(string identifier, T0 arg0, T1 arg1, T2 arg2) + /// + TResult IJSUnmarshalledRuntime.InvokeUnmarshalled(string identifier, T0 arg0, T1 arg1, T2 arg2) { - var result = InternalCalls.InvokeJSUnmarshalled(out var exception, identifier, arg0, arg1, arg2); + var callInfo = new JSCallInfo + { + FunctionIdentifier = identifier, + ResultType = ResultTypeFromGeneric() + }; + + var result = InternalCalls.InvokeJS(out var exception, ref callInfo, arg0, arg1, arg2); + return exception != null ? throw new JSException(exception) : result; diff --git a/src/Components/WebAssembly/Sdk/integrationtests/Microsoft.NET.Sdk.BlazorWebAssembly.IntegrationTests.csproj b/src/Components/WebAssembly/Sdk/integrationtests/Microsoft.NET.Sdk.BlazorWebAssembly.IntegrationTests.csproj index 27241a81b4..e8b9756812 100644 --- a/src/Components/WebAssembly/Sdk/integrationtests/Microsoft.NET.Sdk.BlazorWebAssembly.IntegrationTests.csproj +++ b/src/Components/WebAssembly/Sdk/integrationtests/Microsoft.NET.Sdk.BlazorWebAssembly.IntegrationTests.csproj @@ -36,6 +36,8 @@ + + diff --git a/src/Components/WebAssembly/Sdk/integrationtests/WasmBuildLazyLoadTest.cs b/src/Components/WebAssembly/Sdk/integrationtests/WasmBuildLazyLoadTest.cs index e3925465bb..88a7fb842d 100644 --- a/src/Components/WebAssembly/Sdk/integrationtests/WasmBuildLazyLoadTest.cs +++ b/src/Components/WebAssembly/Sdk/integrationtests/WasmBuildLazyLoadTest.cs @@ -4,6 +4,7 @@ using System.IO; using System.Text.Json; using System.Threading.Tasks; +using Microsoft.AspNetCore.Testing; using Microsoft.NET.Sdk.BlazorWebAssembly; using Xunit; @@ -88,6 +89,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests } [Fact] + [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23756")] public async Task Publish_LazyLoadExplicitAssembly_Debug_Works() { // Arrange diff --git a/src/Components/WebAssembly/Sdk/integrationtests/WasmCompressionTests.cs b/src/Components/WebAssembly/Sdk/integrationtests/WasmCompressionTests.cs index 410db705e7..d7dc25528e 100644 --- a/src/Components/WebAssembly/Sdk/integrationtests/WasmCompressionTests.cs +++ b/src/Components/WebAssembly/Sdk/integrationtests/WasmCompressionTests.cs @@ -113,6 +113,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests } [Fact] + [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23756")] public async Task Publish_WithoutLinkerAndCompression_IsIncremental() { // Arrange diff --git a/src/Components/WebAssembly/Sdk/integrationtests/WasmPublishIntegrationTest.cs b/src/Components/WebAssembly/Sdk/integrationtests/WasmPublishIntegrationTest.cs index 909a71c529..c4be79c220 100644 --- a/src/Components/WebAssembly/Sdk/integrationtests/WasmPublishIntegrationTest.cs +++ b/src/Components/WebAssembly/Sdk/integrationtests/WasmPublishIntegrationTest.cs @@ -41,6 +41,8 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests // Verify web.config Assert.FileExists(result, publishDirectory, "web.config"); + var webConfigContent = new StreamReader(GetType().Assembly.GetManifestResourceStream("Microsoft.NET.Sdk.BlazorWebAssembly.IntegrationTests.BlazorWasm.web.config")).ReadToEnd(); + Assert.FileContentEquals(result, Path.Combine(publishDirectory, "web.config"), webConfigContent); Assert.FileCountEquals(result, 1, publishDirectory, "*", SearchOption.TopDirectoryOnly); VerifyBootManifestHashes(result, blazorPublishDirectory); @@ -141,11 +143,10 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), serviceWorkerContent: "// This is the production service worker", assetsManifestPath: "custom-service-worker-assets.js"); - - VerifyTypeGranularTrimming(result, blazorPublishDirectory); } [Fact] + [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23756")] public async Task Publish_InRelease_Works() { // Arrange @@ -434,7 +435,8 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests Assert.Contains("System.Text.Json.dll", assemblies); // No pdbs - Assert.Null(bootJsonData.resources.pdb); + // Testing this requires an update to the SDK in this repo. Re-enabling tracked via https://github.com/dotnet/aspnetcore/issues/25135 + // Assert.Null(bootJsonData.resources.pdb); Assert.Null(bootJsonData.resources.satelliteResources); Assert.Contains("appsettings.json", bootJsonData.config); @@ -906,16 +908,17 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests private void VerifyTypeGranularTrimming(MSBuildResult result, string blazorPublishDirectory) { - var loggingAssemblyPath = Path.Combine(blazorPublishDirectory, "_framework", "Microsoft.Extensions.Logging.Abstractions.dll"); - Assert.FileExists(result, loggingAssemblyPath); + var componentsShimAssemblyPath = Path.Combine(blazorPublishDirectory, "_framework", "Microsoft.AspNetCore.Razor.Test.ComponentShim.dll"); + Assert.FileExists(result, componentsShimAssemblyPath); - // ILogger is referenced by the app, so we expect it to be preserved - Assert.AssemblyContainsType(result, loggingAssemblyPath, "Microsoft.Extensions.Logging.ILogger"); - // LogLevel is referenced by ILogger and therefore must be preserved. - Assert.AssemblyContainsType(result, loggingAssemblyPath, "Microsoft.Extensions.Logging.LogLevel"); + // RouteView is referenced by the app, so we expect it to be preserved + Assert.AssemblyContainsType(result, componentsShimAssemblyPath, "Microsoft.AspNetCore.Components.RouteView"); - // NullLogger is not referenced by the app, and should be trimmed. - Assert.AssemblyDoesNotContainType(result, loggingAssemblyPath, "Microsoft.Extensions.Logging.Abstractions.NullLogger"); + // RouteData is referenced by RouteView so we expect it to be preserved. + Assert.AssemblyContainsType(result, componentsShimAssemblyPath, "Microsoft.AspNetCore.Components.RouteData"); + + // CascadingParameterAttribute is not referenced by the app, and should be trimmed. + Assert.AssemblyDoesNotContainType(result, componentsShimAssemblyPath, "Microsoft.AspNetCore.Components.CascadingParameterAttribute"); } private static BootJsonData ReadBootJsonData(MSBuildResult result, string path) diff --git a/src/Components/WebAssembly/Sdk/src/BrotliCompress.cs b/src/Components/WebAssembly/Sdk/src/BrotliCompress.cs index 89b3004a5e..9518e81188 100644 --- a/src/Components/WebAssembly/Sdk/src/BrotliCompress.cs +++ b/src/Components/WebAssembly/Sdk/src/BrotliCompress.cs @@ -54,7 +54,18 @@ namespace Microsoft.NET.Sdk.BlazorWebAssembly } } - protected override string GenerateCommandLineCommands() => ToolAssembly; + private static string Quote(string path) + { + if (string.IsNullOrEmpty(path) || (path[0] == '\"' && path[path.Length - 1] == '\"')) + { + // it's already quoted + return path; + } + + return $"\"{path}\""; + } + + protected override string GenerateCommandLineCommands() => Quote(ToolAssembly); protected override string GenerateResponseFileCommands() { diff --git a/src/Components/WebAssembly/Sdk/src/targets/Microsoft.NET.Sdk.BlazorWebAssembly.Current.props b/src/Components/WebAssembly/Sdk/src/targets/Microsoft.NET.Sdk.BlazorWebAssembly.Current.props index a539c78f59..4ec923c2b1 100644 --- a/src/Components/WebAssembly/Sdk/src/targets/Microsoft.NET.Sdk.BlazorWebAssembly.Current.props +++ b/src/Components/WebAssembly/Sdk/src/targets/Microsoft.NET.Sdk.BlazorWebAssembly.Current.props @@ -22,6 +22,9 @@ Copyright (c) .NET Foundation. All rights reserved. false false + + + false 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 370d535eef..ceef7f00b1 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 @@ -53,6 +53,14 @@ Copyright (c) .NET Foundation. All rights reserved. true link + false + + + false + true + false + false + false / true @@ -69,6 +77,12 @@ Copyright (c) .NET Foundation. All rights reserved. + + + + + + @@ -395,7 +409,7 @@ Copyright (c) .NET Foundation. All rights reserved. <_BlazorTypeGranularAssembly Include="@(ManagedAssemblyToLink)" - Condition="'%(Extension)' == '.dll' AND ($([System.String]::Copy('%(Filename)').StartsWith('Microsoft.AspNetCore.')) or $([System.String]::Copy('%(Filename)').StartsWith('Microsoft.Extensions.')))"> + Condition="'%(Extension)' == '.dll' AND $([System.String]::Copy('%(Filename)').StartsWith('Microsoft.AspNetCore.'))"> false all @@ -451,7 +465,7 @@ Copyright (c) .NET Foundation. All rights reserved. Condition="'%(ResolvedFileToPublish.RelativePath)' != 'web.config' AND !$([System.String]::Copy('%(ResolvedFileToPublish.RelativePath)').Replace('\','/').StartsWith('wwwroot/'))" /> - + diff --git a/src/Components/WebAssembly/Sdk/testassets/blazorwasm/Program.cs b/src/Components/WebAssembly/Sdk/testassets/blazorwasm/Program.cs index 0784957aff..4b20dea9de 100644 --- a/src/Components/WebAssembly/Sdk/testassets/blazorwasm/Program.cs +++ b/src/Components/WebAssembly/Sdk/testassets/blazorwasm/Program.cs @@ -8,7 +8,6 @@ namespace standalone { GC.KeepAlive(typeof(System.Text.Json.JsonSerializer)); GC.KeepAlive(typeof(RazorClassLibrary.Class1)); - GC.KeepAlive(typeof(Microsoft.Extensions.Logging.ILogger)); #if REFERENCE_classlibrarywithsatelliteassemblies GC.KeepAlive(typeof(classlibrarywithsatelliteassemblies.Class1)); #endif diff --git a/src/Components/WebAssembly/WebAssembly/src/Hosting/RegisteredComponentsInterop.cs b/src/Components/WebAssembly/WebAssembly/src/Hosting/RegisteredComponentsInterop.cs new file mode 100644 index 0000000000..adb34bdb70 --- /dev/null +++ b/src/Components/WebAssembly/WebAssembly/src/Hosting/RegisteredComponentsInterop.cs @@ -0,0 +1,22 @@ +// 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. + +namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting +{ + internal class RegisteredComponentsInterop + { + private static readonly string Prefix = "Blazor._internal.registeredComponents."; + + public static readonly string GetRegisteredComponentsCount = Prefix + "getRegisteredComponentsCount"; + + public static readonly string GetId = Prefix + "getId"; + + public static readonly string GetAssembly = Prefix + "getAssembly"; + + public static readonly string GetTypeName = Prefix + "getTypeName"; + + public static readonly string GetParameterDefinitions = Prefix + "getParameterDefinitions"; + + public static readonly string GetParameterValues = Prefix + "getParameterValues"; + } +} diff --git a/src/Components/WebAssembly/WebAssembly/src/Hosting/RootComponentMapping.cs b/src/Components/WebAssembly/WebAssembly/src/Hosting/RootComponentMapping.cs index 22429279fd..bf21666dcd 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Hosting/RootComponentMapping.cs +++ b/src/Components/WebAssembly/WebAssembly/src/Hosting/RootComponentMapping.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.Collections; using Microsoft.AspNetCore.Components; namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting @@ -16,7 +17,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting /// and . /// /// The component type. Must implement . - /// The DOM element selector. + /// The DOM element selector or component registration id for the component. public RootComponentMapping(Type componentType, string selector) { if (componentType is null) @@ -38,6 +39,19 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting ComponentType = componentType; Selector = selector; + Parameters = ParameterView.Empty; + } + + /// + /// Creates a new instance of with the provided + /// and . + /// + /// The component type. Must implement . + /// The DOM element selector or registration id for the component. + /// The parameters to pass to the component. + public RootComponentMapping(Type componentType, string selector, ParameterView parameters) : this(componentType, selector) + { + Parameters = parameters; } /// @@ -49,5 +63,10 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting /// Gets the DOM element selector. /// public string Selector { get; } + + /// + /// Gets the parameters to pass to the root component. + /// + public ParameterView Parameters { get; } } } diff --git a/src/Components/WebAssembly/WebAssembly/src/Hosting/RootComponentMappingCollection.cs b/src/Components/WebAssembly/WebAssembly/src/Hosting/RootComponentMappingCollection.cs index ab4e1d8223..c4567a9ffa 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Hosting/RootComponentMappingCollection.cs +++ b/src/Components/WebAssembly/WebAssembly/src/Hosting/RootComponentMappingCollection.cs @@ -34,6 +34,17 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting /// The component type. Must implement . /// The DOM element selector. public void Add(Type componentType, string selector) + { + Add(componentType, selector, ParameterView.Empty); + } + + /// + /// Adds a component mapping to the collection. + /// + /// The component type. Must implement . + /// The DOM element selector. + /// The parameters to the root component. + public void Add(Type componentType, string selector, ParameterView parameters) { if (componentType is null) { @@ -45,7 +56,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting throw new ArgumentNullException(nameof(selector)); } - Add(new RootComponentMapping(componentType, selector)); + Add(new RootComponentMapping(componentType, selector, parameters)); } /// diff --git a/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHost.cs b/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHost.cs index c81dd2ac28..c26caaee99 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHost.cs +++ b/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHost.cs @@ -138,7 +138,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting for (var i = 0; i < rootComponents.Length; i++) { var rootComponent = rootComponents[i]; - await _renderer.AddComponentAsync(rootComponent.ComponentType, rootComponent.Selector); + await _renderer.AddComponentAsync(rootComponent.ComponentType, rootComponent.Selector, rootComponent.Parameters); } await tcs.Task; diff --git a/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs b/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs index a65e4117cd..9e6215c70a 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs +++ b/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs @@ -21,6 +21,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting public sealed class WebAssemblyHostBuilder { private Func _createServiceProvider; + private RootComponentTypeCache _rootComponentCache; /// /// Creates an instance of using the most common @@ -57,6 +58,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting // Retrieve required attributes from JSRuntimeInvoker InitializeNavigationManager(jsRuntimeInvoker); + InitializeRegisteredRootComponents(jsRuntimeInvoker); InitializeDefaultServices(); var hostEnvironment = InitializeEnvironment(jsRuntimeInvoker); @@ -68,6 +70,38 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting }; } + private void InitializeRegisteredRootComponents(WebAssemblyJSRuntimeInvoker jsRuntimeInvoker) + { + var componentsCount = jsRuntimeInvoker.InvokeUnmarshalled(RegisteredComponentsInterop.GetRegisteredComponentsCount, null, null, null); + if (componentsCount == 0) + { + return; + } + + var registeredComponents = new WebAssemblyComponentMarker[componentsCount]; + for (var i = 0; i < componentsCount; i++) + { + var id = jsRuntimeInvoker.InvokeUnmarshalled(RegisteredComponentsInterop.GetId, i, null, null); + var assembly = jsRuntimeInvoker.InvokeUnmarshalled(RegisteredComponentsInterop.GetAssembly, id, null, null); + 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()); + } + + var componentDeserializer = WebAssemblyComponentParameterDeserializer.Instance; + foreach (var registeredComponent in registeredComponents) + { + _rootComponentCache = new RootComponentTypeCache(); + var componentType = _rootComponentCache.GetRootComponent(registeredComponent.Assembly, registeredComponent.TypeName); + var definitions = componentDeserializer.GetParameterDefinitions(registeredComponent.ParameterDefinitions); + var values = componentDeserializer.GetParameterValues(registeredComponent.ParameterValues); + var parameters = componentDeserializer.DeserializeParameters(definitions, values); + + RootComponents.Add(componentType, registeredComponent.PrerenderId, parameters); + } + } + private void InitializeNavigationManager(WebAssemblyJSRuntimeInvoker jsRuntimeInvoker) { var baseUri = jsRuntimeInvoker.InvokeUnmarshalled(BrowserNavigationManagerInterop.GetBaseUri, null, null, null); @@ -190,7 +224,8 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting Services.AddSingleton(WebAssemblyNavigationManager.Instance); Services.AddSingleton(WebAssemblyNavigationInterception.Instance); Services.AddSingleton(new LazyAssemblyLoader(DefaultWebAssemblyJSRuntime.Instance)); - Services.AddLogging(builder => { + Services.AddLogging(builder => + { builder.AddProvider(new WebAssemblyConsoleLoggerProvider(DefaultWebAssemblyJSRuntime.Instance)); }); } diff --git a/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.csproj b/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.csproj index 4dde2eaae6..906e03fe82 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.csproj +++ b/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.csproj @@ -1,4 +1,4 @@ - + $(DefaultNetCoreTargetFramework) @@ -15,13 +15,7 @@ - + @@ -31,6 +25,11 @@ + + + + + diff --git a/src/Components/WebAssembly/WebAssembly/src/Prerendering/ClientComponentParameterDeserializer.cs b/src/Components/WebAssembly/WebAssembly/src/Prerendering/ClientComponentParameterDeserializer.cs new file mode 100644 index 0000000000..855c79e101 --- /dev/null +++ b/src/Components/WebAssembly/WebAssembly/src/Prerendering/ClientComponentParameterDeserializer.cs @@ -0,0 +1,88 @@ +// 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.Text; +using System.Text.Json; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; + +namespace Microsoft.AspNetCore.Components +{ + internal class WebAssemblyComponentParameterDeserializer + { + private readonly ComponentParametersTypeCache _parametersCache; + + public WebAssemblyComponentParameterDeserializer( + ComponentParametersTypeCache parametersCache) + { + _parametersCache = parametersCache; + } + + public static WebAssemblyComponentParameterDeserializer Instance { get; } = new WebAssemblyComponentParameterDeserializer(new ComponentParametersTypeCache()); + + public ParameterView DeserializeParameters(IList parametersDefinitions, IList parameterValues) + { + var parametersDictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); + + if (parameterValues.Count != parametersDefinitions.Count) + { + // Mismatched number of definition/parameter values. + throw new InvalidOperationException($"The number of parameter definitions '{parametersDefinitions.Count}' does not match the number parameter values '{parameterValues.Count}'."); + } + + for (var i = 0; i < parametersDefinitions.Count; i++) + { + var definition = parametersDefinitions[i]; + if (definition.Name == null) + { + throw new InvalidOperationException("The name is missing in a parameter definition."); + } + + if (definition.TypeName == null && definition.Assembly == null) + { + parametersDictionary[definition.Name] = null; + } + else if (definition.TypeName == null || definition.Assembly == null) + { + throw new InvalidOperationException($"The parameter definition for '{definition.Name}' is incomplete: Type='{definition.TypeName}' Assembly='{definition.Assembly}'."); + } + else + { + var parameterType = _parametersCache.GetParameterType(definition.Assembly, definition.TypeName); + if (parameterType == null) + { + throw new InvalidOperationException($"The parameter '{definition.Name} with type '{definition.TypeName}' in assembly '{definition.Assembly}' could not be found."); + } + try + { + var value = (JsonElement)parameterValues[i]; + var parameterValue = JsonSerializer.Deserialize( + value.GetRawText(), + parameterType, + WebAssemblyComponentSerializationSettings.JsonSerializationOptions); + + parametersDictionary[definition.Name] = parameterValue; + } + catch (Exception e) + { + throw new InvalidOperationException("Could not parse the parameter value for parameter '{definition.Name}' of type '{definition.TypeName}' and assembly '{definition.Assembly}'.", e); + } + } + } + + return ParameterView.FromDictionary(parametersDictionary); + } + + public ComponentParameter[] GetParameterDefinitions(string parametersDefinitions) + { + return JsonSerializer.Deserialize(parametersDefinitions, WebAssemblyComponentSerializationSettings.JsonSerializationOptions); + } + + public IList GetParameterValues(string parameterValues) + { + return JsonSerializer.Deserialize>(parameterValues, WebAssemblyComponentSerializationSettings.JsonSerializationOptions); + } + } +} diff --git a/src/Components/WebAssembly/WebAssembly/src/Rendering/WebAssemblyRenderer.cs b/src/Components/WebAssembly/WebAssembly/src/Rendering/WebAssemblyRenderer.cs index cfef7ed0d7..ca033e1107 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Rendering/WebAssemblyRenderer.cs +++ b/src/Components/WebAssembly/WebAssembly/src/Rendering/WebAssemblyRenderer.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Components.RenderTree; using Microsoft.AspNetCore.Components.WebAssembly.Services; using Microsoft.Extensions.Logging; +using Microsoft.JSInterop; using Microsoft.JSInterop.WebAssembly; namespace Microsoft.AspNetCore.Components.WebAssembly.Rendering @@ -46,13 +47,14 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Rendering /// /// The type of the component. /// A CSS selector that uniquely identifies a DOM element. + /// The parameters for the component. /// A that represents the asynchronous rendering of the added component. /// /// Callers of this method may choose to ignore the returned if they do not /// want to await the rendering of the added component. /// - public Task AddComponentAsync(string domElementSelector) where TComponent : IComponent - => AddComponentAsync(typeof(TComponent), domElementSelector); + public Task AddComponentAsync(string domElementSelector, ParameterView parameters) where TComponent : IComponent + => AddComponentAsync(typeof(TComponent), domElementSelector, parameters); /// /// Associates the with the , @@ -60,12 +62,13 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Rendering /// /// The type of the component. /// A CSS selector that uniquely identifies a DOM element. + /// The list of root component parameters. /// A that represents the asynchronous rendering of the added component. /// /// Callers of this method may choose to ignore the returned if they do not /// want to await the rendering of the added component. /// - public Task AddComponentAsync(Type componentType, string domElementSelector) + public Task AddComponentAsync(Type componentType, string domElementSelector, ParameterView parameters) { var component = InstantiateComponent(componentType); var componentId = AssignRootComponentId(component); @@ -82,7 +85,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Rendering componentId, _webAssemblyRendererId); - return RenderRootComponentAsync(componentId); + return RenderRootComponentAsync(componentId, parameters); } /// @@ -95,7 +98,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Rendering /// protected override Task UpdateDisplayAsync(in RenderBatch batch) { - DefaultWebAssemblyJSRuntime.Instance.InvokeUnmarshalled( + ((IJSUnmarshalledRuntime)DefaultWebAssemblyJSRuntime.Instance).InvokeUnmarshalled( "Blazor._internal.renderBatch", _webAssemblyRendererId, batch); diff --git a/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs b/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs index 709c0f576c..9fc3cde388 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs +++ b/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs @@ -80,7 +80,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Services var newAssembliesToLoad = assembliesToLoad.Where(assembly => !_loadedAssemblyCache.Contains(assembly)); var loadedAssemblies = new List(); - var count = (int)await ((WebAssemblyJSRuntime)_jsRuntime).InvokeUnmarshalled>( + var count = (int)await ((IJSUnmarshalledRuntime)_jsRuntime).InvokeUnmarshalled>( GetDynamicAssemblies, newAssembliesToLoad.ToArray(), null, @@ -91,7 +91,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Services return loadedAssemblies; } - var assemblies = ((WebAssemblyJSRuntime)_jsRuntime).InvokeUnmarshalled( + var assemblies = ((IJSUnmarshalledRuntime)_jsRuntime).InvokeUnmarshalled( ReadDynamicAssemblies, null, null, diff --git a/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyConsoleLogger.cs b/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyConsoleLogger.cs index d8fb668579..398453fa99 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyConsoleLogger.cs +++ b/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyConsoleLogger.cs @@ -99,7 +99,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Services _jsRuntime.InvokeVoid("console.error", formattedMessage); break; case LogLevel.Critical: - _jsRuntime.InvokeUnmarshalled("Blazor._internal.dotNetCriticalError", formattedMessage); + ((IJSUnmarshalledRuntime)_jsRuntime).InvokeUnmarshalled("Blazor._internal.dotNetCriticalError", formattedMessage); break; default: // LogLevel.None or invalid enum values Console.WriteLine(formattedMessage); diff --git a/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyJSRuntimeInvoker.cs b/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyJSRuntimeInvoker.cs index 4592c2ce9c..b2960de3ca 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyJSRuntimeInvoker.cs +++ b/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyJSRuntimeInvoker.cs @@ -1,13 +1,13 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.JSInterop.WebAssembly; +using Microsoft.JSInterop; namespace Microsoft.AspNetCore.Components.WebAssembly.Services { /// /// This class exists to enable unit testing for code that needs to call - /// . + /// . /// /// We should only use this in non-perf-critical code paths (for example, during hosting startup, /// where we only call this a fixed number of times, and not during rendering where it might be @@ -22,6 +22,6 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Services public static WebAssemblyJSRuntimeInvoker Instance = new WebAssemblyJSRuntimeInvoker(); public virtual TResult InvokeUnmarshalled(string identifier, T0 arg0, T1 arg1, T2 arg2) - => DefaultWebAssemblyJSRuntime.Instance.InvokeUnmarshalled(identifier, arg0, arg1, arg2); + => ((IJSUnmarshalledRuntime)DefaultWebAssemblyJSRuntime.Instance).InvokeUnmarshalled(identifier, arg0, arg1, arg2); } } diff --git a/src/Components/WebAssembly/WebAssembly/test/TestWebAssemblyJSRuntimeInvoker.cs b/src/Components/WebAssembly/WebAssembly/test/TestWebAssemblyJSRuntimeInvoker.cs index e1b5f9f616..54c198ffcd 100644 --- a/src/Components/WebAssembly/WebAssembly/test/TestWebAssemblyJSRuntimeInvoker.cs +++ b/src/Components/WebAssembly/WebAssembly/test/TestWebAssemblyJSRuntimeInvoker.cs @@ -29,6 +29,8 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting case "Blazor._internal.navigationManager.getUnmarshalledLocationHref": var testHref = "https://www.example.com/awesome-part-that-will-be-truncated-in-tests/cool"; return (TResult)(object)testHref; + case "Blazor._internal.registeredComponents.getRegisteredComponentsCount": + return (TResult)(object)0; default: throw new NotImplementedException($"{nameof(TestWebAssemblyJSRuntimeInvoker)} has no implementation for '{identifier}'."); } diff --git a/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Data/Migrations/20200818132003_IdentityServer4.Designer.cs b/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Data/Migrations/20200818132003_IdentityServer4.Designer.cs new file mode 100644 index 0000000000..3ef8ebfb22 --- /dev/null +++ b/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Data/Migrations/20200818132003_IdentityServer4.Designer.cs @@ -0,0 +1,405 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Wasm.Authentication.Server.Data; + +namespace Wasm.Authentication.Server.Data.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20200818132003_IdentityServer4")] + partial class IdentityServer4 + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.0-rc.1.20416.1"); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.DeviceFlowCodes", b => + { + b.Property("UserCode") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("ClientId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("CreationTime") + .HasColumnType("TEXT"); + + b.Property("Data") + .IsRequired() + .HasMaxLength(50000) + .HasColumnType("TEXT"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("DeviceCode") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Expiration") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("SubjectId") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.HasKey("UserCode"); + + b.HasIndex("DeviceCode") + .IsUnique(); + + b.HasIndex("Expiration"); + + b.ToTable("DeviceCodes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.PersistedGrant", b => + { + b.Property("Key") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("ClientId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("ConsumedTime") + .HasColumnType("TEXT"); + + b.Property("CreationTime") + .HasColumnType("TEXT"); + + b.Property("Data") + .IsRequired() + .HasMaxLength(50000) + .HasColumnType("TEXT"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Expiration") + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("SubjectId") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Key"); + + b.HasIndex("Expiration"); + + b.HasIndex("SubjectId", "ClientId", "Type"); + + b.HasIndex("SubjectId", "SessionId", "Type"); + + b.ToTable("PersistedGrants"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Wasm.Authentication.Server.Models.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Wasm.Authentication.Server.Models.UserPreference", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("ApplicationUserId") + .HasColumnType("TEXT"); + + b.Property("Color") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationUserId") + .IsUnique(); + + b.ToTable("UserPreferences"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Wasm.Authentication.Server.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Wasm.Authentication.Server.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Wasm.Authentication.Server.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Wasm.Authentication.Server.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Wasm.Authentication.Server.Models.UserPreference", b => + { + b.HasOne("Wasm.Authentication.Server.Models.ApplicationUser", null) + .WithOne("UserPreference") + .HasForeignKey("Wasm.Authentication.Server.Models.UserPreference", "ApplicationUserId"); + }); + + modelBuilder.Entity("Wasm.Authentication.Server.Models.ApplicationUser", b => + { + b.Navigation("UserPreference"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Data/Migrations/20200818132003_IdentityServer4.cs b/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Data/Migrations/20200818132003_IdentityServer4.cs new file mode 100644 index 0000000000..59133a5862 --- /dev/null +++ b/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Data/Migrations/20200818132003_IdentityServer4.cs @@ -0,0 +1,77 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Wasm.Authentication.Server.Data.Migrations +{ + public partial class IdentityServer4 : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ConsumedTime", + table: "PersistedGrants", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "Description", + table: "PersistedGrants", + type: "TEXT", + maxLength: 200, + nullable: true); + + migrationBuilder.AddColumn( + name: "SessionId", + table: "PersistedGrants", + type: "TEXT", + maxLength: 100, + nullable: true); + + migrationBuilder.AddColumn( + name: "Description", + table: "DeviceCodes", + type: "TEXT", + maxLength: 200, + nullable: true); + + migrationBuilder.AddColumn( + name: "SessionId", + table: "DeviceCodes", + type: "TEXT", + maxLength: 100, + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_PersistedGrants_SubjectId_SessionId_Type", + table: "PersistedGrants", + columns: new[] { "SubjectId", "SessionId", "Type" }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_PersistedGrants_SubjectId_SessionId_Type", + table: "PersistedGrants"); + + migrationBuilder.DropColumn( + name: "ConsumedTime", + table: "PersistedGrants"); + + migrationBuilder.DropColumn( + name: "Description", + table: "PersistedGrants"); + + migrationBuilder.DropColumn( + name: "SessionId", + table: "PersistedGrants"); + + migrationBuilder.DropColumn( + name: "Description", + table: "DeviceCodes"); + + migrationBuilder.DropColumn( + name: "SessionId", + table: "DeviceCodes"); + } + } +} diff --git a/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Data/Migrations/ApplicationDbContextModelSnapshot.cs b/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Data/Migrations/ApplicationDbContextModelSnapshot.cs index 312d93c9a5..c68c2e0966 100644 --- a/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Data/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Data/Migrations/ApplicationDbContextModelSnapshot.cs @@ -14,39 +14,47 @@ namespace Wasm.Authentication.Server.Data.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "3.1.2"); + .HasAnnotation("ProductVersion", "5.0.0-rc.1.20416.1"); modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.DeviceFlowCodes", b => { b.Property("UserCode") - .HasColumnType("TEXT") - .HasMaxLength(200); + .HasMaxLength(200) + .HasColumnType("TEXT"); b.Property("ClientId") .IsRequired() - .HasColumnType("TEXT") - .HasMaxLength(200); + .HasMaxLength(200) + .HasColumnType("TEXT"); b.Property("CreationTime") .HasColumnType("TEXT"); b.Property("Data") .IsRequired() - .HasColumnType("TEXT") - .HasMaxLength(50000); + .HasMaxLength(50000) + .HasColumnType("TEXT"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("TEXT"); b.Property("DeviceCode") .IsRequired() - .HasColumnType("TEXT") - .HasMaxLength(200); + .HasMaxLength(200) + .HasColumnType("TEXT"); b.Property("Expiration") .IsRequired() .HasColumnType("TEXT"); + b.Property("SessionId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + b.Property("SubjectId") - .HasColumnType("TEXT") - .HasMaxLength(200); + .HasMaxLength(200) + .HasColumnType("TEXT"); b.HasKey("UserCode"); @@ -61,33 +69,44 @@ namespace Wasm.Authentication.Server.Data.Migrations modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.PersistedGrant", b => { b.Property("Key") - .HasColumnType("TEXT") - .HasMaxLength(200); + .HasMaxLength(200) + .HasColumnType("TEXT"); b.Property("ClientId") .IsRequired() - .HasColumnType("TEXT") - .HasMaxLength(200); + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("ConsumedTime") + .HasColumnType("TEXT"); b.Property("CreationTime") .HasColumnType("TEXT"); b.Property("Data") .IsRequired() - .HasColumnType("TEXT") - .HasMaxLength(50000); + .HasMaxLength(50000) + .HasColumnType("TEXT"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("TEXT"); b.Property("Expiration") .HasColumnType("TEXT"); + b.Property("SessionId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + b.Property("SubjectId") - .HasColumnType("TEXT") - .HasMaxLength(200); + .HasMaxLength(200) + .HasColumnType("TEXT"); b.Property("Type") .IsRequired() - .HasColumnType("TEXT") - .HasMaxLength(50); + .HasMaxLength(50) + .HasColumnType("TEXT"); b.HasKey("Key"); @@ -95,6 +114,8 @@ namespace Wasm.Authentication.Server.Data.Migrations b.HasIndex("SubjectId", "ClientId", "Type"); + b.HasIndex("SubjectId", "SessionId", "Type"); + b.ToTable("PersistedGrants"); }); @@ -108,18 +129,18 @@ namespace Wasm.Authentication.Server.Data.Migrations .HasColumnType("TEXT"); b.Property("Name") - .HasColumnType("TEXT") - .HasMaxLength(256); + .HasMaxLength(256) + .HasColumnType("TEXT"); b.Property("NormalizedName") - .HasColumnType("TEXT") - .HasMaxLength(256); + .HasMaxLength(256) + .HasColumnType("TEXT"); b.HasKey("Id"); b.HasIndex("NormalizedName") .IsUnique() - .HasName("RoleNameIndex"); + .HasDatabaseName("RoleNameIndex"); b.ToTable("AspNetRoles"); }); @@ -173,12 +194,12 @@ namespace Wasm.Authentication.Server.Data.Migrations modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { b.Property("LoginProvider") - .HasColumnType("TEXT") - .HasMaxLength(128); + .HasMaxLength(128) + .HasColumnType("TEXT"); b.Property("ProviderKey") - .HasColumnType("TEXT") - .HasMaxLength(128); + .HasMaxLength(128) + .HasColumnType("TEXT"); b.Property("ProviderDisplayName") .HasColumnType("TEXT"); @@ -215,12 +236,12 @@ namespace Wasm.Authentication.Server.Data.Migrations .HasColumnType("TEXT"); b.Property("LoginProvider") - .HasColumnType("TEXT") - .HasMaxLength(128); + .HasMaxLength(128) + .HasColumnType("TEXT"); b.Property("Name") - .HasColumnType("TEXT") - .HasMaxLength(128); + .HasMaxLength(128) + .HasColumnType("TEXT"); b.Property("Value") .HasColumnType("TEXT"); @@ -243,8 +264,8 @@ namespace Wasm.Authentication.Server.Data.Migrations .HasColumnType("TEXT"); b.Property("Email") - .HasColumnType("TEXT") - .HasMaxLength(256); + .HasMaxLength(256) + .HasColumnType("TEXT"); b.Property("EmailConfirmed") .HasColumnType("INTEGER"); @@ -256,12 +277,12 @@ namespace Wasm.Authentication.Server.Data.Migrations .HasColumnType("TEXT"); b.Property("NormalizedEmail") - .HasColumnType("TEXT") - .HasMaxLength(256); + .HasMaxLength(256) + .HasColumnType("TEXT"); b.Property("NormalizedUserName") - .HasColumnType("TEXT") - .HasMaxLength(256); + .HasMaxLength(256) + .HasColumnType("TEXT"); b.Property("PasswordHash") .HasColumnType("TEXT"); @@ -279,17 +300,17 @@ namespace Wasm.Authentication.Server.Data.Migrations .HasColumnType("INTEGER"); b.Property("UserName") - .HasColumnType("TEXT") - .HasMaxLength(256); + .HasMaxLength(256) + .HasColumnType("TEXT"); b.HasKey("Id"); b.HasIndex("NormalizedEmail") - .HasName("EmailIndex"); + .HasDatabaseName("EmailIndex"); b.HasIndex("NormalizedUserName") .IsUnique() - .HasName("UserNameIndex"); + .HasDatabaseName("UserNameIndex"); b.ToTable("AspNetUsers"); }); @@ -371,6 +392,11 @@ namespace Wasm.Authentication.Server.Data.Migrations .WithOne("UserPreference") .HasForeignKey("Wasm.Authentication.Server.Models.UserPreference", "ApplicationUserId"); }); + + modelBuilder.Entity("Wasm.Authentication.Server.Models.ApplicationUser", b => + { + b.Navigation("UserPreference"); + }); #pragma warning restore 612, 618 } } diff --git a/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Startup.cs b/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Startup.cs index 1224ee978f..038e01f0c7 100644 --- a/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Startup.cs +++ b/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Startup.cs @@ -3,6 +3,7 @@ using System.Linq; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; @@ -57,6 +58,11 @@ namespace Wasm.Authentication.Server app.UseWebAssemblyDebugging(); } + app.UseCookiePolicy(new CookiePolicyOptions + { + MinimumSameSitePolicy = SameSiteMode.Lax + }); + app.UseBlazorFrameworkFiles(); app.UseStaticFiles(); diff --git a/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Wasm.Authentication.Server.csproj b/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Wasm.Authentication.Server.csproj index 8f0b709198..8daf509266 100644 --- a/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Wasm.Authentication.Server.csproj +++ b/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Wasm.Authentication.Server.csproj @@ -10,10 +10,13 @@ + + + diff --git a/src/Components/benchmarkapps/Wasm.Performance/Directory.Build.props b/src/Components/benchmarkapps/Wasm.Performance/Directory.Build.props new file mode 100644 index 0000000000..0556b5271e --- /dev/null +++ b/src/Components/benchmarkapps/Wasm.Performance/Directory.Build.props @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/Components/benchmarkapps/Wasm.Performance/Driver/Program.cs b/src/Components/benchmarkapps/Wasm.Performance/Driver/Program.cs index c3c3ae618f..c72ab9dcca 100644 --- a/src/Components/benchmarkapps/Wasm.Performance/Driver/Program.cs +++ b/src/Components/benchmarkapps/Wasm.Performance/Driver/Program.cs @@ -16,6 +16,7 @@ using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Hosting.Server.Features; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using OpenQA.Selenium; using DevHostServerProgram = Microsoft.AspNetCore.Components.WebAssembly.DevServer.Server.Program; namespace Wasm.Performance.Driver @@ -81,7 +82,20 @@ namespace Wasm.Performance.Driver { BenchmarkResultTask = new TaskCompletionSource(); using var runCancellationToken = new CancellationTokenSource(timeForEachRun); - using var registration = runCancellationToken.Token.Register(() => BenchmarkResultTask.TrySetException(new TimeoutException($"Timed out after {timeForEachRun}"))); + using var registration = runCancellationToken.Token.Register(() => + { + string exceptionMessage = $"Timed out after {timeForEachRun}."; + try + { + var innerHtml = browser.FindElement(By.CssSelector(":first-child")).GetAttribute("innerHTML"); + exceptionMessage += Environment.NewLine + "Browser state: " + Environment.NewLine + innerHtml; + } + catch + { + // Do nothing; + } + BenchmarkResultTask.TrySetException(new TimeoutException(exceptionMessage)); + }); var results = await BenchmarkResultTask.Task; @@ -89,6 +103,11 @@ namespace Wasm.Performance.Driver includeMetadata: firstRun, isStressRun: isStressRun); + if (!isStressRun) + { + PrettyPrint(results); + } + firstRun = false; } while (isStressRun && !stressRunCancellation.IsCancellationRequested); @@ -230,6 +249,17 @@ namespace Wasm.Performance.Driver Console.WriteLine(builder); } + static void PrettyPrint(BenchmarkResult benchmarkResult) + { + Console.WriteLine(); + Console.WriteLine("| Name | Description | Duration | NumExecutions | "); + Console.WriteLine("--------------------------"); + foreach (var result in benchmarkResult.ScenarioResults) + { + Console.WriteLine($"| {result.Descriptor.Name} | {result.Name} | {result.Duration} | {result.NumExecutions} |"); + } + } + static IHost StartTestApp() { var args = new[] diff --git a/src/Components/benchmarkapps/Wasm.Performance/Driver/Selenium.cs b/src/Components/benchmarkapps/Wasm.Performance/Driver/Selenium.cs index f9d7ef47ef..9748549099 100644 --- a/src/Components/benchmarkapps/Wasm.Performance/Driver/Selenium.cs +++ b/src/Components/benchmarkapps/Wasm.Performance/Driver/Selenium.cs @@ -16,12 +16,7 @@ namespace Wasm.Performance.Driver const int SeleniumPort = 4444; static bool RunHeadlessBrowser = true; - static bool PoolForBrowserLogs = -#if DEBUG - true; -#else - false; -#endif + static bool PoolForBrowserLogs = true; private static async ValueTask WaitForServerAsync(int port, CancellationToken cancellationToken) { diff --git a/src/Components/benchmarkapps/Wasm.Performance/Driver/Wasm.Performance.Driver.csproj b/src/Components/benchmarkapps/Wasm.Performance/Driver/Wasm.Performance.Driver.csproj index 66aea279ee..346ddc48f1 100644 --- a/src/Components/benchmarkapps/Wasm.Performance/Driver/Wasm.Performance.Driver.csproj +++ b/src/Components/benchmarkapps/Wasm.Performance/Driver/Wasm.Performance.Driver.csproj @@ -12,13 +12,18 @@ + + - + + + + $(DefaultNetCoreTargetFramework) true + + false diff --git a/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj b/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj index 256ea831e1..a2fe529a19 100644 --- a/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj +++ b/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj @@ -41,7 +41,6 @@ - @@ -56,6 +55,8 @@ + + diff --git a/src/Components/test/E2ETest/Tests/ClientRenderingMultpleComponentsTest.cs b/src/Components/test/E2ETest/Tests/ClientRenderingMultpleComponentsTest.cs new file mode 100644 index 0000000000..7e4df2898e --- /dev/null +++ b/src/Components/test/E2ETest/Tests/ClientRenderingMultpleComponentsTest.cs @@ -0,0 +1,95 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Linq; +using System.Text.Json; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components.E2ETest.Infrastructure; +using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures; +using Microsoft.AspNetCore.E2ETesting; +using OpenQA.Selenium; +using TestServer; +using Xunit; +using Xunit.Abstractions; + +namespace Microsoft.AspNetCore.Components.E2ETests.Tests +{ + public class ClientRenderingMultpleComponentsTest : ServerTestBase> + { + private const string MarkerPattern = ".*?.*?"; + + public ClientRenderingMultpleComponentsTest( + BrowserFixture browserFixture, + BasicTestAppServerSiteFixture serverFixture, + ITestOutputHelper output) + : base(browserFixture, serverFixture, output) + { + } + + public DateTime LastLogTimeStamp { get; set; } = DateTime.MinValue; + + public override async Task InitializeAsync() + { + await base.InitializeAsync(); + + // Capture the last log timestamp so that we can filter logs when we + // check for duplicate connections. + var lastLog = Browser.Manage().Logs.GetLog(LogType.Browser).LastOrDefault(); + if (lastLog != null) + { + LastLogTimeStamp = lastLog.Timestamp; + } + } + + [Fact] + public void CanRenderMultipleRootComponents() + { + Navigate("/Client/multiple-components"); + + var greets = Browser.FindElements(By.CssSelector(".greet-wrapper .greet")).Select(e => e.Text).ToArray(); + + Assert.Equal(7, greets.Length); // 1 statically rendered + 5 prerendered + 1 server prerendered + Assert.DoesNotContain("Hello Red fish", greets); + Assert.Single(greets, "Hello John"); + Assert.Single(greets, "Hello Abraham"); + Assert.Equal(2, greets.Where(g => g == "Hello Blue fish").Count()); + Assert.Equal(3, greets.Where(g => string.Equals("Hello", g)).Count()); // 3 server prerendered without parameters + var content = Browser.FindElement(By.Id("test-container")).GetAttribute("innerHTML"); + var markers = ReadMarkers(content); + var componentSequence = markers.Select(m => m.Item1.PrerenderId != null).ToArray(); + Assert.Equal(13, componentSequence.Length); + + // Once the app starts, output changes + BeginInteractivity(); + + Browser.Exists(By.CssSelector("h3.interactive")); + var updatedGreets = Browser.FindElements(By.CssSelector(".greet-wrapper .greet")).Select(e => e.Text).ToArray(); + Assert.Equal(7, updatedGreets.Where(g => string.Equals("Hello Alfred", g)).Count()); + Assert.Equal(2, updatedGreets.Where(g => g == "Hello Red fish").Count()); + Assert.Equal(2, updatedGreets.Where(g => g == "Hello Blue fish").Count()); + Assert.Single(updatedGreets.Where(g => string.Equals("Hello Albert", g))); + Assert.Single(updatedGreets.Where(g => string.Equals("Hello Abraham", g))); + } + + private (WebAssemblyComponentMarker, WebAssemblyComponentMarker)[] ReadMarkers(string content) + { + content = content.Replace("\r\n", ""); + var matches = Regex.Matches(content, MarkerPattern); + var markers = matches.Select(s => JsonSerializer.Deserialize( + s.Groups[1].Value, + WebAssemblyComponentSerializationSettings.JsonSerializationOptions)); + + var prerenderMarkers = markers.Where(m => m.PrerenderId != null).GroupBy(p => p.PrerenderId).Select(g => (g.First(), g.Skip(1).First())).ToArray(); + var nonPrerenderMarkers = markers.Where(m => m.PrerenderId == null).Select(g => (g, (WebAssemblyComponentMarker)default)).ToArray(); + + return prerenderMarkers.Concat(nonPrerenderMarkers).ToArray(); + } + + private void BeginInteractivity() + { + Browser.FindElement(By.Id("load-boot-script")).Click(); + } + } +} diff --git a/src/Components/test/E2ETest/Tests/FormsTest.cs b/src/Components/test/E2ETest/Tests/FormsTest.cs index 265314d4ab..9c4f840dcf 100644 --- a/src/Components/test/E2ETest/Tests/FormsTest.cs +++ b/src/Components/test/E2ETest/Tests/FormsTest.cs @@ -560,6 +560,23 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests Browser.Equal("", () => selectWithoutComponent.GetAttribute("value")); } + [Fact] + public void RespectsCustomFieldCssClassProvider() + { + var appElement = MountTypicalValidationComponent(); + var socksInput = appElement.FindElement(By.ClassName("socks")).FindElement(By.TagName("input")); + var messagesAccessor = CreateValidationMessagesAccessor(appElement); + + // Validates on edit + Browser.Equal("valid-socks", () => socksInput.GetAttribute("class")); + socksInput.SendKeys("Purple\t"); + Browser.Equal("modified valid-socks", () => socksInput.GetAttribute("class")); + + // Can become invalid + socksInput.SendKeys(" with yellow spots\t"); + Browser.Equal("modified invalid-socks", () => socksInput.GetAttribute("class")); + } + [Fact] public void NavigateOnSubmitWorks() { diff --git a/src/Components/test/E2ETest/Tests/InputFileTest.cs b/src/Components/test/E2ETest/Tests/InputFileTest.cs new file mode 100644 index 0000000000..d96d4358dc --- /dev/null +++ b/src/Components/test/E2ETest/Tests/InputFileTest.cs @@ -0,0 +1,175 @@ +// 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.Linq; +using System.Text; +using BasicTestApp; +using Microsoft.AspNetCore.Components.E2ETest; +using Microsoft.AspNetCore.Components.E2ETest.Infrastructure; +using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures; +using Microsoft.AspNetCore.E2ETesting; +using OpenQA.Selenium; +using OpenQA.Selenium.Support.Extensions; +using Xunit; +using Xunit.Abstractions; + +namespace Microsoft.AspNetCore.Components.E2ETests.Tests +{ + public class InputFileTest : ServerTestBase>, IDisposable + { + private string _tempDirectory; + + public InputFileTest( + BrowserFixture browserFixture, + ToggleExecutionModeServerFixture serverFixture, + ITestOutputHelper output) + : base(browserFixture, serverFixture, output) + { + } + + protected override void InitializeAsyncCore() + { + _tempDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); + Directory.CreateDirectory(_tempDirectory); + + Navigate(ServerPathBase, noReload: _serverFixture.ExecutionMode == ExecutionMode.Client); + Browser.MountTestComponent(); + } + + [Fact] + public void CanUploadSingleSmallFile() + { + // Create a temporary text file + var file = TempFile.Create(_tempDirectory, "txt", "This file was uploaded to the browser and read from .NET."); + + // Upload the file + var inputFile = Browser.FindElement(By.Id("input-file")); + inputFile.SendKeys(file.Path); + + var fileContainer = Browser.FindElement(By.Id($"file-{file.Name}")); + var fileSizeElement = fileContainer.FindElement(By.Id("file-size")); + var fileContentElement = fileContainer.FindElement(By.Id("file-content")); + + // Validate that the file was uploaded correctly + Browser.Equal(file.Contents.Length.ToString(), () => fileSizeElement.Text); + Browser.Equal(file.Text, () => fileContentElement.Text); + } + + [Fact] + public void CanUploadSingleLargeFile() + { + // Create a large text file + var fileContentSizeInBytes = 1024 * 1024; + var contentBuilder = new StringBuilder(); + + for (int i = 0; i < fileContentSizeInBytes; i++) + { + contentBuilder.Append((i % 10).ToString()); + } + + var file = TempFile.Create(_tempDirectory, "txt", contentBuilder.ToString()); + + // Upload the file + var inputFile = Browser.FindElement(By.Id("input-file")); + inputFile.SendKeys(file.Path); + + var fileContainer = Browser.FindElement(By.Id($"file-{file.Name}")); + var fileSizeElement = fileContainer.FindElement(By.Id("file-size")); + var fileContentElement = fileContainer.FindElement(By.Id("file-content")); + + // Validate that the file was uploaded correctly + Browser.Equal(file.Contents.Length.ToString(), () => fileSizeElement.Text); + Browser.Equal(file.Text, () => fileContentElement.Text); + } + + [Fact] + public void CanUploadMultipleFiles() + { + // Create multiple small text files + var files = Enumerable.Range(1, 3) + .Select(i => TempFile.Create(_tempDirectory, "txt", $"Contents of file {i}.")) + .ToList(); + + // Upload each file + var inputFile = Browser.FindElement(By.Id("input-file")); + inputFile.SendKeys(string.Join("\n", files.Select(f => f.Path))); + + // VAlidate that each file was uploaded correctly + Assert.All(files, file => + { + var fileContainer = Browser.FindElement(By.Id($"file-{file.Name}")); + var fileSizeElement = fileContainer.FindElement(By.Id("file-size")); + var fileContentElement = fileContainer.FindElement(By.Id("file-content")); + + Browser.Equal(file.Contents.Length.ToString(), () => fileSizeElement.Text); + Browser.Equal(file.Text, () => fileContentElement.Text); + }); + } + + [Fact] + public void CanUploadAndConvertImageFile() + { + var sourceImageId = "image-source"; + + // Get the source image base64 + var base64 = Browser.ExecuteJavaScript($@" + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d'); + const image = document.getElementById('{sourceImageId}'); + + canvas.width = image.naturalWidth; + canvas.height = image.naturalHeight; + context.drawImage(image, 0, 0, image.naturalWidth, image.naturalHeight); + + return canvas.toDataURL().split(',').pop();"); + + // Save the image file locally + var file = TempFile.Create(_tempDirectory, "png", Convert.FromBase64String(base64)); + + // Re-upload the image file (it will be converted to a JPEG and scaled to fix 640x480) + var inputFile = Browser.FindElement(By.Id("input-image")); + inputFile.SendKeys(file.Path); + + // Validate that the image was converted without error and is the correct size + var uploadedImage = Browser.FindElement(By.Id("image-uploaded")); + + Browser.Equal(480, () => uploadedImage.Size.Width); + Browser.Equal(480, () => uploadedImage.Size.Height); + } + + public void Dispose() + { + Directory.Delete(_tempDirectory, recursive: true); + } + + private struct TempFile + { + public string Name { get; } + public string Path { get; } + public byte[] Contents { get; } + + public string Text => Encoding.ASCII.GetString(Contents); + + private TempFile(string tempDirectory, string extension, byte[] contents) + { + Name = $"{Guid.NewGuid():N}.{extension}"; + Path = $"{tempDirectory}\\{Name}"; + Contents = contents; + } + + public static TempFile Create(string tempDirectory, string extension, byte[] contents) + { + var file = new TempFile(tempDirectory, extension, contents); + + File.WriteAllBytes(file.Path, contents); + + return file; + } + + public static TempFile Create(string tempDirectory, string extension, string text) + => Create(tempDirectory, extension, Encoding.ASCII.GetBytes(text)); + } + } +} diff --git a/src/Components/test/E2ETest/Tests/InteropTest.cs b/src/Components/test/E2ETest/Tests/InteropTest.cs index 2397ea3f9d..69d84233a0 100644 --- a/src/Components/test/E2ETest/Tests/InteropTest.cs +++ b/src/Components/test/E2ETest/Tests/InteropTest.cs @@ -55,10 +55,13 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests ["result7Async"] = @"[{""id"":6,""isValid"":true,""data"":{""source"":""Some random text with at least 6 characters"",""start"":6,""length"":6}},6,123,24,48,6.25]", ["result8Async"] = @"[{""id"":7,""isValid"":false,""data"":{""source"":""Some random text with at least 7 characters"",""start"":7,""length"":7}},7,123,28,56,7.25,[0.5,1.5,2.5,3.5,4.5,5.5,6.5]]", ["result9Async"] = @"[{""id"":8,""isValid"":true,""data"":{""source"":""Some random text with at least 8 characters"",""start"":8,""length"":8}},8,123,32,64,8.25,[0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5],{""source"":""Some random text with at least 7 characters"",""start"":9,""length"":9}]", + ["roundTripJSObjectReferenceAsync"] = @"""successful""", + ["invokeDisposedJSObjectReferenceExceptionAsync"] = @"""JS object instance with ID", ["AsyncThrowSyncException"] = @"""System.InvalidOperationException: Threw a sync exception!", ["AsyncThrowAsyncException"] = @"""System.InvalidOperationException: Threw an async exception!", ["SyncExceptionFromAsyncMethod"] = "Function threw a sync exception!", ["AsyncExceptionFromAsyncMethod"] = "Function threw an async exception!", + ["JSObjectReferenceInvokeNonFunctionException"] = "The value 'nonFunction' is not a function.", ["resultReturnDotNetObjectByRefAsync"] = "1001", ["instanceMethodThisTypeNameAsync"] = @"""JavaScriptInterop""", ["instanceMethodStringValueUpperAsync"] = @"""MY STRING""", @@ -69,6 +72,10 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests ["testDtoAsync"] = "Same", ["returnPrimitiveAsync"] = "123", ["returnArrayAsync"] = "first,second", + ["jsObjectReference.identity"] = "Invoked from JSObjectReference", + ["jsObjectReference.nested.add"] = "5", + ["addViaJSObjectReference"] = "5", + ["jsObjectReferenceModule"] = "Returned from module!", ["syncGenericInstanceMethod"] = @"""Initial value""", ["asyncGenericInstanceMethod"] = @"""Updated value 1""", }; @@ -93,6 +100,8 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests ["result7"] = @"[{""id"":6,""isValid"":true,""data"":{""source"":""Some random text with at least 6 characters"",""start"":6,""length"":6}},6,123,24,48,6.25]", ["result8"] = @"[{""id"":7,""isValid"":false,""data"":{""source"":""Some random text with at least 7 characters"",""start"":7,""length"":7}},7,123,28,56,7.25,[0.5,1.5,2.5,3.5,4.5,5.5,6.5]]", ["result9"] = @"[{""id"":8,""isValid"":true,""data"":{""source"":""Some random text with at least 8 characters"",""start"":8,""length"":8}},8,123,32,64,8.25,[0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5],{""source"":""Some random text with at least 7 characters"",""start"":9,""length"":9}]", + ["roundTripJSObjectReference"] = @"""successful""", + ["invokeDisposedJSObjectReferenceException"] = @"""JS object instance with ID", ["ThrowException"] = @"""System.InvalidOperationException: Threw an exception!", ["ExceptionFromSyncMethod"] = "Function threw an exception!", ["resultReturnDotNetObjectByRefSync"] = "1000", @@ -100,6 +109,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests ["instanceMethodStringValueUpper"] = @"""MY STRING""", ["instanceMethodIncomingByRef"] = "123", ["instanceMethodOutgoingByRef"] = "1234", + ["jsInProcessObjectReference.identity"] = "Invoked from JSInProcessObjectReference", ["stringValueUpperSync"] = "MY STRING", ["testDtoNonSerializedValueSync"] = "99999", ["testDtoSync"] = "Same", diff --git a/src/Components/test/E2ETest/Tests/RoutingTest.cs b/src/Components/test/E2ETest/Tests/RoutingTest.cs index 28fe0a1727..d1642864db 100644 --- a/src/Components/test/E2ETest/Tests/RoutingTest.cs +++ b/src/Components/test/E2ETest/Tests/RoutingTest.cs @@ -570,14 +570,24 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests { var app = Browser.MountTestComponent(); - // Navigating from one page to another should - // cancel the previous OnNavigate Task SetUrlViaPushState("/Other"); var errorUiElem = Browser.Exists(By.Id("blazor-error-ui"), TimeSpan.FromSeconds(10)); Assert.NotNull(errorUiElem); } + [Fact] + public void OnNavigate_CanRenderUIForSyncExceptions() + { + var app = Browser.MountTestComponent(); + + // Should capture exception from synchronously thrown + SetUrlViaPushState("/WithLazyAssembly"); + + var errorUiElem = Browser.Exists(By.Id("blazor-error-ui"), TimeSpan.FromSeconds(10)); + Assert.NotNull(errorUiElem); + } + [Fact] public void OnNavigate_DoesNotRenderWhileOnNavigateExecuting() { diff --git a/src/Components/test/E2ETest/Tests/WebAssemblyAuthenticationTests.cs b/src/Components/test/E2ETest/Tests/WebAssemblyAuthenticationTests.cs index 998144b33c..52b25edefc 100644 --- a/src/Components/test/E2ETest/Tests/WebAssemblyAuthenticationTests.cs +++ b/src/Components/test/E2ETest/Tests/WebAssemblyAuthenticationTests.cs @@ -199,7 +199,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests "profile", "Wasm.Authentication.ServerAPI" }, - payload.Scopes); + 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); diff --git a/src/Components/test/testassets/BasicTestApp/FormsTest/CustomFieldCssClassProvider.cs b/src/Components/test/testassets/BasicTestApp/FormsTest/CustomFieldCssClassProvider.cs new file mode 100644 index 0000000000..bee221d307 --- /dev/null +++ b/src/Components/test/testassets/BasicTestApp/FormsTest/CustomFieldCssClassProvider.cs @@ -0,0 +1,47 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Linq; +using Microsoft.AspNetCore.Components.Forms; + +namespace BasicTestApp.FormsTest +{ + // For E2E testing, this is a rough example of a field CSS class provider that looks for + // a custom attribute defining CSS class names. It isn't very efficient (it does reflection + // and allocates on every invocation) but is sufficient for testing purposes. + public class CustomFieldCssClassProvider : FieldCssClassProvider + { + public override string GetFieldCssClass(EditContext editContext, in FieldIdentifier fieldIdentifier) + { + var cssClassName = base.GetFieldCssClass(editContext, fieldIdentifier); + + // If we can find a [CustomValidationClassName], use it + var propertyInfo = fieldIdentifier.Model.GetType().GetProperty(fieldIdentifier.FieldName); + if (propertyInfo != null) + { + var customValidationClassName = (CustomValidationClassNameAttribute)propertyInfo + .GetCustomAttributes(typeof(CustomValidationClassNameAttribute), true) + .FirstOrDefault(); + if (customValidationClassName != null) + { + cssClassName = string.Join(' ', cssClassName.Split(' ').Select(token => token switch + { + "valid" => customValidationClassName.Valid ?? token, + "invalid" => customValidationClassName.Invalid ?? token, + _ => token, + })); + } + } + + return cssClassName; + } + } + + [AttributeUsage(AttributeTargets.Property)] + public class CustomValidationClassNameAttribute : Attribute + { + public string Valid { get; set; } + public string Invalid { get; set; } + } +} diff --git a/src/Components/test/testassets/BasicTestApp/FormsTest/TypicalValidationComponent.razor b/src/Components/test/testassets/BasicTestApp/FormsTest/TypicalValidationComponent.razor index 89a53802ee..4f91e46538 100644 --- a/src/Components/test/testassets/BasicTestApp/FormsTest/TypicalValidationComponent.razor +++ b/src/Components/test/testassets/BasicTestApp/FormsTest/TypicalValidationComponent.razor @@ -66,6 +66,9 @@

+

+ Socks color: +

Accepts terms:

@@ -98,6 +101,7 @@ protected override void OnInitialized() { editContext = new EditContext(person); + editContext.SetFieldCssClassProvider(new CustomFieldCssClassProvider()); customValidationMessageStore = new ValidationMessageStore(editContext); } @@ -145,6 +149,9 @@ [Required, EnumDataType(typeof(Country))] public Country? Country { get; set; } = null; + [Required, StringLength(10), CustomValidationClassName(Valid = "valid-socks", Invalid = "invalid-socks")] + public string SocksColor { get; set; } + public string Username { get; set; } } diff --git a/src/Components/test/testassets/BasicTestApp/Index.razor b/src/Components/test/testassets/BasicTestApp/Index.razor index 6747601918..db232b3aa4 100644 --- a/src/Components/test/testassets/BasicTestApp/Index.razor +++ b/src/Components/test/testassets/BasicTestApp/Index.razor @@ -46,6 +46,7 @@ + diff --git a/src/Components/test/testassets/BasicTestApp/InputFileComponent.razor b/src/Components/test/testassets/BasicTestApp/InputFileComponent.razor new file mode 100644 index 0000000000..e9f7dbd301 --- /dev/null +++ b/src/Components/test/testassets/BasicTestApp/InputFileComponent.razor @@ -0,0 +1,80 @@ +@using System.IO; +@using Microsoft.AspNetCore.Components.Web.Extensions + +

File preview

+ +
+ +@if (isLoading) +{ +

Loading...


+} + +@foreach (var (file, content) in loadedFiles) +{ +

+ File name: @(file.Name)
+ File size (bytes): @(file.Size)
+ File content: @content
+

+} + +

Image upload

+ +
+ +@if (imageDataUri != null) +{ +

+ Uploaded image:
+ +

+} + +

+ Source image:
+ +

+ +@code { + Dictionary loadedFiles = new Dictionary(); + + bool isLoading; + + string imageDataUri; + + async Task LoadFiles(InputFileChangeEventArgs e) + { + isLoading = true; + loadedFiles.Clear(); + + foreach (var file in e.Files) + { + StateHasChanged(); + + using var reader = new StreamReader(file.OpenReadStream()); + + loadedFiles.Add(file, await reader.ReadToEndAsync()); + } + + isLoading = false; + } + + async Task LoadImage(InputFileChangeEventArgs e) + { + var file = e.Files.SingleOrDefault(); + + if (file != null) + { + var format = "image/jpeg"; + var imageFile = await file.ToImageFileAsync(format, 640, 480); + + using var fileStream = imageFile.OpenReadStream(); + using var memoryStream = new MemoryStream(); + await fileStream.CopyToAsync(memoryStream); + + imageDataUri = $"data:{format};base64,{Convert.ToBase64String(memoryStream.ToArray())}"; + StateHasChanged(); + } + } +} diff --git a/src/Components/test/testassets/BasicTestApp/InteropComponent.razor b/src/Components/test/testassets/BasicTestApp/InteropComponent.razor index d329d68900..b24da1366b 100644 --- a/src/Components/test/testassets/BasicTestApp/InteropComponent.razor +++ b/src/Components/test/testassets/BasicTestApp/InteropComponent.razor @@ -46,6 +46,8 @@

@SyncExceptionFromAsyncMethod?.Message

@nameof(AsyncExceptionFromAsyncMethod)

@AsyncExceptionFromAsyncMethod?.Message

+

@nameof(JSObjectReferenceInvokeNonFunctionException)

+

@JSObjectReferenceInvokeNonFunctionException?.Message

@if (DoneWithInterop) { @@ -59,6 +61,7 @@ public JSException ExceptionFromSyncMethod { get; set; } public JSException SyncExceptionFromAsyncMethod { get; set; } public JSException AsyncExceptionFromAsyncMethod { get; set; } + public JSException JSObjectReferenceInvokeNonFunctionException { get; set; } public IDictionary ReceiveDotNetObjectByRefResult { get; set; } = new Dictionary(); public IDictionary ReceiveDotNetObjectByRefAsyncResult { get; set; } = new Dictionary(); @@ -134,6 +137,28 @@ ReturnValues["returnArray"] = string.Join(",", ((IJSInProcessRuntime)JSRuntime).Invoke("returnArray").Select(x => x.Source).ToArray()); } + var jsObjectReference = await JSRuntime.InvokeAsync("returnJSObjectReference"); + ReturnValues["jsObjectReference.identity"] = await jsObjectReference.InvokeAsync("identity", "Invoked from JSObjectReference"); + ReturnValues["jsObjectReference.nested.add"] = (await jsObjectReference.InvokeAsync("nested.add", 2, 3)).ToString(); + ReturnValues["addViaJSObjectReference"] = (await JSRuntime.InvokeAsync("addViaJSObjectReference", jsObjectReference, 2, 3)).ToString(); + + try + { + await jsObjectReference.InvokeAsync("nonFunction"); + } + catch (JSException e) + { + JSObjectReferenceInvokeNonFunctionException = e; + } + + var module = await JSRuntime.InvokeAsync("import", "./js/testmodule.js"); + ReturnValues["jsObjectReferenceModule"] = await module.InvokeAsync("identity", "Returned from module!"); + + if (shouldSupportSyncInterop) + { + InvokeInProcessJSInterop(); + } + Invocations = invocations; DoneWithInterop = true; } @@ -163,6 +188,14 @@ ReceiveDotNetObjectByRefResult["testDto"] = result.TestDto.Value == passDotNetObjectByRef ? "Same" : "Different"; } + public void InvokeInProcessJSInterop() + { + var inProcRuntime = ((IJSInProcessRuntime)JSRuntime); + + var jsInProcObjectReference = inProcRuntime.Invoke("returnJSObjectReference"); + ReturnValues["jsInProcessObjectReference.identity"] = jsInProcObjectReference.Invoke("identity", "Invoked from JSInProcessObjectReference"); + } + public class PassDotNetObjectByRefArgs { public string StringValue { get; set; } diff --git a/src/Components/test/testassets/BasicTestApp/InteropTest/JavaScriptInterop.cs b/src/Components/test/testassets/BasicTestApp/InteropTest/JavaScriptInterop.cs index 18cefecd15..8667bdc2c6 100644 --- a/src/Components/test/testassets/BasicTestApp/InteropTest/JavaScriptInterop.cs +++ b/src/Components/test/testassets/BasicTestApp/InteropTest/JavaScriptInterop.cs @@ -414,6 +414,47 @@ namespace BasicTestApp.InteropTest return objectByRef.Value.GetNonSerializedValue(); } + [JSInvokable] + public static JSObjectReference RoundTripJSObjectReference(JSObjectReference jsObjectReference) + { + return jsObjectReference; + } + + [JSInvokable] + public static async Task RoundTripJSObjectReferenceAsync(JSObjectReference jSObjectReference) + { + await Task.Yield(); + return jSObjectReference; + } + + [JSInvokable] + public static string InvokeDisposedJSObjectReferenceException(JSInProcessObjectReference jsObjectReference) + { + try + { + jsObjectReference.Invoke("noop"); + return "No exception thrown"; + } + catch (JSException e) + { + return e.Message; + } + } + + [JSInvokable] + public static async Task InvokeDisposedJSObjectReferenceExceptionAsync(JSObjectReference jsObjectReference) + { + try + { + await jsObjectReference.InvokeVoidAsync("noop"); + return "No exception thrown"; + } + catch (JSException e) + { + return e.Message; + } + } + [JSInvokable] public InstanceMethodOutput InstanceMethod(InstanceMethodInput input) { diff --git a/src/Components/test/testassets/BasicTestApp/RouterTest/TestRouterWithOnNavigate.razor b/src/Components/test/testassets/BasicTestApp/RouterTest/TestRouterWithOnNavigate.razor index 7b0c289b56..933512d2bf 100644 --- a/src/Components/test/testassets/BasicTestApp/RouterTest/TestRouterWithOnNavigate.razor +++ b/src/Components/test/testassets/BasicTestApp/RouterTest/TestRouterWithOnNavigate.razor @@ -26,9 +26,15 @@ { "LongPage1", new Func(TestLoadingPageShows) }, { "LongPage2", new Func(TestOnNavCancel) }, { "Other", new Func(TestOnNavException) }, - {"WithParameters/name/Abc", new Func(TestRefreshHandling)} + { "WithLazyAssembly", new Func(TestOnNavException) }, + { "WithParameters/name/Abc", new Func(TestRefreshHandling) } }; + protected override void OnAfterRender(bool firstRender) + { + Console.WriteLine("Render triggered..."); + } + private async Task OnNavigateAsync(NavigationContext args) { Console.WriteLine($"Running OnNavigate for {args.Path}..."); @@ -56,6 +62,11 @@ throw new Exception("This is an uncaught exception."); } + public static Task TestOnNavSyncException(NavigationContext args) + { + throw new Exception("This is an uncaught exception."); + } + public static async Task TestRefreshHandling(NavigationContext args) { await Task.Delay(Timeout.Infinite, args.CancellationToken); diff --git a/src/Components/test/testassets/BasicTestApp/VirtualizationComponent.razor b/src/Components/test/testassets/BasicTestApp/VirtualizationComponent.razor index 29aba9ea3e..69e776ccfd 100644 --- a/src/Components/test/testassets/BasicTestApp/VirtualizationComponent.razor +++ b/src/Components/test/testassets/BasicTestApp/VirtualizationComponent.razor @@ -22,7 +22,7 @@
Item @context
-
Loading item @context.Index...
+
Loading item @context.Index...
diff --git a/src/Components/test/testassets/BasicTestApp/wwwroot/images/blazor_logo_1000x.png b/src/Components/test/testassets/BasicTestApp/wwwroot/images/blazor_logo_1000x.png new file mode 100644 index 0000000000..fb308a8e28 Binary files /dev/null and b/src/Components/test/testassets/BasicTestApp/wwwroot/images/blazor_logo_1000x.png differ diff --git a/src/Components/test/testassets/BasicTestApp/wwwroot/index.html b/src/Components/test/testassets/BasicTestApp/wwwroot/index.html index 20c78f34f2..f387c50b57 100644 --- a/src/Components/test/testassets/BasicTestApp/wwwroot/index.html +++ b/src/Components/test/testassets/BasicTestApp/wwwroot/index.html @@ -45,6 +45,8 @@ + + diff --git a/src/Components/test/testassets/BasicTestApp/wwwroot/js/jsinteroptests.js b/src/Components/test/testassets/BasicTestApp/wwwroot/js/jsinteroptests.js index dbbba1e0c8..14ef4714c1 100644 --- a/src/Components/test/testassets/BasicTestApp/wwwroot/js/jsinteroptests.js +++ b/src/Components/test/testassets/BasicTestApp/wwwroot/js/jsinteroptests.js @@ -30,6 +30,17 @@ async function invokeDotNetInteropMethodsAsync(shouldSupportSyncInterop, dotNetO var returnDotNetObjectByRefResult = DotNet.invokeMethod(assemblyName, 'ReturnDotNetObjectByRef'); results['resultReturnDotNetObjectByRefSync'] = DotNet.invokeMethod(assemblyName, 'ExtractNonSerializedValue', returnDotNetObjectByRefResult['Some sync instance']); + var jsObjectReference = DotNet.createJSObjectReference({ + prop: 'successful', + noop: function () { } + }); + + var returnedObject = DotNet.invokeMethod(assemblyName, 'RoundTripJSObjectReference', jsObjectReference); + results['roundTripJSObjectReference'] = returnedObject && returnedObject.prop; + + DotNet.disposeJSObjectReference(jsObjectReference); + results['invokeDisposedJSObjectReferenceException'] = DotNet.invokeMethod(assemblyName, 'InvokeDisposedJSObjectReferenceException', jsObjectReference); + var instanceMethodResult = instanceMethodsTarget.invokeMethod('InstanceMethod', { stringValue: 'My string', dtoByRef: dotNetObjectByRef @@ -66,6 +77,17 @@ async function invokeDotNetInteropMethodsAsync(shouldSupportSyncInterop, dotNetO const returnDotNetObjectByRefAsync = await DotNet.invokeMethodAsync(assemblyName, 'ReturnDotNetObjectByRefAsync'); results['resultReturnDotNetObjectByRefAsync'] = await DotNet.invokeMethodAsync(assemblyName, 'ExtractNonSerializedValue', returnDotNetObjectByRefAsync['Some async instance']); + var jsObjectReference = DotNet.createJSObjectReference({ + prop: 'successful', + noop: function () { } + }); + + var returnedObject = await DotNet.invokeMethodAsync(assemblyName, 'RoundTripJSObjectReferenceAsync', jsObjectReference); + results['roundTripJSObjectReferenceAsync'] = returnedObject && returnedObject.prop; + + DotNet.disposeJSObjectReference(jsObjectReference); + results['invokeDisposedJSObjectReferenceExceptionAsync'] = await DotNet.invokeMethodAsync(assemblyName, 'InvokeDisposedJSObjectReferenceExceptionAsync', jsObjectReference); + const instanceMethodAsync = await instanceMethodsTarget.invokeMethodAsync('InstanceMethodAsync', { stringValue: 'My string', dtoByRef: dotNetObjectByRef @@ -167,6 +189,8 @@ window.jsInteropTests = { asyncFunctionThrowsAsyncException: asyncFunctionThrowsAsyncException, returnPrimitive: returnPrimitive, returnPrimitiveAsync: returnPrimitiveAsync, + returnJSObjectReference: returnJSObjectReference, + addViaJSObjectReference: addViaJSObjectReference, receiveDotNetObjectByRef: receiveDotNetObjectByRef, receiveDotNetObjectByRefAsync: receiveDotNetObjectByRefAsync }; @@ -195,6 +219,27 @@ function returnArrayAsync() { }); } +function returnJSObjectReference() { + return { + identity: function (value) { + return value; + }, + nonFunction: 123, + nested: { + add: function (a, b) { + return a + b; + } + }, + dispose: function () { + DotNet.disposeJSObjectReference(this); + }, + }; +} + +function addViaJSObjectReference(jsObjectReference, a, b) { + return jsObjectReference.nested.add(a, b); +} + function functionThrowsException() { throw new Error('Function threw an exception!'); } @@ -258,4 +303,4 @@ function receiveDotNetObjectByRefAsync(incomingData) { testDto: testDto }; }); -} \ No newline at end of file +} diff --git a/src/Components/test/testassets/BasicTestApp/wwwroot/js/testmodule.js b/src/Components/test/testassets/BasicTestApp/wwwroot/js/testmodule.js new file mode 100644 index 0000000000..ab7a818ba8 --- /dev/null +++ b/src/Components/test/testassets/BasicTestApp/wwwroot/js/testmodule.js @@ -0,0 +1,3 @@ +export function identity(value) { + return value; +} diff --git a/src/Components/test/testassets/TestServer/Components.TestServer.csproj b/src/Components/test/testassets/TestServer/Components.TestServer.csproj index 651b301bec..59b8fe5685 100644 --- a/src/Components/test/testassets/TestServer/Components.TestServer.csproj +++ b/src/Components/test/testassets/TestServer/Components.TestServer.csproj @@ -22,10 +22,13 @@ - + + + + <_Parameter1>Microsoft.AspNetCore.Testing.BasicTestApp.ContentRoot diff --git a/src/Components/test/testassets/TestServer/MultipleComponents.cs b/src/Components/test/testassets/TestServer/MultipleComponents.cs index b48de346df..3a3bf468a6 100644 --- a/src/Components/test/testassets/TestServer/MultipleComponents.cs +++ b/src/Components/test/testassets/TestServer/MultipleComponents.cs @@ -32,6 +32,18 @@ namespace TestServer app.UseDeveloperExceptionPage(); } + app.Map("/Client/multiple-components", app => + { + app.UseBlazorFrameworkFiles(); + app.UseStaticFiles(); + app.UseRouting(); + app.UseEndpoints(endpoints => + { + endpoints.MapRazorPages(); + endpoints.MapFallbackToPage("/Client/MultipleComponents"); + }); + }); + app.Map("/multiple-components", app => { app.UseStaticFiles(); diff --git a/src/Components/test/testassets/TestServer/Pages/Client/MultipleComponents.cshtml b/src/Components/test/testassets/TestServer/Pages/Client/MultipleComponents.cshtml new file mode 100644 index 0000000000..0f7078e0e6 --- /dev/null +++ b/src/Components/test/testassets/TestServer/Pages/Client/MultipleComponents.cshtml @@ -0,0 +1,29 @@ +@page "/multiple-components" +@using BasicTestApp.MultipleComponents; + +@{ + Layout = "./MultipleComponentsLayout.cshtml"; +} + + +@(await Html.RenderComponentAsync(RenderMode.WebAssemblyPrerendered)) +@(await Html.RenderComponentAsync(RenderMode.WebAssembly)) + + +
+

Some content before

+ +

Some content between

+ +

Some content after

+
+

Some content before

+ + +

Some content after

+
+
+
+ + +
diff --git a/src/Components/test/testassets/TestServer/Pages/Client/MultipleComponentsLayout.cshtml b/src/Components/test/testassets/TestServer/Pages/Client/MultipleComponentsLayout.cshtml new file mode 100644 index 0000000000..e46aae2983 --- /dev/null +++ b/src/Components/test/testassets/TestServer/Pages/Client/MultipleComponentsLayout.cshtml @@ -0,0 +1,45 @@ +@using BasicTestApp.MultipleComponents; + + + + + Multiple component entry points + @* We need to make sure base is set to "/" so that the libraries load correctly *@ + + @* This page is used to validate the ability to render multiple root components in a blazor webassembly application. + *@ + + +
+ + + @RenderBody() + + +
+ + @* + So that E2E tests can make assertions about both the prerendered and + interactive states, we only load the .js file when told to. + *@ +
+ + + + + + + + + diff --git a/src/Components/test/testassets/TestServer/Pages/_ServerHost.cshtml b/src/Components/test/testassets/TestServer/Pages/_ServerHost.cshtml index 54a00f8697..ebd2beeaf9 100644 --- a/src/Components/test/testassets/TestServer/Pages/_ServerHost.cshtml +++ b/src/Components/test/testassets/TestServer/Pages/_ServerHost.cshtml @@ -41,6 +41,8 @@ + +