Merge branch 'master' into merge/release/5.0-preview8-to-master
This commit is contained in:
commit
e1fcdcaa86
|
|
@ -0,0 +1,66 @@
|
|||
---
|
||||
name: 🐞 Razor Tooling Bug report
|
||||
about: Report an issue about something that is not working in the new Razor tooling
|
||||
labels: area-razor.tooling, feature-razor.vs
|
||||
---
|
||||
|
||||
<!--
|
||||
|
||||
More information on our issue management policies can be found here: https://aka.ms/aspnet/issue-policies
|
||||
|
||||
Please keep in mind that the GitHub issue tracker is not intended as a general support forum, but for reporting **non-security** bugs and feature requests.
|
||||
|
||||
If you believe you have an issue that affects the SECURITY of the platform, please do NOT create an issue and instead email your issue details to secure@microsoft.com. Your report may be eligible for our [bug bounty](https://www.microsoft.com/en-us/msrc/bounty-dot-net-core) but ONLY if it is reported through email.
|
||||
For other types of questions, consider using [StackOverflow](https://stackoverflow.com).
|
||||
|
||||
-->
|
||||
|
||||
<!-- NOTE: This issue template is meant specifically to be used for issues with the new experimental Razor tooling experience provided in Visual Studio's Preview Feature pane -->
|
||||
|
||||
### Describe the bug
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
### To Reproduce
|
||||
<!--
|
||||
We ❤ code! Point us to a minimalistic repro project hosted in a GitHub repo.
|
||||
For a repro project, create a new ASP.NET Core project using the template of your your choice, apply the minimum required code to result in the issue you're observing.
|
||||
|
||||
We will close this issue if:
|
||||
- the repro project you share with us is complex. We can't investigate custom projects, so don't point us to such, please.
|
||||
- if we will not be able to repro the behavior you're reporting
|
||||
-->
|
||||
|
||||
### Logs & Exceptions
|
||||
|
||||
Please collect the data below before reporting your issue to aid us in diagnosing the root cause.
|
||||
|
||||
#### Activity log
|
||||
[Here](https://docs.microsoft.com/en-us/visualstudio/extensibility/how-to-use-the-activity-log?view=vs-2019#to-examine-the-activity-log) are the instructions on how to generate/acquire one.
|
||||
|
||||
#### Razor Language Server Client log
|
||||
<!-- In Visual Studio's `Output` window, the drop-down contains a `Razor Language Server Client` item. Include that below. -->
|
||||
<details>
|
||||
<summary>Razor Language Server Client Log Output</summary>
|
||||
|
||||
Paste log output here
|
||||
|
||||
</details>
|
||||
|
||||
#### HTML Language Server Client log
|
||||
<!-- In Visual Studio's `Output` window, the drop-down contains a `HtmlyLanguageClient` item. Include that below. -->
|
||||
<details>
|
||||
<summary>HTML Language Server Client Log Output</summary>
|
||||
|
||||
Paste log output here
|
||||
|
||||
</details>
|
||||
|
||||
### Further technical details
|
||||
- VS version (Help => About Microsoft Visual Studio, i.e. 16.8.0 Preview 1 30313.27...). If in Codespaces there will be two versions (server and client), please provide both.
|
||||
- Scenario (Local, LiveShare, Codespaces)
|
||||
|
||||
### Pre-requisite checklist
|
||||
- [ ] Steps to reproduce the issue
|
||||
- [ ] Visual Studio Activity Log attached.
|
||||
- [ ] Razor Language Server client logs included.
|
||||
- [ ] HTML Language Server client logs included
|
||||
793
AspNetCore.sln
793
AspNetCore.sln
File diff suppressed because it is too large
Load Diff
|
|
@ -151,9 +151,7 @@
|
|||
Include="$(RepoRoot)src\Analyzers\Internal.AspNetCore.Analyzers\src\Internal.AspNetCore.Analyzers.csproj"
|
||||
ReferenceOutputAssembly="false"
|
||||
OutputItemType="Analyzer"
|
||||
PrivateAssets="All"
|
||||
Version="$(InternalAspNetCoreAnalyzersPackageVersion)"
|
||||
IsImplicitlyDefined="true" />
|
||||
PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Compilation options which apply to all languages. Language-specific options should be set in eng/targets/$(lang).Common.props -->
|
||||
|
|
|
|||
|
|
@ -133,10 +133,14 @@ docker run \
|
|||
-t \
|
||||
-e TF_BUILD \
|
||||
-e BUILD_NUMBER \
|
||||
-e BUILD_BUILDID \
|
||||
-e SYSTEM_TEAMPROJECT \
|
||||
-e BUILD_BUILDNUMBER \
|
||||
-e BUILD_REPOSITORY_URI \
|
||||
-e BUILD_SOURCEVERSION \
|
||||
-e BUILD_SOURCEBRANCH \
|
||||
-e SYSTEM_DEFINITIONID \
|
||||
-e SYSTEM_TEAMFOUNDATIONCOLLECTIONURI \
|
||||
-e DOTNET_CLI_TELEMETRY_OPTOUT \
|
||||
-e Configuration \
|
||||
-v "$DIR:$DIR" \
|
||||
|
|
|
|||
|
|
@ -4,6 +4,22 @@ Building ASP.NET Core from source allows you to tweak and customize ASP.NET Core
|
|||
|
||||
See <https://github.com/dotnet/aspnetcore/labels/area-infrastructure> for known issues and to track ongoing work.
|
||||
|
||||
## Clone the source code
|
||||
|
||||
ASP.NET Core uses git submodules to include the source from a few other projects.
|
||||
|
||||
For a new copy of the project, run:
|
||||
|
||||
```ps1
|
||||
git clone --recursive https://github.com/dotnet/aspnetcore
|
||||
```
|
||||
|
||||
To update an existing copy, run:
|
||||
|
||||
```ps1
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
## Install pre-requisites
|
||||
|
||||
### Windows
|
||||
|
|
@ -22,7 +38,8 @@ Building ASP.NET Core on Windows requires:
|
|||
However, any Visual Studio 2019 instance that meets the requirements should be fine. See [global.json](/global.json)
|
||||
and [eng/scripts/vs.json](/eng/scripts/vs.json) for those requirements. By default, the script will install Visual Studio Enterprise Edition, however you can use a different edition by passing the `-Edition` flag.
|
||||
* Git. <https://git-scm.org>
|
||||
* NodeJS. LTS version of 10.14.2 or newer <https://nodejs.org>
|
||||
* NodeJS. LTS version of 10.14.2 or newer <https://nodejs.org>.
|
||||
* Install yarn globally (`npm install -g yarn`)
|
||||
* Java Development Kit 11 or newer. Either:
|
||||
* OpenJDK <https://jdk.java.net/>
|
||||
* Oracle's JDK <https://www.oracle.com/technetwork/java/javase/downloads/index.html>
|
||||
|
|
@ -52,22 +69,6 @@ Building ASP.NET Core on macOS or Linux requires:
|
|||
* OpenJDK <https://jdk.java.net/>
|
||||
* Oracle's JDK <https://www.oracle.com/technetwork/java/javase/downloads/index.html>
|
||||
|
||||
## Clone the source code
|
||||
|
||||
ASP.NET Core uses git submodules to include the source from a few other projects.
|
||||
|
||||
For a new copy of the project, run:
|
||||
|
||||
```ps1
|
||||
git clone --recursive https://github.com/dotnet/aspnetcore
|
||||
```
|
||||
|
||||
To update an existing copy, run:
|
||||
|
||||
```ps1
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
**NOTE** some ISPs have been know to use web filtering software that has caused issues with git repository cloning, if you experience issues cloning this repo please review <https://help.github.com/en/github/authenticating-to-github/using-ssh-over-the-https-port>
|
||||
|
||||
## Building in Visual Studio
|
||||
|
|
@ -86,6 +87,9 @@ Before opening our .sln/.slnf files in Visual Studio or VS Code, you need to per
|
|||
> :bulb: Pro tip: you will also want to run this command after pulling large sets of changes. On the master
|
||||
> branch, we regularly update the versions of .NET Core SDK required to build the repo.
|
||||
> You will need to restart Visual Studio every time we update the .NET Core SDK.
|
||||
> To allow executing the setup script, you may need to update the execution policy on your machine.
|
||||
You can do so by running the `Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser` command
|
||||
in PowerShell. For more information on execution policies, you can read the [execution policy docs](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy).
|
||||
|
||||
2. Use the `startvs.cmd` script to open Visual Studio .sln/.slnf files. This script first sets the required
|
||||
environment variables.
|
||||
|
|
|
|||
|
|
@ -44,10 +44,6 @@
|
|||
<!-- Project selection can be overridden on the command line by passing in -projects. -->
|
||||
<When Condition="'$(ProjectToBuild)' != ''">
|
||||
<ItemGroup>
|
||||
<!-- Include RTMVersions.csproj unless this invocation is building RepoTasks.csproj or won't compile C#. -->
|
||||
<ProjectToBuild Include="$(RepoRoot)eng\RTMVersions\RTMVersions.csproj"
|
||||
Exclude="@(ProjectToExclude)"
|
||||
Condition=" $(ProjectToBuild.EndsWith('.csproj')) AND !$(ProjectToBuild.EndsWith('RepoTasks.csproj')) " />
|
||||
<ProjectToBuild Include="$(ProjectToBuild)" Exclude="@(ProjectToExclude);$(RepoRoot)**\bin\**\*;$(RepoRoot)**\obj\**\*">
|
||||
<RestoreInParallel Condition="'%(Extension)' == '.npmproj'">false</RestoreInParallel>
|
||||
</ProjectToBuild>
|
||||
|
|
@ -125,11 +121,8 @@
|
|||
<!--
|
||||
Use caution to avoid deep recursion. If the globbing pattern picks up something which exceeds MAX_PATH,
|
||||
the entire pattern will silently fail to evaluate correctly.
|
||||
|
||||
Include RTMVersions.csproj when building any managed projects.
|
||||
-->
|
||||
<DotNetProjects Include="
|
||||
$(RepoRoot)eng\RTMVersions\RTMVersions.csproj;
|
||||
$(RepoRoot)src\Framework\App.Ref\src\Microsoft.AspNetCore.App.Ref.csproj;
|
||||
$(RepoRoot)src\Framework\App.Runtime\src\Microsoft.AspNetCore.App.Runtime.csproj;
|
||||
$(RepoRoot)src\Framework\App.Ref.Internal\src\Microsoft.AspNetCore.App.Ref.Internal.csproj;
|
||||
|
|
@ -178,7 +171,6 @@
|
|||
$(RepoRoot)**\obj\**\*;"
|
||||
Condition=" '$(BuildMainlyReferenceProviders)' != 'true' " />
|
||||
<DotNetProjects Include="
|
||||
$(RepoRoot)eng\RTMVersions\RTMVersions.csproj;
|
||||
$(RepoRoot)src\DefaultBuilder\**\src\*.csproj;
|
||||
$(RepoRoot)src\Features\JsonPatch\**\src\*.csproj;
|
||||
$(RepoRoot)src\DataProtection\**\src\*.csproj;
|
||||
|
|
|
|||
|
|
@ -71,6 +71,8 @@ and are generated based on the last package release.
|
|||
<LatestPackageReference Include="System.Reflection.Metadata" />
|
||||
<LatestPackageReference Include="System.Runtime.CompilerServices.Unsafe" />
|
||||
<LatestPackageReference Include="System.Runtime.InteropServices.RuntimeInformation" />
|
||||
<!-- System.Security.AccessControl should only be referenced in Dependencies.props and RTMVersions.csproj. -->
|
||||
<LatestPackageReference Include="System.Security.AccessControl" />
|
||||
<LatestPackageReference Include="System.Security.Cryptography.Cng" />
|
||||
<LatestPackageReference Include="System.Security.Cryptography.Pkcs" />
|
||||
<LatestPackageReference Include="System.Security.Cryptography.Xml" />
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
<Project>
|
||||
<!-- Minimize what gets set to avoid useless references in this simple project. -->
|
||||
<Import Project="..\Common.props" />
|
||||
<Import Project="..\Versions.props" />
|
||||
<Import Project="..\Dependencies.props" />
|
||||
</Project>
|
||||
|
|
@ -1 +0,0 @@
|
|||
<Project />
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<!--
|
||||
Gather project references for compilation against RTM packages. %(RTMVersion) is set for about a dozen packages
|
||||
in all servicing builds. Cannot reference two versions of a package, mandating this separate package.
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
|
||||
<!-- Don't bother building anything here. We only need to ensure the RTM packages are on disk. -->
|
||||
<DebugType>none</DebugType>
|
||||
<IncludeBuildOutput>false</IncludeBuildOutput>
|
||||
<CopyBuildOutputToPublishDirectory>false</CopyBuildOutputToPublishDirectory>
|
||||
<CopyBuildOutputToOutputDirectory>false</CopyBuildOutputToOutputDirectory>
|
||||
<CopyOutputSymbolsToOutputDirectory>false</CopyOutputSymbolsToOutputDirectory>
|
||||
<GenerateDependencyFile>false</GenerateDependencyFile>
|
||||
|
||||
<!-- This project should not be referenced via the `<Reference>` implementation. -->
|
||||
<IsProjectReferenceProvider>false</IsProjectReferenceProvider>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="@(LatestPackageReference->HasMetadata('RTMVersion'))" Version="%(RTMVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Arcade SDK calls Test target on every project in the repo but provides an empty fallback. Do same here. -->
|
||||
<Target Name="Test" />
|
||||
</Project>
|
||||
|
|
@ -13,292 +13,297 @@
|
|||
<Uri>https://github.com/dotnet/blazor</Uri>
|
||||
<Sha>cc449601d638ffaab58ae9487f0fd010bb178a12</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="dotnet-ef" Version="5.0.0-preview.8.20360.8">
|
||||
<Dependency Name="dotnet-ef" Version="5.0.0-rc.1.20367.2">
|
||||
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||
<Sha>58abc390e0e3eb849b5773da3f5ed2982ade521d</Sha>
|
||||
<Sha>1aac0aec91bb6e5baa682450b7157331f2226173</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.InMemory" Version="5.0.0-preview.8.20360.8">
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.InMemory" Version="5.0.0-rc.1.20367.2">
|
||||
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||
<Sha>58abc390e0e3eb849b5773da3f5ed2982ade521d</Sha>
|
||||
<Sha>1aac0aec91bb6e5baa682450b7157331f2226173</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.Relational" Version="5.0.0-preview.8.20360.8">
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.Relational" Version="5.0.0-rc.1.20367.2">
|
||||
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||
<Sha>58abc390e0e3eb849b5773da3f5ed2982ade521d</Sha>
|
||||
<Sha>1aac0aec91bb6e5baa682450b7157331f2226173</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.0-preview.8.20360.8">
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.0-rc.1.20367.2">
|
||||
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||
<Sha>58abc390e0e3eb849b5773da3f5ed2982ade521d</Sha>
|
||||
<Sha>1aac0aec91bb6e5baa682450b7157331f2226173</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.0-preview.8.20360.8">
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.0-rc.1.20367.2">
|
||||
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||
<Sha>58abc390e0e3eb849b5773da3f5ed2982ade521d</Sha>
|
||||
<Sha>1aac0aec91bb6e5baa682450b7157331f2226173</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.Tools" Version="5.0.0-preview.8.20360.8">
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore.Tools" Version="5.0.0-rc.1.20367.2">
|
||||
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||
<Sha>58abc390e0e3eb849b5773da3f5ed2982ade521d</Sha>
|
||||
<Sha>1aac0aec91bb6e5baa682450b7157331f2226173</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore" Version="5.0.0-preview.8.20360.8">
|
||||
<Dependency Name="Microsoft.EntityFrameworkCore" Version="5.0.0-rc.1.20367.2">
|
||||
<Uri>https://github.com/dotnet/efcore</Uri>
|
||||
<Sha>58abc390e0e3eb849b5773da3f5ed2982ade521d</Sha>
|
||||
<Sha>1aac0aec91bb6e5baa682450b7157331f2226173</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Caching.Abstractions" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Caching.Abstractions" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Caching.Memory" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Caching.Memory" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Binder" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Binder" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.CommandLine" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.CommandLine" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.FileExtensions" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.FileExtensions" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Ini" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Ini" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Json" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Json" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.UserSecrets" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.UserSecrets" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Xml" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Xml" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.DependencyInjection" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.DependencyInjection" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Abstractions" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Abstractions" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Composite" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Composite" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Physical" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Physical" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.FileSystemGlobbing" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.FileSystemGlobbing" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.HostFactoryResolver.Sources" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.HostFactoryResolver.Sources" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Hosting" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Hosting" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Http" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Http" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Configuration" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Configuration" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Console" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Console" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Debug" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Debug" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.EventSource" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.EventSource" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.EventLog" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.EventLog" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.TraceSource" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.TraceSource" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Logging" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Options.DataAnnotations" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Options.DataAnnotations" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Options" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Options" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Primitives" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Primitives" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Internal.Transport" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.Internal.Transport" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Win32.Registry" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Win32.Registry" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Win32.SystemEvents" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Win32.SystemEvents" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.ComponentModel.Annotations" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.ComponentModel.Annotations" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Diagnostics.DiagnosticSource" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.Diagnostics.DiagnosticSource" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Diagnostics.EventLog" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.Diagnostics.EventLog" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Drawing.Common" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.Drawing.Common" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.IO.Pipelines" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.IO.Pipelines" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Net.Http.Json" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.Net.Http.Json" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Net.Http.WinHttpHandler" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.Net.Http.WinHttpHandler" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Net.WebSockets.WebSocketProtocol" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.Net.WebSockets.WebSocketProtocol" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Reflection.Metadata" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.Reflection.Metadata" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Resources.Extensions" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.Resources.Extensions" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Runtime.CompilerServices.Unsafe" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.Runtime.CompilerServices.Unsafe" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Security.Cryptography.Cng" Version="5.0.0-preview.8.20361.2">
|
||||
<!-- System.Security.AccessControl should only be referenced in Dependencies.props and RTMVersions.csproj. -->
|
||||
<Dependency Name="System.Security.AccessControl" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Security.Cryptography.Pkcs" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.Security.Cryptography.Cng" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Security.Cryptography.Xml" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.Security.Cryptography.Pkcs" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Security.Permissions" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.Security.Cryptography.Xml" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Security.Principal.Windows" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.Security.Permissions" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.ServiceProcess.ServiceController" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.Security.Principal.Windows" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Text.Encodings.Web" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.ServiceProcess.ServiceController" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Text.Json" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.Text.Encodings.Web" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Threading.Channels" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.Text.Json" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Windows.Extensions" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.Threading.Channels" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.DependencyModel" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="System.Windows.Extensions" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.NETCore.App.Ref" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.Extensions.DependencyModel" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.NETCore.App.Ref" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<!--
|
||||
Win-x64 is used here because we have picked an arbitrary runtime identifier to flow the version of the latest NETCore.App runtime.
|
||||
All Runtime.$rid packages should have the same version.
|
||||
-->
|
||||
<Dependency Name="Microsoft.NETCore.App.Runtime.win-x64" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.NETCore.App.Runtime.win-x64" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.NETCore.App.Internal" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.NETCore.App.Internal" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
</ProductDependencies>
|
||||
<ToolsetDependencies>
|
||||
<!-- Listed explicitly to workaround https://github.com/dotnet/cli/issues/10528 -->
|
||||
<Dependency Name="Microsoft.NETCore.Platforms" Version="5.0.0-preview.8.20361.2">
|
||||
<Dependency Name="Microsoft.NETCore.Platforms" Version="5.0.0-rc.1.20370.4">
|
||||
<Uri>https://github.com/dotnet/runtime</Uri>
|
||||
<Sha>f37dd6fc8595e130909dcb3085a56342d04aa20c</Sha>
|
||||
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="5.0.0-beta.20364.3">
|
||||
<Uri>https://github.com/dotnet/arcade</Uri>
|
||||
|
|
@ -308,9 +313,9 @@
|
|||
<Uri>https://github.com/dotnet/arcade</Uri>
|
||||
<Sha>ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Net.Compilers.Toolset" Version="3.8.0-1.20361.1">
|
||||
<Dependency Name="Microsoft.Net.Compilers.Toolset" Version="3.8.0-1.20367.11">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>f24d2c5c98211908ab90d6f1f42e7592411d6058</Sha>
|
||||
<Sha>fb7b2e716d163b7abebf57db505e01a4a521ddae</Sha>
|
||||
</Dependency>
|
||||
</ToolsetDependencies>
|
||||
</Dependencies>
|
||||
|
|
|
|||
|
|
@ -9,14 +9,14 @@
|
|||
<AspNetCoreMajorVersion>5</AspNetCoreMajorVersion>
|
||||
<AspNetCoreMinorVersion>0</AspNetCoreMinorVersion>
|
||||
<AspNetCorePatchVersion>0</AspNetCorePatchVersion>
|
||||
<PreReleaseVersionIteration>8</PreReleaseVersionIteration>
|
||||
<PreReleaseVersionIteration>1</PreReleaseVersionIteration>
|
||||
<!--
|
||||
When StabilizePackageVersion is set to 'true', this branch will produce stable outputs for 'Shipping' packages
|
||||
-->
|
||||
<StabilizePackageVersion Condition="'$(StabilizePackageVersion)' == ''">false</StabilizePackageVersion>
|
||||
<DotNetFinalVersionKind Condition="'$(StabilizePackageVersion)' == 'true'">release</DotNetFinalVersionKind>
|
||||
<PreReleaseVersionLabel>preview</PreReleaseVersionLabel>
|
||||
<PreReleaseBrandingLabel>Preview $(PreReleaseVersionIteration)</PreReleaseBrandingLabel>
|
||||
<PreReleaseVersionLabel>rc</PreReleaseVersionLabel>
|
||||
<PreReleaseBrandingLabel>RC $(PreReleaseVersionIteration)</PreReleaseBrandingLabel>
|
||||
<IncludePreReleaseLabelInPackageVersion>true</IncludePreReleaseLabelInPackageVersion>
|
||||
<IncludePreReleaseLabelInPackageVersion Condition=" '$(DotNetFinalVersionKind)' == 'release' ">false</IncludePreReleaseLabelInPackageVersion>
|
||||
<AspNetCoreMajorMinorVersion>$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion)</AspNetCoreMajorMinorVersion>
|
||||
|
|
@ -62,82 +62,84 @@
|
|||
-->
|
||||
<PropertyGroup Label="Automated">
|
||||
<!-- Packages from dotnet/roslyn -->
|
||||
<MicrosoftNetCompilersToolsetPackageVersion>3.8.0-1.20361.1</MicrosoftNetCompilersToolsetPackageVersion>
|
||||
<MicrosoftNetCompilersToolsetPackageVersion>3.8.0-1.20367.11</MicrosoftNetCompilersToolsetPackageVersion>
|
||||
<!-- Packages from dotnet/runtime -->
|
||||
<MicrosoftExtensionsDependencyModelPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsDependencyModelPackageVersion>
|
||||
<MicrosoftNETCoreAppInternalPackageVersion>5.0.0-preview.8.20361.2</MicrosoftNETCoreAppInternalPackageVersion>
|
||||
<MicrosoftNETCoreAppRefPackageVersion>5.0.0-preview.8.20361.2</MicrosoftNETCoreAppRefPackageVersion>
|
||||
<MicrosoftNETCoreAppRuntimewinx64PackageVersion>5.0.0-preview.8.20361.2</MicrosoftNETCoreAppRuntimewinx64PackageVersion>
|
||||
<MicrosoftWin32RegistryPackageVersion>5.0.0-preview.8.20361.2</MicrosoftWin32RegistryPackageVersion>
|
||||
<MicrosoftWin32SystemEventsPackageVersion>5.0.0-preview.8.20361.2</MicrosoftWin32SystemEventsPackageVersion>
|
||||
<MicrosoftExtensionsCachingAbstractionsPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsCachingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsCachingMemoryPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsCachingMemoryPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationAbstractionsPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsConfigurationAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationBinderPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsConfigurationBinderPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
|
||||
<MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationIniPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsConfigurationIniPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationJsonPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsConfigurationJsonPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsConfigurationPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationUserSecretsPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsConfigurationUserSecretsPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationXmlPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsConfigurationXmlPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersCompositePackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsFileProvidersCompositePackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
|
||||
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
|
||||
<MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>
|
||||
<MicrosoftExtensionsHostingAbstractionsPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsHostingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsHostingPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsHostingPackageVersion>
|
||||
<MicrosoftExtensionsHttpPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsHttpPackageVersion>
|
||||
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsLoggingConfigurationPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsLoggingConfigurationPackageVersion>
|
||||
<MicrosoftExtensionsLoggingConsolePackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsLoggingConsolePackageVersion>
|
||||
<MicrosoftExtensionsLoggingDebugPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsLoggingDebugPackageVersion>
|
||||
<MicrosoftExtensionsLoggingEventSourcePackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsLoggingEventSourcePackageVersion>
|
||||
<MicrosoftExtensionsLoggingEventLogPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsLoggingEventLogPackageVersion>
|
||||
<MicrosoftExtensionsLoggingPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsLoggingPackageVersion>
|
||||
<MicrosoftExtensionsLoggingTraceSourcePackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsLoggingTraceSourcePackageVersion>
|
||||
<MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>
|
||||
<MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>
|
||||
<MicrosoftExtensionsOptionsPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsOptionsPackageVersion>
|
||||
<MicrosoftExtensionsPrimitivesPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsPrimitivesPackageVersion>
|
||||
<MicrosoftExtensionsInternalTransportPackageVersion>5.0.0-preview.8.20361.2</MicrosoftExtensionsInternalTransportPackageVersion>
|
||||
<SystemComponentModelAnnotationsPackageVersion>5.0.0-preview.8.20361.2</SystemComponentModelAnnotationsPackageVersion>
|
||||
<SystemDiagnosticsDiagnosticSourcePackageVersion>5.0.0-preview.8.20361.2</SystemDiagnosticsDiagnosticSourcePackageVersion>
|
||||
<SystemDiagnosticsEventLogPackageVersion>5.0.0-preview.8.20361.2</SystemDiagnosticsEventLogPackageVersion>
|
||||
<SystemDrawingCommonPackageVersion>5.0.0-preview.8.20361.2</SystemDrawingCommonPackageVersion>
|
||||
<SystemIOPipelinesPackageVersion>5.0.0-preview.8.20361.2</SystemIOPipelinesPackageVersion>
|
||||
<SystemNetHttpJsonPackageVersion>5.0.0-preview.8.20361.2</SystemNetHttpJsonPackageVersion>
|
||||
<SystemNetHttpWinHttpHandlerPackageVersion>5.0.0-preview.8.20361.2</SystemNetHttpWinHttpHandlerPackageVersion>
|
||||
<SystemNetWebSocketsWebSocketProtocolPackageVersion>5.0.0-preview.8.20361.2</SystemNetWebSocketsWebSocketProtocolPackageVersion>
|
||||
<SystemReflectionMetadataPackageVersion>5.0.0-preview.8.20361.2</SystemReflectionMetadataPackageVersion>
|
||||
<SystemResourcesExtensionsPackageVersion>5.0.0-preview.8.20361.2</SystemResourcesExtensionsPackageVersion>
|
||||
<SystemRuntimeCompilerServicesUnsafePackageVersion>5.0.0-preview.8.20361.2</SystemRuntimeCompilerServicesUnsafePackageVersion>
|
||||
<SystemSecurityCryptographyCngPackageVersion>5.0.0-preview.8.20361.2</SystemSecurityCryptographyCngPackageVersion>
|
||||
<SystemSecurityCryptographyPkcsPackageVersion>5.0.0-preview.8.20361.2</SystemSecurityCryptographyPkcsPackageVersion>
|
||||
<SystemSecurityCryptographyXmlPackageVersion>5.0.0-preview.8.20361.2</SystemSecurityCryptographyXmlPackageVersion>
|
||||
<SystemSecurityPermissionsPackageVersion>5.0.0-preview.8.20361.2</SystemSecurityPermissionsPackageVersion>
|
||||
<SystemSecurityPrincipalWindowsPackageVersion>5.0.0-preview.8.20361.2</SystemSecurityPrincipalWindowsPackageVersion>
|
||||
<SystemServiceProcessServiceControllerPackageVersion>5.0.0-preview.8.20361.2</SystemServiceProcessServiceControllerPackageVersion>
|
||||
<SystemTextEncodingsWebPackageVersion>5.0.0-preview.8.20361.2</SystemTextEncodingsWebPackageVersion>
|
||||
<SystemTextJsonPackageVersion>5.0.0-preview.8.20361.2</SystemTextJsonPackageVersion>
|
||||
<SystemThreadingChannelsPackageVersion>5.0.0-preview.8.20361.2</SystemThreadingChannelsPackageVersion>
|
||||
<SystemWindowsExtensionsPackageVersion>5.0.0-preview.8.20361.2</SystemWindowsExtensionsPackageVersion>
|
||||
<MicrosoftExtensionsDependencyModelPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsDependencyModelPackageVersion>
|
||||
<MicrosoftNETCoreAppInternalPackageVersion>5.0.0-rc.1.20370.4</MicrosoftNETCoreAppInternalPackageVersion>
|
||||
<MicrosoftNETCoreAppRefPackageVersion>5.0.0-rc.1.20370.4</MicrosoftNETCoreAppRefPackageVersion>
|
||||
<MicrosoftNETCoreAppRuntimewinx64PackageVersion>5.0.0-rc.1.20370.4</MicrosoftNETCoreAppRuntimewinx64PackageVersion>
|
||||
<MicrosoftWin32RegistryPackageVersion>5.0.0-rc.1.20370.4</MicrosoftWin32RegistryPackageVersion>
|
||||
<MicrosoftWin32SystemEventsPackageVersion>5.0.0-rc.1.20370.4</MicrosoftWin32SystemEventsPackageVersion>
|
||||
<MicrosoftExtensionsCachingAbstractionsPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsCachingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsCachingMemoryPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsCachingMemoryPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationAbstractionsPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsConfigurationAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationBinderPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsConfigurationBinderPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
|
||||
<MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationIniPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsConfigurationIniPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationJsonPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsConfigurationJsonPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsConfigurationPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationUserSecretsPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsConfigurationUserSecretsPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationXmlPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsConfigurationXmlPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersCompositePackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsFileProvidersCompositePackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
|
||||
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
|
||||
<MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>
|
||||
<MicrosoftExtensionsHostingAbstractionsPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsHostingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsHostingPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsHostingPackageVersion>
|
||||
<MicrosoftExtensionsHttpPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsHttpPackageVersion>
|
||||
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsLoggingConfigurationPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsLoggingConfigurationPackageVersion>
|
||||
<MicrosoftExtensionsLoggingConsolePackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsLoggingConsolePackageVersion>
|
||||
<MicrosoftExtensionsLoggingDebugPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsLoggingDebugPackageVersion>
|
||||
<MicrosoftExtensionsLoggingEventSourcePackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsLoggingEventSourcePackageVersion>
|
||||
<MicrosoftExtensionsLoggingEventLogPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsLoggingEventLogPackageVersion>
|
||||
<MicrosoftExtensionsLoggingPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsLoggingPackageVersion>
|
||||
<MicrosoftExtensionsLoggingTraceSourcePackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsLoggingTraceSourcePackageVersion>
|
||||
<MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>
|
||||
<MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>
|
||||
<MicrosoftExtensionsOptionsPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsOptionsPackageVersion>
|
||||
<MicrosoftExtensionsPrimitivesPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsPrimitivesPackageVersion>
|
||||
<MicrosoftExtensionsInternalTransportPackageVersion>5.0.0-rc.1.20370.4</MicrosoftExtensionsInternalTransportPackageVersion>
|
||||
<SystemComponentModelAnnotationsPackageVersion>5.0.0-rc.1.20370.4</SystemComponentModelAnnotationsPackageVersion>
|
||||
<SystemDiagnosticsDiagnosticSourcePackageVersion>5.0.0-rc.1.20370.4</SystemDiagnosticsDiagnosticSourcePackageVersion>
|
||||
<SystemDiagnosticsEventLogPackageVersion>5.0.0-rc.1.20370.4</SystemDiagnosticsEventLogPackageVersion>
|
||||
<SystemDrawingCommonPackageVersion>5.0.0-rc.1.20370.4</SystemDrawingCommonPackageVersion>
|
||||
<SystemIOPipelinesPackageVersion>5.0.0-rc.1.20370.4</SystemIOPipelinesPackageVersion>
|
||||
<SystemNetHttpJsonPackageVersion>5.0.0-rc.1.20370.4</SystemNetHttpJsonPackageVersion>
|
||||
<SystemNetHttpWinHttpHandlerPackageVersion>5.0.0-rc.1.20370.4</SystemNetHttpWinHttpHandlerPackageVersion>
|
||||
<SystemNetWebSocketsWebSocketProtocolPackageVersion>5.0.0-rc.1.20370.4</SystemNetWebSocketsWebSocketProtocolPackageVersion>
|
||||
<SystemReflectionMetadataPackageVersion>5.0.0-rc.1.20370.4</SystemReflectionMetadataPackageVersion>
|
||||
<SystemResourcesExtensionsPackageVersion>5.0.0-rc.1.20370.4</SystemResourcesExtensionsPackageVersion>
|
||||
<SystemRuntimeCompilerServicesUnsafePackageVersion>5.0.0-rc.1.20370.4</SystemRuntimeCompilerServicesUnsafePackageVersion>
|
||||
<!-- System.Security.AccessControl should only be referenced in Dependencies.props and RTMVersions.csproj. -->
|
||||
<SystemSecurityAccessControlPackageVersion>5.0.0-rc.1.20370.4</SystemSecurityAccessControlPackageVersion>
|
||||
<SystemSecurityCryptographyCngPackageVersion>5.0.0-rc.1.20370.4</SystemSecurityCryptographyCngPackageVersion>
|
||||
<SystemSecurityCryptographyPkcsPackageVersion>5.0.0-rc.1.20370.4</SystemSecurityCryptographyPkcsPackageVersion>
|
||||
<SystemSecurityCryptographyXmlPackageVersion>5.0.0-rc.1.20370.4</SystemSecurityCryptographyXmlPackageVersion>
|
||||
<SystemSecurityPermissionsPackageVersion>5.0.0-rc.1.20370.4</SystemSecurityPermissionsPackageVersion>
|
||||
<SystemSecurityPrincipalWindowsPackageVersion>5.0.0-rc.1.20370.4</SystemSecurityPrincipalWindowsPackageVersion>
|
||||
<SystemServiceProcessServiceControllerPackageVersion>5.0.0-rc.1.20370.4</SystemServiceProcessServiceControllerPackageVersion>
|
||||
<SystemTextEncodingsWebPackageVersion>5.0.0-rc.1.20370.4</SystemTextEncodingsWebPackageVersion>
|
||||
<SystemTextJsonPackageVersion>5.0.0-rc.1.20370.4</SystemTextJsonPackageVersion>
|
||||
<SystemThreadingChannelsPackageVersion>5.0.0-rc.1.20370.4</SystemThreadingChannelsPackageVersion>
|
||||
<SystemWindowsExtensionsPackageVersion>5.0.0-rc.1.20370.4</SystemWindowsExtensionsPackageVersion>
|
||||
<!-- Only listed explicitly to workaround https://github.com/dotnet/cli/issues/10528 -->
|
||||
<MicrosoftNETCorePlatformsPackageVersion>5.0.0-preview.8.20361.2</MicrosoftNETCorePlatformsPackageVersion>
|
||||
<MicrosoftNETCorePlatformsPackageVersion>5.0.0-rc.1.20370.4</MicrosoftNETCorePlatformsPackageVersion>
|
||||
<!-- Packages from dotnet/blazor -->
|
||||
<MicrosoftAspNetCoreComponentsWebAssemblyRuntimePackageVersion>3.2.0</MicrosoftAspNetCoreComponentsWebAssemblyRuntimePackageVersion>
|
||||
<!-- Packages from dotnet/efcore -->
|
||||
<dotnetefPackageVersion>5.0.0-preview.8.20360.8</dotnetefPackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreInMemoryPackageVersion>5.0.0-preview.8.20360.8</MicrosoftEntityFrameworkCoreInMemoryPackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreRelationalPackageVersion>5.0.0-preview.8.20360.8</MicrosoftEntityFrameworkCoreRelationalPackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreSqlitePackageVersion>5.0.0-preview.8.20360.8</MicrosoftEntityFrameworkCoreSqlitePackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreSqlServerPackageVersion>5.0.0-preview.8.20360.8</MicrosoftEntityFrameworkCoreSqlServerPackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreToolsPackageVersion>5.0.0-preview.8.20360.8</MicrosoftEntityFrameworkCoreToolsPackageVersion>
|
||||
<MicrosoftEntityFrameworkCorePackageVersion>5.0.0-preview.8.20360.8</MicrosoftEntityFrameworkCorePackageVersion>
|
||||
<dotnetefPackageVersion>5.0.0-rc.1.20367.2</dotnetefPackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreInMemoryPackageVersion>5.0.0-rc.1.20367.2</MicrosoftEntityFrameworkCoreInMemoryPackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreRelationalPackageVersion>5.0.0-rc.1.20367.2</MicrosoftEntityFrameworkCoreRelationalPackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreSqlitePackageVersion>5.0.0-rc.1.20367.2</MicrosoftEntityFrameworkCoreSqlitePackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreSqlServerPackageVersion>5.0.0-rc.1.20367.2</MicrosoftEntityFrameworkCoreSqlServerPackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreToolsPackageVersion>5.0.0-rc.1.20367.2</MicrosoftEntityFrameworkCoreToolsPackageVersion>
|
||||
<MicrosoftEntityFrameworkCorePackageVersion>5.0.0-rc.1.20367.2</MicrosoftEntityFrameworkCorePackageVersion>
|
||||
</PropertyGroup>
|
||||
<!--
|
||||
|
||||
|
|
@ -155,7 +157,6 @@
|
|||
-->
|
||||
<MicrosoftNETCoreAppRuntimeVersion>$(MicrosoftNETCoreAppRuntimewinx64PackageVersion)</MicrosoftNETCoreAppRuntimeVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<!--
|
||||
We ship ref/ assemblies for runtime packages in our targeting targeting pack. When servicing that targeting pack,
|
||||
these assemblies must not change. Must also compile our assemblies against the initial ref/ assemblies for runtime
|
||||
|
|
@ -163,6 +164,14 @@
|
|||
Upshot is we need Major.Minor.0 runtime packages for compilation and the targeting pack and Major.Minor.Latest
|
||||
runtime packages for everything else. This is not an issue for assemblies available in Microsoft.NETCore.App.Ref or
|
||||
Microsoft.Extensions.Internal.Transport because it is next to impossible we would service those packages.
|
||||
|
||||
System.Security.AccessControl should only be referenced in Dependencies.props and RTMVersions.csproj. Because
|
||||
it's a transitive reference, we reship the ref/ assembly in Microsoft.AspNetCore.App.Ref. dotnet/runtime ships
|
||||
the implementation assemblies in Microsoft.NETCore.App.Runtime.* packages.
|
||||
|
||||
If testing this configuration prior to servicing, update the versions of dependencies too. E.g. change
|
||||
`$(SystemSecurityPrincipalWindowsV0PackageVersion)` if you change `$(SystemSecurityAccessControlV0PackageVersion)`
|
||||
because System.Security.AccessControl will otherwise be loadable. This should not be necessary in servicing.
|
||||
-->
|
||||
<PropertyGroup Condition=" '$(IsServicingBuild)' == 'true' ">
|
||||
<MicrosoftWin32RegistryV0PackageVersion>$(MicrosoftWin32RegistryPackageVersion.Split('.')[0]).$(MicrosoftWin32RegistryPackageVersion.Split('.')[1]).0</MicrosoftWin32RegistryV0PackageVersion>
|
||||
|
|
@ -178,7 +187,6 @@
|
|||
<SystemSecurityPrincipalWindowsV0PackageVersion>$(SystemSecurityPrincipalWindowsPackageVersion.Split('.')[0]).$(SystemSecurityPrincipalWindowsPackageVersion.Split('.')[1]).0</SystemSecurityPrincipalWindowsV0PackageVersion>
|
||||
<SystemWindowsExtensionsV0PackageVersion>$(SystemWindowsExtensionsPackageVersion.Split('.')[0]).$(SystemWindowsExtensionsPackageVersion.Split('.')[1]).0</SystemWindowsExtensionsV0PackageVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="Manual">
|
||||
<!-- DiagnosticAdapter package pinned temporarily until migrated/deprecated -->
|
||||
<MicrosoftExtensionsDiagnosticAdapterPackageVersion>5.0.0-preview.4.20180.4</MicrosoftExtensionsDiagnosticAdapterPackageVersion>
|
||||
|
|
@ -252,9 +260,6 @@
|
|||
<MonoCecilPackageVersion>0.11.2</MonoCecilPackageVersion>
|
||||
<NewtonsoftJsonBsonPackageVersion>1.0.2</NewtonsoftJsonBsonPackageVersion>
|
||||
<NewtonsoftJsonPackageVersion>12.0.2</NewtonsoftJsonPackageVersion>
|
||||
<!-- Begin: STOP!!! Razor need to reference the version of JSON that our HOSTS support. -->
|
||||
<Razor_NewtonsoftJsonPackageVersion>9.0.1</Razor_NewtonsoftJsonPackageVersion>
|
||||
<!-- End: STOP!!! Razor need to reference the version of JSON that our HOSTS support. -->
|
||||
<NSwagApiDescriptionClientPackageVersion>13.0.4</NSwagApiDescriptionClientPackageVersion>
|
||||
<SeleniumSupportPackageVersion>3.12.1</SeleniumSupportPackageVersion>
|
||||
<SeleniumWebDriverMicrosoftDriverPackageVersion>17.17134.0</SeleniumWebDriverMicrosoftDriverPackageVersion>
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@
|
|||
</Target>
|
||||
|
||||
<!--
|
||||
This target resolves remaining Referene items to Packages, if possible. If not, they are left as Reference items fo the SDK to resolve.
|
||||
This target resolves remaining Reference items to Packages, if possible. If not, they are left as Reference items fo the SDK to resolve.
|
||||
This executes on NuGet restore and during DesignTimeBuild. It should not run in the outer, cross-targeting build.
|
||||
-->
|
||||
<Target Name="ResolveCustomReferences"
|
||||
|
|
@ -205,21 +205,23 @@
|
|||
</Target>
|
||||
|
||||
<!--
|
||||
Muck with @(ResolvedCompileFileDefinitions) items between generation and use in order to compile against RTM lib/
|
||||
Change @(ResolvedCompileFileDefinitions) items between generation and use in order to compile against RTM lib/
|
||||
or ref/ assemblies. The approach works for all TFMs because it happens after a specific assembly is chosen for
|
||||
compilation; no need to restrict this to (say) the default TFM.
|
||||
|
||||
Condition checks for RTMVersions.csproj.nuget.g.props file only to ensure restore operation is complete.
|
||||
|
||||
This target could get confused if the layout changes for one of the dozen special-cased packages during servicing.
|
||||
E.g. ResolvePackageAssets picks a compatible assembly from the 5.0.1 package and _UseRTMReferenceAssemblies
|
||||
changes the path to one not present in the 5.0.0 package. Fortunately, this will break the build with complaints
|
||||
about the "invalid strong name".
|
||||
-->
|
||||
<Target Name="_UseRTMReferenceAssemblies"
|
||||
Condition=" '$(EnableCustomReferenceResolution)' == 'true' AND EXISTS('$(RepoRoot)eng\RTMVersions\obj\RTMVersions.csproj.nuget.g.props') "
|
||||
Condition=" '$(MSBuildProjectName)' != 'RepoTasks' "
|
||||
AfterTargets="ResolvePackageAssets"
|
||||
BeforeTargets="GenerateBuildDependencyFile;GeneratePublishDependencyFile;ILLink;ResolveLockFileReferences"
|
||||
DependsOnTargets="ResolvePackageAssets">
|
||||
<Error Condition=" !EXISTS('$(RepoRoot)artifacts\obj\RepoTasks\RepoTasks.csproj.nuget.g.props') "
|
||||
Text="The eng/tools/RepoTasks project must be restored before building other projects." />
|
||||
|
||||
<JoinItems Left="@(ResolvedCompileFileDefinitions)"
|
||||
Right="@(LatestPackageReference->HasMetadata('RTMVersion'))"
|
||||
LeftKey="Filename"
|
||||
|
|
|
|||
|
|
@ -36,5 +36,15 @@
|
|||
<Reference Include="Microsoft.Deployment.WindowsInstaller.Package">
|
||||
<HintPath>$(WiXSdkPath)\Microsoft.Deployment.WindowsInstaller.Package.dll</HintPath>
|
||||
</Reference>
|
||||
|
||||
<!--
|
||||
Gather project references for compilation against RTM packages. %(RTMVersion) is set for about a dozen packages
|
||||
in all servicing builds. Cannot reference two versions of a package, mandating this separation from projects
|
||||
using the relevant packages.
|
||||
-->
|
||||
<PackageReference Include="@(LatestPackageReference->HasMetadata('RTMVersion'))"
|
||||
IncludeAssets="None"
|
||||
PrivateAssets="All"
|
||||
Version="%(RTMVersion)" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ namespace A.Internal.Namespace
|
|||
|
||||
[Theory]
|
||||
[MemberData(nameof(PublicMemberDefinitions))]
|
||||
[QuarantinedTest]
|
||||
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/22440")]
|
||||
public async Task PublicExposureOfPubternalTypeProducesPUB0001(string member)
|
||||
{
|
||||
var code = GetSourceFromNamespaceDeclaration($@"
|
||||
|
|
|
|||
|
|
@ -54,6 +54,12 @@ namespace Microsoft.AspNetCore.Components.Authorization
|
|||
[Parameter]
|
||||
public RenderFragment Authorizing { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The resource to which access is being controlled.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public object Resource { get; set; }
|
||||
|
||||
[CascadingParameter]
|
||||
private Task<AuthenticationState> ExistingCascadedAuthenticationState { get; set; }
|
||||
|
||||
|
|
@ -82,6 +88,7 @@ namespace Microsoft.AspNetCore.Components.Authorization
|
|||
builder.AddAttribute(2, nameof(AuthorizeRouteViewCore.Authorized), _renderAuthorizedDelegate);
|
||||
builder.AddAttribute(3, nameof(AuthorizeRouteViewCore.Authorizing), _renderAuthorizingDelegate);
|
||||
builder.AddAttribute(4, nameof(AuthorizeRouteViewCore.NotAuthorized), _renderNotAuthorizedDelegate);
|
||||
builder.AddAttribute(5, nameof(AuthorizeRouteViewCore.Resource), Resource);
|
||||
builder.CloseComponent();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,78 @@ namespace Microsoft.AspNetCore.Components.Authorization
|
|||
edit => AssertPrependText(batch, edit, "Hello from the page with message: Hello, world!"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AuthorizesWhenResourceIsSet()
|
||||
{
|
||||
// Arrange
|
||||
var routeData = new RouteData(typeof(TestPageRequiringAuthorization), new Dictionary<string, object>
|
||||
{
|
||||
{ nameof(TestPageRequiringAuthorization.Message), "Hello, world!" }
|
||||
});
|
||||
var resource = "foo";
|
||||
_testAuthorizationService.NextResult = AuthorizationResult.Success();
|
||||
|
||||
// Act
|
||||
_renderer.RenderRootComponent(_authorizeRouteViewComponentId, ParameterView.FromDictionary(new Dictionary<string, object>
|
||||
{
|
||||
{ nameof(AuthorizeRouteView.RouteData), routeData },
|
||||
{ nameof(AuthorizeRouteView.DefaultLayout), typeof(TestLayout) },
|
||||
{ nameof(AuthorizeRouteView.Resource), resource }
|
||||
}));
|
||||
|
||||
// Assert: renders layout
|
||||
var batch = _renderer.Batches.Single();
|
||||
var layoutDiff = batch.GetComponentDiffs<TestLayout>().Single();
|
||||
Assert.Collection(layoutDiff.Edits,
|
||||
edit => AssertPrependText(batch, edit, "Layout starts here"),
|
||||
edit =>
|
||||
{
|
||||
Assert.Equal(RenderTreeEditType.PrependFrame, edit.Type);
|
||||
AssertFrame.Component<TestPageRequiringAuthorization>(batch.ReferenceFrames[edit.ReferenceFrameIndex]);
|
||||
},
|
||||
edit => AssertPrependText(batch, edit, "Layout ends here"));
|
||||
|
||||
// Assert: renders page
|
||||
var pageDiff = batch.GetComponentDiffs<TestPageRequiringAuthorization>().Single();
|
||||
Assert.Collection(pageDiff.Edits,
|
||||
edit => AssertPrependText(batch, edit, "Hello from the page with message: Hello, world!"));
|
||||
|
||||
// Assert: Asserts that the Resource is present and set to "foo"
|
||||
Assert.Collection(_testAuthorizationService.AuthorizeCalls, call=>
|
||||
{
|
||||
Assert.Equal(resource, call.resource.ToString());
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NotAuthorizedWhenResourceMissing()
|
||||
{
|
||||
// Arrange
|
||||
var routeData = new RouteData(typeof(TestPageRequiringAuthorization), EmptyParametersDictionary);
|
||||
_testAuthorizationService.NextResult = AuthorizationResult.Failed();
|
||||
|
||||
// Act
|
||||
_renderer.RenderRootComponent(_authorizeRouteViewComponentId, ParameterView.FromDictionary(new Dictionary<string, object>
|
||||
{
|
||||
{ nameof(AuthorizeRouteView.RouteData), routeData },
|
||||
{ nameof(AuthorizeRouteView.DefaultLayout), typeof(TestLayout) },
|
||||
}));
|
||||
|
||||
// Assert: renders layout containing "not authorized" message
|
||||
var batch = _renderer.Batches.Single();
|
||||
var layoutDiff = batch.GetComponentDiffs<TestLayout>().Single();
|
||||
Assert.Collection(layoutDiff.Edits,
|
||||
edit => AssertPrependText(batch, edit, "Layout starts here"),
|
||||
edit => AssertPrependText(batch, edit, "Not authorized"),
|
||||
edit => AssertPrependText(batch, edit, "Layout ends here"));
|
||||
|
||||
// Assert: Asserts that the Resource is Null
|
||||
Assert.Collection(_testAuthorizationService.AuthorizeCalls, call=>
|
||||
{
|
||||
Assert.Null(call.resource);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenNotAuthorized_RendersDefaultNotAuthorizedContentInsideLayout()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -61,6 +61,13 @@ namespace Microsoft.AspNetCore.Components
|
|||
return Receiver.HandleEventAsync(new EventCallbackWorkItem(Delegate), arg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the delegate associated with this binding and dispatches an event notification to the
|
||||
/// appropriate component.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="Task"/> which completes asynchronously once event processing has completed.</returns>
|
||||
public Task InvokeAsync() => InvokeAsync(null!);
|
||||
|
||||
object? IEventCallback.UnpackForRenderTree()
|
||||
{
|
||||
return RequiresExplicitReceiver ? (object)this : Delegate;
|
||||
|
|
|
|||
|
|
@ -56,6 +56,13 @@ namespace Microsoft.AspNetCore.Components
|
|||
return Receiver.HandleEventAsync(new EventCallbackWorkItem(Delegate), arg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the delegate associated with this binding and dispatches an event notification to the
|
||||
/// appropriate component.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="Task"/> which completes asynchronously once event processing has completed.</returns>
|
||||
public Task InvokeAsync() => InvokeAsync(default!);
|
||||
|
||||
internal EventCallback AsUntyped()
|
||||
{
|
||||
return new EventCallback(Receiver ?? Delegate?.Target as IHandleEvent, Delegate);
|
||||
|
|
|
|||
|
|
@ -498,6 +498,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
{
|
||||
ProcessRenderQueue();
|
||||
}
|
||||
|
||||
ComponentsProfiling.Instance.End();
|
||||
}
|
||||
|
||||
|
|
@ -634,11 +635,43 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
|||
var disposeComponentId = _batchBuilder.ComponentDisposalQueue.Dequeue();
|
||||
var disposeComponentState = GetRequiredComponentState(disposeComponentId);
|
||||
Log.DisposingComponent(_logger, disposeComponentState);
|
||||
if (!disposeComponentState.TryDisposeInBatch(_batchBuilder, out var exception))
|
||||
if (!(disposeComponentState.Component is IAsyncDisposable))
|
||||
{
|
||||
exceptions ??= new List<Exception>();
|
||||
exceptions.Add(exception);
|
||||
if (!disposeComponentState.TryDisposeInBatch(_batchBuilder, out var exception))
|
||||
{
|
||||
exceptions ??= new List<Exception>();
|
||||
exceptions.Add(exception);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = disposeComponentState.DisposeInBatchAsync(_batchBuilder);
|
||||
if (result.IsCompleted)
|
||||
{
|
||||
if (!result.IsCompletedSuccessfully)
|
||||
{
|
||||
exceptions ??= new List<Exception>();
|
||||
exceptions.Add(result.Exception);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddToPendingTasks(GetHandledAsynchronousDisposalErrorsTask(result));
|
||||
|
||||
async Task GetHandledAsynchronousDisposalErrorsTask(Task result)
|
||||
{
|
||||
try
|
||||
{
|
||||
await result;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
HandleException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_componentStateById.Remove(disposeComponentId);
|
||||
_batchBuilder.DisposedComponentIds.Append(disposeComponentId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,6 +101,13 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
exception = ex;
|
||||
}
|
||||
|
||||
CleanupComponentStateResources(batchBuilder);
|
||||
|
||||
return exception == null;
|
||||
}
|
||||
|
||||
private void CleanupComponentStateResources(RenderBatchBuilder batchBuilder)
|
||||
{
|
||||
// We don't expect these things to throw.
|
||||
RenderTreeDiffBuilder.DisposeFrames(batchBuilder, CurrentRenderTree.GetFrames());
|
||||
|
||||
|
|
@ -110,8 +117,6 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
}
|
||||
|
||||
DisposeBuffers();
|
||||
|
||||
return exception == null;
|
||||
}
|
||||
|
||||
// Callers expect this method to always return a faulted task.
|
||||
|
|
@ -222,5 +227,31 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
((IDisposable)CurrentRenderTree).Dispose();
|
||||
_latestDirectParametersSnapshot?.Dispose();
|
||||
}
|
||||
|
||||
public Task DisposeInBatchAsync(RenderBatchBuilder batchBuilder)
|
||||
{
|
||||
_componentWasDisposed = true;
|
||||
|
||||
CleanupComponentStateResources(batchBuilder);
|
||||
|
||||
try
|
||||
{
|
||||
var result = ((IAsyncDisposable)Component).DisposeAsync();
|
||||
if (result.IsCompletedSuccessfully)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We know we are dealing with an exception that happened asynchronously, so return a task
|
||||
// to the caller so that he can unwrap it.
|
||||
return result.AsTask();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return Task.FromException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Components.Routing
|
|||
public override bool Match(string pathSegment, out object? convertedValue)
|
||||
{
|
||||
// Unset values are set to null in the Parameters object created in
|
||||
// the RouteContext. To match this pattern, unset optional parmeters
|
||||
// the RouteContext. To match this pattern, unset optional parameters
|
||||
// are converted to null.
|
||||
if (string.IsNullOrEmpty(pathSegment))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,10 +29,20 @@ namespace Microsoft.AspNetCore.Components.Routing
|
|||
|
||||
internal void Match(RouteContext context)
|
||||
{
|
||||
string? catchAllValue = null;
|
||||
|
||||
// If this template contains a catch-all parameter, we can concatenate the pathSegments
|
||||
// at and beyond the catch-all segment's position. For example:
|
||||
// Template: /foo/bar/{*catchAll}
|
||||
// PathSegments: /foo/bar/one/two/three
|
||||
if (Template.ContainsCatchAllSegment && context.Segments.Length >= Template.Segments.Length)
|
||||
{
|
||||
catchAllValue = string.Join('/', context.Segments[Range.StartAt(Template.Segments.Length - 1)]);
|
||||
}
|
||||
// If there are no optional segments on the route and the length of the route
|
||||
// and the template do not match, then there is no chance of this matching and
|
||||
// we can bail early.
|
||||
if (Template.OptionalSegmentsCount == 0 && Template.Segments.Length != context.Segments.Length)
|
||||
else if (Template.OptionalSegmentsCount == 0 && Template.Segments.Length != context.Segments.Length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -43,7 +53,15 @@ namespace Microsoft.AspNetCore.Components.Routing
|
|||
for (var i = 0; i < Template.Segments.Length; i++)
|
||||
{
|
||||
var segment = Template.Segments[i];
|
||||
|
||||
|
||||
if (segment.IsCatchAll)
|
||||
{
|
||||
numMatchingSegments += 1;
|
||||
parameters ??= new Dictionary<string, object>(StringComparer.Ordinal);
|
||||
parameters[segment.Value] = catchAllValue;
|
||||
break;
|
||||
}
|
||||
|
||||
// If the template contains more segments than the path, then
|
||||
// we may need to break out of this for-loop. This can happen
|
||||
// in one of two cases:
|
||||
|
|
@ -86,7 +104,7 @@ namespace Microsoft.AspNetCore.Components.Routing
|
|||
// In addition to extracting parameter values from the URL, each route entry
|
||||
// also knows which other parameters should be supplied with null values. These
|
||||
// are parameters supplied by other route entries matching the same handler.
|
||||
if (UnusedRouteParameterNames.Length > 0)
|
||||
if (!Template.ContainsCatchAllSegment && UnusedRouteParameterNames.Length > 0)
|
||||
{
|
||||
parameters ??= new Dictionary<string, object>(StringComparer.Ordinal);
|
||||
for (var i = 0; i < UnusedRouteParameterNames.Length; i++)
|
||||
|
|
@ -116,7 +134,7 @@ namespace Microsoft.AspNetCore.Components.Routing
|
|||
// `/this/is/a/template` and the route `/this/`. In that case, we want to ensure
|
||||
// that all non-optional segments have matched as well.
|
||||
var allNonOptionalSegmentsMatch = numMatchingSegments >= (Template.Segments.Length - Template.OptionalSegmentsCount);
|
||||
if (allRouteSegmentsMatch && allNonOptionalSegmentsMatch)
|
||||
if (Template.ContainsCatchAllSegment || (allRouteSegmentsMatch && allNonOptionalSegmentsMatch))
|
||||
{
|
||||
context.Parameters = parameters;
|
||||
context.Handler = Handler;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ namespace Microsoft.AspNetCore.Components.Routing
|
|||
TemplateText = templateText;
|
||||
Segments = segments;
|
||||
OptionalSegmentsCount = segments.Count(template => template.IsOptional);
|
||||
ContainsCatchAllSegment = segments.Any(template => template.IsCatchAll);
|
||||
}
|
||||
|
||||
public string TemplateText { get; }
|
||||
|
|
@ -22,5 +23,7 @@ namespace Microsoft.AspNetCore.Components.Routing
|
|||
public TemplateSegment[] Segments { get; }
|
||||
|
||||
public int OptionalSegmentsCount { get; }
|
||||
|
||||
public bool ContainsCatchAllSegment { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,15 +12,15 @@ namespace Microsoft.AspNetCore.Components.Routing
|
|||
// The class in here just takes care of parsing a route and extracting
|
||||
// simple parameters from it.
|
||||
// Some differences with ASP.NET Core routes are:
|
||||
// * We don't support catch all parameter segments.
|
||||
// * We don't support complex segments.
|
||||
// The things that we support are:
|
||||
// * Literal path segments. (Like /Path/To/Some/Page)
|
||||
// * Parameter path segments (Like /Customer/{Id}/Orders/{OrderId})
|
||||
// * Catch-all parameters (Like /blog/{*slug})
|
||||
internal class TemplateParser
|
||||
{
|
||||
public static readonly char[] InvalidParameterNameCharacters =
|
||||
new char[] { '*', '{', '}', '=', '.' };
|
||||
new char[] { '{', '}', '=', '.' };
|
||||
|
||||
internal static RouteTemplate ParseTemplate(string template)
|
||||
{
|
||||
|
|
@ -80,6 +80,12 @@ namespace Microsoft.AspNetCore.Components.Routing
|
|||
for (int i = 0; i < templateSegments.Length; i++)
|
||||
{
|
||||
var currentSegment = templateSegments[i];
|
||||
|
||||
if (currentSegment.IsCatchAll && i != templateSegments.Length - 1)
|
||||
{
|
||||
throw new InvalidOperationException($"Invalid template '{template}'. A catch-all parameter can only appear as the last segment of the route template.");
|
||||
}
|
||||
|
||||
if (!currentSegment.IsParameter)
|
||||
{
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -12,34 +12,48 @@ namespace Microsoft.AspNetCore.Components.Routing
|
|||
{
|
||||
IsParameter = isParameter;
|
||||
|
||||
IsCatchAll = segment.StartsWith('*');
|
||||
|
||||
if (IsCatchAll)
|
||||
{
|
||||
// Only one '*' currently allowed
|
||||
Value = segment.Substring(1);
|
||||
|
||||
var invalidCharacter = Value.IndexOf('*');
|
||||
if (Value.IndexOf('*') != -1)
|
||||
{
|
||||
throw new InvalidOperationException($"Invalid template '{template}'. A catch-all parameter may only have one '*' at the beginning of the segment.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Value = segment;
|
||||
}
|
||||
|
||||
// Process segments that are not parameters or do not contain
|
||||
// a token separating a type constraint.
|
||||
if (!isParameter || segment.IndexOf(':') < 0)
|
||||
if (!isParameter || Value.IndexOf(':') < 0)
|
||||
{
|
||||
// Set the IsOptional flag to true for segments that contain
|
||||
// a parameter with no type constraints but optionality set
|
||||
// via the '?' token.
|
||||
if (segment.IndexOf('?') == segment.Length - 1)
|
||||
if (Value.IndexOf('?') == Value.Length - 1)
|
||||
{
|
||||
IsOptional = true;
|
||||
Value = segment.Substring(0, segment.Length - 1);
|
||||
Value = Value.Substring(0, Value.Length - 1);
|
||||
}
|
||||
// If the `?` optional marker shows up in the segment but not at the very end,
|
||||
// then throw an error.
|
||||
else if (segment.IndexOf('?') >= 0 && segment.IndexOf('?') != segment.Length - 1)
|
||||
else if (Value.IndexOf('?') >= 0 && Value.IndexOf('?') != Value.Length - 1)
|
||||
{
|
||||
throw new ArgumentException($"Malformed parameter '{segment}' in route '{template}'. '?' character can only appear at the end of parameter name.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Value = segment;
|
||||
}
|
||||
|
||||
|
||||
Constraints = Array.Empty<RouteConstraint>();
|
||||
}
|
||||
else
|
||||
{
|
||||
var tokens = segment.Split(':');
|
||||
var tokens = Value.Split(':');
|
||||
if (tokens[0].Length == 0)
|
||||
{
|
||||
throw new ArgumentException($"Malformed parameter '{segment}' in route '{template}' has no name before the constraints list.");
|
||||
|
|
@ -54,6 +68,21 @@ namespace Microsoft.AspNetCore.Components.Routing
|
|||
.Select(token => RouteConstraint.Parse(template, segment, token))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (IsParameter)
|
||||
{
|
||||
if (IsOptional && IsCatchAll)
|
||||
{
|
||||
throw new InvalidOperationException($"Invalid segment '{segment}' in route '{template}'. A catch-all parameter cannot be marked optional.");
|
||||
}
|
||||
|
||||
// Moving the check for this here instead of TemplateParser so we can allow catch-all.
|
||||
// We checked for '*' up above specifically for catch-all segments, this one checks for all others
|
||||
if (Value.IndexOf('*') != -1)
|
||||
{
|
||||
throw new InvalidOperationException($"Invalid template '{template}'. The character '*' in parameter segment '{{{segment}}}' is not allowed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The value of the segment. The exact text to match when is a literal.
|
||||
|
|
@ -64,6 +93,8 @@ namespace Microsoft.AspNetCore.Components.Routing
|
|||
|
||||
public bool IsOptional { get; }
|
||||
|
||||
public bool IsCatchAll { get; }
|
||||
|
||||
public RouteConstraint[] Constraints { get; }
|
||||
|
||||
public bool Match(string pathSegment, out object? matchedParameterValue)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Components
|
|||
var callback = default(EventCallback);
|
||||
|
||||
// Act & Assert (Does not throw)
|
||||
await callback.InvokeAsync(null);
|
||||
await callback.InvokeAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Components
|
|||
var callback = default(EventCallback<EventArgs>);
|
||||
|
||||
// Act & Assert (Does not throw)
|
||||
await callback.InvokeAsync(null);
|
||||
await callback.InvokeAsync();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.Components
|
|||
var callback = new EventCallback(null, (Action)(() => runCount++));
|
||||
|
||||
// Act
|
||||
await callback.InvokeAsync(null);
|
||||
await callback.InvokeAsync();
|
||||
|
||||
|
||||
// Assert
|
||||
|
|
@ -54,7 +54,7 @@ namespace Microsoft.AspNetCore.Components
|
|||
var callback = new EventCallback<EventArgs>(null, (Action)(() => runCount++));
|
||||
|
||||
// Act
|
||||
await callback.InvokeAsync(null);
|
||||
await callback.InvokeAsync();
|
||||
|
||||
|
||||
// Assert
|
||||
|
|
@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Components
|
|||
var callback = new EventCallback(component, (Action)(() => runCount++));
|
||||
|
||||
// Act
|
||||
await callback.InvokeAsync(null);
|
||||
await callback.InvokeAsync();
|
||||
|
||||
|
||||
// Assert
|
||||
|
|
@ -108,7 +108,7 @@ namespace Microsoft.AspNetCore.Components
|
|||
var callback = new EventCallback(component, (Action<EventArgs>)((e) => { arg = e; runCount++; }));
|
||||
|
||||
// Act
|
||||
await callback.InvokeAsync(null);
|
||||
await callback.InvokeAsync();
|
||||
|
||||
|
||||
// Assert
|
||||
|
|
@ -184,7 +184,7 @@ namespace Microsoft.AspNetCore.Components
|
|||
var callback = new EventCallback(component, (Func<Task>)(() => { runCount++; return Task.CompletedTask; }));
|
||||
|
||||
// Act
|
||||
await callback.InvokeAsync(null);
|
||||
await callback.InvokeAsync();
|
||||
|
||||
|
||||
// Assert
|
||||
|
|
@ -221,7 +221,7 @@ namespace Microsoft.AspNetCore.Components
|
|||
var callback = new EventCallback(component, (Func<EventArgs, Task>)((e) => { arg = e; runCount++; return Task.CompletedTask; }));
|
||||
|
||||
// Act
|
||||
await callback.InvokeAsync(null);
|
||||
await callback.InvokeAsync();
|
||||
|
||||
|
||||
// Assert
|
||||
|
|
@ -297,7 +297,7 @@ namespace Microsoft.AspNetCore.Components
|
|||
var callback = new EventCallback<EventArgs>(component, (Action)(() => runCount++));
|
||||
|
||||
// Act
|
||||
await callback.InvokeAsync(null);
|
||||
await callback.InvokeAsync();
|
||||
|
||||
|
||||
// Assert
|
||||
|
|
@ -334,7 +334,7 @@ namespace Microsoft.AspNetCore.Components
|
|||
var callback = new EventCallback<EventArgs>(component, (Action<EventArgs>)((e) => { arg = e; runCount++; }));
|
||||
|
||||
// Act
|
||||
await callback.InvokeAsync(null);
|
||||
await callback.InvokeAsync();
|
||||
|
||||
|
||||
// Assert
|
||||
|
|
@ -373,7 +373,7 @@ namespace Microsoft.AspNetCore.Components
|
|||
var callback = new EventCallback<EventArgs>(component, (Func<Task>)(() => { runCount++; return Task.CompletedTask; }));
|
||||
|
||||
// Act
|
||||
await callback.InvokeAsync(null);
|
||||
await callback.InvokeAsync();
|
||||
|
||||
|
||||
// Assert
|
||||
|
|
@ -410,7 +410,7 @@ namespace Microsoft.AspNetCore.Components
|
|||
var callback = new EventCallback<EventArgs>(component, (Func<EventArgs, Task>)((e) => { arg = e; runCount++; return Task.CompletedTask; }));
|
||||
|
||||
// Act
|
||||
await callback.InvokeAsync(null);
|
||||
await callback.InvokeAsync();
|
||||
|
||||
|
||||
// Assert
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Components
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void IncomingParameterMatchesOverridenParameter_ThatDoesNotHasAttribute()
|
||||
public void IncomingParameterMatchesOverriddenParameter_ThatDoesNotHaveAttribute()
|
||||
{
|
||||
// Test for https://github.com/dotnet/aspnetcore/issues/13162
|
||||
// Arrange
|
||||
|
|
|
|||
|
|
@ -487,7 +487,8 @@ namespace Microsoft.AspNetCore.Components.Test
|
|||
public void DispatchEventHandlesSynchronousExceptionsFromEventHandlers()
|
||||
{
|
||||
// Arrange: Render a component with an event handler
|
||||
var renderer = new TestRenderer {
|
||||
var renderer = new TestRenderer
|
||||
{
|
||||
ShouldHandleExceptions = true
|
||||
};
|
||||
|
||||
|
|
@ -2086,6 +2087,238 @@ namespace Microsoft.AspNetCore.Components.Test
|
|||
Assert.Contains(exception2, aex.InnerExceptions);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RenderBatch_HandlesSynchronousExceptionsInAsyncDisposableComponents()
|
||||
{
|
||||
// Arrange
|
||||
var renderer = new TestRenderer { ShouldHandleExceptions = true };
|
||||
var exception1 = new InvalidOperationException();
|
||||
|
||||
var firstRender = true;
|
||||
var component = new TestComponent(builder =>
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
builder.AddContent(0, "Hello");
|
||||
builder.OpenComponent<AsyncDisposableComponent>(1);
|
||||
builder.AddAttribute(1, nameof(AsyncDisposableComponent.AsyncDisposeAction), (Func<ValueTask>)(() => throw exception1));
|
||||
builder.CloseComponent();
|
||||
}
|
||||
});
|
||||
var componentId = renderer.AssignRootComponentId(component);
|
||||
component.TriggerRender();
|
||||
|
||||
// Act: Second render
|
||||
firstRender = false;
|
||||
component.TriggerRender();
|
||||
|
||||
// Assert: Applicable children are included in disposal list
|
||||
Assert.Equal(2, renderer.Batches.Count);
|
||||
Assert.Equal(new[] { 1, }, renderer.Batches[1].DisposedComponentIDs);
|
||||
|
||||
// Outer component is still alive and not disposed.
|
||||
Assert.False(component.Disposed);
|
||||
var aex = Assert.IsType<AggregateException>(Assert.Single(renderer.HandledExceptions));
|
||||
var innerException = Assert.Single(aex.Flatten().InnerExceptions);
|
||||
Assert.Same(exception1, innerException);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RenderBatch_CanDisposeSynchronousAsyncDisposableImplementations()
|
||||
{
|
||||
// Arrange
|
||||
var renderer = new TestRenderer { ShouldHandleExceptions = true };
|
||||
|
||||
var firstRender = true;
|
||||
var component = new TestComponent(builder =>
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
builder.AddContent(0, "Hello");
|
||||
builder.OpenComponent<AsyncDisposableComponent>(1);
|
||||
builder.AddAttribute(1, nameof(AsyncDisposableComponent.AsyncDisposeAction), (Func<ValueTask>)(() => default));
|
||||
builder.CloseComponent();
|
||||
}
|
||||
});
|
||||
var componentId = renderer.AssignRootComponentId(component);
|
||||
component.TriggerRender();
|
||||
|
||||
// Act: Second render
|
||||
firstRender = false;
|
||||
component.TriggerRender();
|
||||
|
||||
// Assert: Applicable children are included in disposal list
|
||||
Assert.Equal(2, renderer.Batches.Count);
|
||||
Assert.Equal(new[] { 1, }, renderer.Batches[1].DisposedComponentIDs);
|
||||
|
||||
// Outer component is still alive and not disposed.
|
||||
Assert.False(component.Disposed);
|
||||
Assert.Empty(renderer.HandledExceptions);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RenderBatch_CanDisposeAsynchronousAsyncDisposables()
|
||||
{
|
||||
// Arrange
|
||||
var semaphore = new Semaphore(0, 1);
|
||||
var renderer = new TestRenderer { ShouldHandleExceptions = true };
|
||||
renderer.OnExceptionHandled = () => semaphore.Release();
|
||||
var exception1 = new InvalidOperationException();
|
||||
var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
var firstRender = true;
|
||||
var component = new TestComponent(builder =>
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
builder.AddContent(0, "Hello");
|
||||
builder.OpenComponent<AsyncDisposableComponent>(1);
|
||||
builder.AddAttribute(1, nameof(AsyncDisposableComponent.AsyncDisposeAction), (Func<ValueTask>)(async () => { await tcs.Task; }));
|
||||
builder.CloseComponent();
|
||||
}
|
||||
});
|
||||
|
||||
var componentId = renderer.AssignRootComponentId(component);
|
||||
component.TriggerRender();
|
||||
// Act: Second render
|
||||
firstRender = false;
|
||||
component.TriggerRender();
|
||||
|
||||
// Assert: Applicable children are included in disposal list
|
||||
Assert.Equal(2, renderer.Batches.Count);
|
||||
Assert.Equal(new[] { 1, }, renderer.Batches[1].DisposedComponentIDs);
|
||||
|
||||
// Outer component is still alive and not disposed.
|
||||
Assert.False(component.Disposed);
|
||||
Assert.Empty(renderer.HandledExceptions);
|
||||
|
||||
// Continue execution
|
||||
tcs.SetResult();
|
||||
Assert.False(semaphore.WaitOne(10));
|
||||
Assert.Empty(renderer.HandledExceptions);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RenderBatch_HandlesAsynchronousExceptionsInAsyncDisposableComponents()
|
||||
{
|
||||
// Arrange
|
||||
var semaphore = new Semaphore(0, 1);
|
||||
var renderer = new TestRenderer { ShouldHandleExceptions = true };
|
||||
renderer.OnExceptionHandled = () => semaphore.Release();
|
||||
var exception1 = new InvalidOperationException();
|
||||
var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
var firstRender = true;
|
||||
var component = new TestComponent(builder =>
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
builder.AddContent(0, "Hello");
|
||||
builder.OpenComponent<AsyncDisposableComponent>(1);
|
||||
builder.AddAttribute(1, nameof(AsyncDisposableComponent.AsyncDisposeAction), (Func<ValueTask>)(async () => { await tcs.Task; throw exception1; }));
|
||||
builder.CloseComponent();
|
||||
}
|
||||
});
|
||||
var componentId = renderer.AssignRootComponentId(component);
|
||||
component.TriggerRender();
|
||||
// Act: Second render
|
||||
firstRender = false;
|
||||
component.TriggerRender();
|
||||
|
||||
// Assert: Applicable children are included in disposal list
|
||||
Assert.Equal(2, renderer.Batches.Count);
|
||||
Assert.Equal(new[] { 1, }, renderer.Batches[1].DisposedComponentIDs);
|
||||
|
||||
// Outer component is still alive and not disposed.
|
||||
Assert.False(component.Disposed);
|
||||
Assert.Empty(renderer.HandledExceptions);
|
||||
|
||||
// Continue execution
|
||||
tcs.SetResult();
|
||||
semaphore.WaitOne();
|
||||
var aex = Assert.IsType<InvalidOperationException>(Assert.Single(renderer.HandledExceptions));
|
||||
Assert.Same(exception1, aex);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RenderBatch_ReportsSynchronousCancelationsAsErrors()
|
||||
{
|
||||
// Arrange
|
||||
var renderer = new TestRenderer { ShouldHandleExceptions = true };
|
||||
var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
var firstRender = true;
|
||||
var component = new TestComponent(builder =>
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
builder.AddContent(0, "Hello");
|
||||
builder.OpenComponent<AsyncDisposableComponent>(1);
|
||||
builder.AddAttribute(1, nameof(AsyncDisposableComponent.AsyncDisposeAction), (Func<ValueTask>)(() => throw new TaskCanceledException()));
|
||||
builder.CloseComponent();
|
||||
}
|
||||
});
|
||||
var componentId = renderer.AssignRootComponentId(component);
|
||||
component.TriggerRender();
|
||||
|
||||
// Act: Second render
|
||||
firstRender = false;
|
||||
component.TriggerRender();
|
||||
|
||||
// Assert: Applicable children are included in disposal list
|
||||
Assert.Equal(2, renderer.Batches.Count);
|
||||
Assert.Equal(new[] { 1, }, renderer.Batches[1].DisposedComponentIDs);
|
||||
|
||||
// Outer component is still alive and not disposed.
|
||||
Assert.False(component.Disposed);
|
||||
var aex = Assert.IsType<AggregateException>(Assert.Single(renderer.HandledExceptions));
|
||||
Assert.IsType<TaskCanceledException>(Assert.Single(aex.Flatten().InnerExceptions));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RenderBatch_ReportsAsynchronousCancelationsAsErrors()
|
||||
{
|
||||
// Arrange
|
||||
var semaphore = new Semaphore(0, 1);
|
||||
var renderer = new TestRenderer { ShouldHandleExceptions = true };
|
||||
renderer.OnExceptionHandled += () => semaphore.Release();
|
||||
var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var firstRender = true;
|
||||
var component = new TestComponent(builder =>
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
builder.AddContent(0, "Hello");
|
||||
builder.OpenComponent<AsyncDisposableComponent>(1);
|
||||
builder.AddAttribute(
|
||||
1,
|
||||
nameof(AsyncDisposableComponent.AsyncDisposeAction),
|
||||
(Func<ValueTask>)(() => new ValueTask(tcs.Task)));
|
||||
builder.CloseComponent();
|
||||
}
|
||||
});
|
||||
var componentId = renderer.AssignRootComponentId(component);
|
||||
component.TriggerRender();
|
||||
|
||||
// Act: Second render
|
||||
firstRender = false;
|
||||
component.TriggerRender();
|
||||
|
||||
// Assert: Applicable children are included in disposal list
|
||||
Assert.Equal(2, renderer.Batches.Count);
|
||||
Assert.Equal(new[] { 1, }, renderer.Batches[1].DisposedComponentIDs);
|
||||
|
||||
// Outer component is still alive and not disposed.
|
||||
Assert.False(component.Disposed);
|
||||
Assert.Empty(renderer.HandledExceptions);
|
||||
|
||||
// Cancel execution
|
||||
tcs.SetCanceled();
|
||||
|
||||
semaphore.WaitOne();
|
||||
var aex = Assert.IsType<TaskCanceledException>(Assert.Single(renderer.HandledExceptions));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RenderBatch_DoesNotDisposeComponentMultipleTimes()
|
||||
{
|
||||
|
|
@ -2589,7 +2822,7 @@ namespace Microsoft.AspNetCore.Components.Test
|
|||
|
||||
// Act: Toggle the checkbox
|
||||
var eventArgs = new ChangeEventArgs { Value = true };
|
||||
var renderTask = renderer.DispatchEventAsync(checkboxChangeEventHandlerId, eventArgs);
|
||||
var renderTask = renderer.DispatchEventAsync(checkboxChangeEventHandlerId, eventArgs);
|
||||
|
||||
Assert.True(renderTask.IsCompletedSuccessfully);
|
||||
var latestBatch = renderer.Batches.Last();
|
||||
|
|
@ -3768,7 +4001,7 @@ namespace Microsoft.AspNetCore.Components.Test
|
|||
requestedType => Assert.Equal(typeof(TestComponent), requestedType));
|
||||
}
|
||||
|
||||
private class TestComponentActivator<TResult> : IComponentActivator where TResult: IComponent, new()
|
||||
private class TestComponentActivator<TResult> : IComponentActivator where TResult : IComponent, new()
|
||||
{
|
||||
public List<Type> RequestedComponentTypes { get; } = new List<Type>();
|
||||
|
||||
|
|
@ -4147,6 +4380,24 @@ namespace Microsoft.AspNetCore.Components.Test
|
|||
}
|
||||
}
|
||||
|
||||
private class AsyncDisposableComponent : AutoRenderComponent, IAsyncDisposable
|
||||
{
|
||||
public bool Disposed { get; private set; }
|
||||
|
||||
[Parameter]
|
||||
public Func<ValueTask> AsyncDisposeAction { get; set; }
|
||||
|
||||
public ValueTask DisposeAsync()
|
||||
{
|
||||
Disposed = true;
|
||||
return AsyncDisposeAction == null ? default : AsyncDisposeAction.Invoke();
|
||||
}
|
||||
|
||||
protected override void BuildRenderTree(RenderTreeBuilder builder)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class TestAsyncRenderer : TestRenderer
|
||||
{
|
||||
public Task NextUpdateDisplayReturnTask { get; set; }
|
||||
|
|
|
|||
|
|
@ -226,6 +226,23 @@ namespace Microsoft.AspNetCore.Components.Test.Routing
|
|||
Assert.Single(context.Parameters, p => p.Key == "parameter" && (string)p.Value == expectedValue);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("/blog/value1", "value1")]
|
||||
[InlineData("/blog/value1/foo%20bar", "value1/foo bar")]
|
||||
public void CanMatchCatchAllParameterTemplate(string path, string expectedValue)
|
||||
{
|
||||
// Arrange
|
||||
var routeTable = new TestRouteTableBuilder().AddRoute("/blog/{*parameter}").Build();
|
||||
var context = new RouteContext(path);
|
||||
|
||||
// Act
|
||||
routeTable.Route(context);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(context.Handler);
|
||||
Assert.Single(context.Parameters, p => p.Key == "parameter" && (string)p.Value == expectedValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanMatchTemplateWithMultipleParameters()
|
||||
{
|
||||
|
|
@ -247,6 +264,29 @@ namespace Microsoft.AspNetCore.Components.Test.Routing
|
|||
Assert.Equal(expectedParameters, context.Parameters);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void CanMatchTemplateWithMultipleParametersAndCatchAllParameter()
|
||||
{
|
||||
// Arrange
|
||||
var routeTable = new TestRouteTableBuilder().AddRoute("/{some}/awesome/{route}/with/{*catchAll}").Build();
|
||||
var context = new RouteContext("/an/awesome/path/with/some/catch/all/stuff");
|
||||
|
||||
var expectedParameters = new Dictionary<string, object>
|
||||
{
|
||||
["some"] = "an",
|
||||
["route"] = "path",
|
||||
["catchAll"] = "some/catch/all/stuff"
|
||||
};
|
||||
|
||||
// Act
|
||||
routeTable.Route(context);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(context.Handler);
|
||||
Assert.Equal(expectedParameters, context.Parameters);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> CanMatchParameterWithConstraintCases() => new object[][]
|
||||
{
|
||||
new object[] { "/{value:bool}", "/true", true },
|
||||
|
|
@ -476,7 +516,7 @@ namespace Microsoft.AspNetCore.Components.Test.Routing
|
|||
|
||||
|
||||
[Fact]
|
||||
public void PrefersLiteralTemplateOverParmeterizedTemplates()
|
||||
public void PrefersLiteralTemplateOverParameterizedTemplates()
|
||||
{
|
||||
// Arrange
|
||||
var routeTable = new TestRouteTableBuilder()
|
||||
|
|
|
|||
|
|
@ -83,6 +83,45 @@ namespace Microsoft.AspNetCore.Components.Routing
|
|||
Assert.Equal(expected, actual, RouteTemplateTestComparer.Instance);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_SingleCatchAllParameter()
|
||||
{
|
||||
// Arrange
|
||||
var expected = new ExpectedTemplateBuilder().Parameter("p");
|
||||
|
||||
// Act
|
||||
var actual = TemplateParser.ParseTemplate("{*p}");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual, RouteTemplateTestComparer.Instance);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_MixedLiteralAndCatchAllParameter()
|
||||
{
|
||||
// Arrange
|
||||
var expected = new ExpectedTemplateBuilder().Literal("awesome").Literal("wow").Parameter("p");
|
||||
|
||||
// Act
|
||||
var actual = TemplateParser.ParseTemplate("awesome/wow/{*p}");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual, RouteTemplateTestComparer.Instance);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_MixedLiteralParameterAndCatchAllParameter()
|
||||
{
|
||||
// Arrange
|
||||
var expected = new ExpectedTemplateBuilder().Literal("awesome").Parameter("p1").Parameter("p2");
|
||||
|
||||
// Act
|
||||
var actual = TemplateParser.ParseTemplate("awesome/{p1}/{*p2}");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual, RouteTemplateTestComparer.Instance);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidTemplate_WithRepeatedParameter()
|
||||
{
|
||||
|
|
@ -113,7 +152,8 @@ namespace Microsoft.AspNetCore.Components.Routing
|
|||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("{*}", "Invalid template '{*}'. The character '*' in parameter segment '{*}' is not allowed.")]
|
||||
// * is only allowed at beginning for catch-all parameters
|
||||
[InlineData("{p*}", "Invalid template '{p*}'. The character '*' in parameter segment '{p*}' is not allowed.")]
|
||||
[InlineData("{{}", "Invalid template '{{}'. The character '{' in parameter segment '{{}' is not allowed.")]
|
||||
[InlineData("{}}", "Invalid template '{}}'. The character '}' in parameter segment '{}}' is not allowed.")]
|
||||
[InlineData("{=}", "Invalid template '{=}'. The character '=' in parameter segment '{=}' is not allowed.")]
|
||||
|
|
@ -166,6 +206,26 @@ namespace Microsoft.AspNetCore.Components.Routing
|
|||
Assert.Equal(expectedMessage, ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidTemplate_CatchAllParamWithMultipleAsterisks()
|
||||
{
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => TemplateParser.ParseTemplate("/test/{a}/{**b}"));
|
||||
|
||||
var expectedMessage = "Invalid template '/test/{a}/{**b}'. A catch-all parameter may only have one '*' at the beginning of the segment.";
|
||||
|
||||
Assert.Equal(expectedMessage, ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidTemplate_CatchAllParamNotLast()
|
||||
{
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => TemplateParser.ParseTemplate("/test/{*a}/{b}"));
|
||||
|
||||
var expectedMessage = "Invalid template 'test/{*a}/{b}'. A catch-all parameter can only appear as the last segment of the route template.";
|
||||
|
||||
Assert.Equal(expectedMessage, ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidTemplate_BadOptionalCharacterPosition()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ app {
|
|||
height: 3.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.main {
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ namespace Microsoft.AspNetCore.Components.Web.Rendering
|
|||
exceptions.Add(e);
|
||||
};
|
||||
|
||||
// Receive the ack for the intial batch
|
||||
// Receive the ack for the initial batch
|
||||
_ = renderer.OnRenderCompletedAsync(2, null);
|
||||
// Receive the ack for the second batch
|
||||
_ = renderer.OnRenderCompletedAsync(2, null);
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ namespace Microsoft.AspNetCore.Components.Web
|
|||
"touch" => Deserialize<TouchEventArgs>(eventArgsJson),
|
||||
"unknown" => EventArgs.Empty,
|
||||
"wheel" => Deserialize<WheelEventArgs>(eventArgsJson),
|
||||
"toggle" => Deserialize<EventArgs>(eventArgsJson),
|
||||
_ => throw new InvalidOperationException($"Unsupported event type '{eventArgsType}'. EventId: '{eventHandlerId}'."),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -66,8 +66,11 @@ async function boot(options?: Partial<WebAssemblyStartOptions>): Promise<void> {
|
|||
);
|
||||
});
|
||||
|
||||
// Get the custom environment setting if defined
|
||||
const environment = options?.environment;
|
||||
|
||||
// Fetch the resources and prepare the Mono runtime
|
||||
const bootConfigResult = await BootConfigResult.initAsync();
|
||||
const bootConfigResult = await BootConfigResult.initAsync(environment);
|
||||
|
||||
const [resourceLoader] = await Promise.all([
|
||||
WebAssemblyResourceLoader.initAsync(bootConfigResult.bootConfig, options || {}),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ export class BootConfigResult {
|
|||
private constructor(public bootConfig: BootJsonData, public applicationEnvironment: string) {
|
||||
}
|
||||
|
||||
static async initAsync(): Promise<BootConfigResult> {
|
||||
static async initAsync(environment?: string): Promise<BootConfigResult> {
|
||||
const bootConfigResponse = await fetch('_framework/blazor.boot.json', {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
|
|
@ -10,8 +10,8 @@ export class BootConfigResult {
|
|||
});
|
||||
|
||||
// While we can expect an ASP.NET Core hosted application to include the environment, other
|
||||
// hosts may not. Assume 'Production' in the absenc of any specified value.
|
||||
const applicationEnvironment = bootConfigResponse.headers.get('Blazor-Environment') || 'Production';
|
||||
// hosts may not. Assume 'Production' in the absence of any specified value.
|
||||
const applicationEnvironment = environment || bootConfigResponse.headers.get('Blazor-Environment') || 'Production';
|
||||
const bootConfig: BootJsonData = await bootConfigResponse.json();
|
||||
|
||||
return new BootConfigResult(bootConfig, applicationEnvironment);
|
||||
|
|
|
|||
|
|
@ -356,6 +356,7 @@ function createEmscriptenModuleInstance(resourceLoader: WebAssemblyResourceLoade
|
|||
resourceLoader.purgeUnusedCacheEntriesAsync(); // Don't await - it's fine to run in background
|
||||
|
||||
MONO.mono_wasm_setenv("MONO_URI_DOTNETRELATIVEORABSOLUTE", "true");
|
||||
MONO.mono_wasm_setenv("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", "1");
|
||||
const load_runtime = cwrap('mono_wasm_load_runtime', null, ['string', 'number']);
|
||||
// -1 enables debugging with logging disabled. 0 disables debugging entirely.
|
||||
load_runtime(appBinDirName, hasDebuggingEnabled() ? -1 : 0);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// Import type definitions to ensure that the global declaration
|
||||
// is of BINDING is included when tests run
|
||||
import './Mono/MonoTypes';
|
||||
import { System_String } from './Platform';
|
||||
|
||||
interface TimingEntry {
|
||||
|
|
|
|||
|
|
@ -165,6 +165,12 @@ async function getCacheToUseIfEnabled(bootConfig: BootJsonData): Promise<Cache |
|
|||
return null;
|
||||
}
|
||||
|
||||
// cache integrity is compromised if the first request has been served over http
|
||||
// in this case, we want to disable caching and integrity validation
|
||||
if (document.location.protocol !== 'https:') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Define a separate cache for each base href, so we're isolated from any other
|
||||
// Blazor application running on the same origin. We need this so that we're free
|
||||
// to purge from the cache anything we're not using and don't let it keep growing,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,11 @@ export interface WebAssemblyStartOptions {
|
|||
* @returns A URI string or a Response promise to override the loading process, or null/undefined to allow the default loading behavior.
|
||||
*/
|
||||
loadBootResource(type: WebAssemblyBootResourceType, name: string, defaultUri: string, integrity: string) : string | Promise<Response> | null | undefined;
|
||||
|
||||
/**
|
||||
* Override built-in environment setting on start.
|
||||
*/
|
||||
environment?: string;
|
||||
}
|
||||
|
||||
// This type doesn't have to align with anything in BootConfig.
|
||||
|
|
|
|||
|
|
@ -238,7 +238,8 @@ export class BrowserRenderer {
|
|||
document.createElementNS('http://www.w3.org/2000/svg', tagName) :
|
||||
document.createElement(tagName);
|
||||
const newElement = toLogicalElement(newDomElementRaw);
|
||||
insertLogicalChild(newDomElementRaw, parent, childIndex);
|
||||
|
||||
let inserted = false;
|
||||
|
||||
// Apply attributes
|
||||
const descendantsEndIndexExcl = frameIndex + frameReader.subtreeLength(frame);
|
||||
|
|
@ -247,6 +248,8 @@ export class BrowserRenderer {
|
|||
if (frameReader.frameType(descendantFrame) === FrameType.attribute) {
|
||||
this.applyAttribute(batch, componentId, newDomElementRaw, descendantFrame);
|
||||
} else {
|
||||
insertLogicalChild(newDomElementRaw, parent, childIndex);
|
||||
inserted = true;
|
||||
// As soon as we see a non-attribute child, all the subsequent child frames are
|
||||
// not attributes, so bail out and insert the remnants recursively
|
||||
this.insertFrameRange(batch, componentId, newElement, 0, frames, descendantIndex, descendantsEndIndexExcl);
|
||||
|
|
@ -254,17 +257,40 @@ export class BrowserRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
// We handle setting 'value' on a <select> in two different ways:
|
||||
// [1] When inserting a corresponding <option>, in case you're dynamically adding options
|
||||
// this element did not have any children, so it's not inserted yet.
|
||||
if (!inserted) {
|
||||
insertLogicalChild(newDomElementRaw, parent, childIndex);
|
||||
}
|
||||
|
||||
// We handle setting 'value' on a <select> in three different ways:
|
||||
// [1] When inserting a corresponding <option>, in case you're dynamically adding options.
|
||||
// This is the case below.
|
||||
// [2] After we finish inserting the <select>, in case the descendant options are being
|
||||
// added as an opaque markup block rather than individually
|
||||
// Right here we implement [2]
|
||||
if (newDomElementRaw instanceof HTMLSelectElement && selectValuePropname in newDomElementRaw) {
|
||||
// added as an opaque markup block rather than individually. This is the other case below.
|
||||
// [3] In case the the value of the select and the option value is changed in the same batch.
|
||||
// We just receive an attribute frame and have to set the select value afterwards.
|
||||
|
||||
if (newDomElementRaw instanceof HTMLOptionElement)
|
||||
{
|
||||
// Situation 1
|
||||
this.trySetSelectValueFromOptionElement(newDomElementRaw);
|
||||
} else if (newDomElementRaw instanceof HTMLSelectElement && selectValuePropname in newDomElementRaw) {
|
||||
// Situation 2
|
||||
const selectValue: string | null = newDomElementRaw[selectValuePropname];
|
||||
setSelectElementValue(newDomElementRaw, selectValue);
|
||||
}
|
||||
}
|
||||
|
||||
private trySetSelectValueFromOptionElement(optionElement: HTMLOptionElement) {
|
||||
const selectElem = this.findClosestAncestorSelectElement(optionElement);
|
||||
if (selectElem && (selectValuePropname in selectElem) && selectElem[selectValuePropname] === optionElement.value) {
|
||||
setSelectElementValue(selectElem, optionElement.value);
|
||||
delete selectElem[selectValuePropname];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private insertComponent(batch: RenderBatch, parent: LogicalElement, childIndex: number, frame: RenderTreeFrame) {
|
||||
const containerElement = createAndInsertLogicalContainer(parent, childIndex);
|
||||
|
||||
|
|
@ -385,13 +411,10 @@ export class BrowserRenderer {
|
|||
} else {
|
||||
element.removeAttribute('value');
|
||||
}
|
||||
|
||||
// See above for why we have this special handling for <select>/<option>
|
||||
// Note that this is only one of the two cases where we set the value on a <select>
|
||||
const selectElem = this.findClosestAncestorSelectElement(element);
|
||||
if (selectElem && (selectValuePropname in selectElem) && selectElem[selectValuePropname] === value) {
|
||||
this.tryApplyValueProperty(batch, selectElem, attributeFrame);
|
||||
delete selectElem[selectValuePropname];
|
||||
}
|
||||
// Situation 3
|
||||
this.trySetSelectValueFromOptionElement(<HTMLOptionElement>element);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ const nonBubblingEvents = toLookup([
|
|||
'scroll',
|
||||
'submit',
|
||||
'unload',
|
||||
'toggle',
|
||||
'DOMNodeInsertedIntoDocument',
|
||||
'DOMNodeRemovedFromDocument',
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -89,6 +89,9 @@ export class EventForDotNet<TData extends UIEventArgs> {
|
|||
case 'mousewheel':
|
||||
return new EventForDotNet<UIWheelEventArgs>('wheel', parseWheelEvent(event as WheelEvent));
|
||||
|
||||
case 'toggle':
|
||||
return new EventForDotNet<UIEventArgs>('toggle', { type: event.type });
|
||||
|
||||
default:
|
||||
return new EventForDotNet<UIEventArgs>('unknown', { type: event.type });
|
||||
}
|
||||
|
|
@ -248,7 +251,7 @@ function normalizeTimeBasedValue(element: HTMLInputElement): string {
|
|||
|
||||
// The following interfaces must be kept in sync with the UIEventArgs C# classes
|
||||
|
||||
export type EventArgsType = 'change' | 'clipboard' | 'drag' | 'error' | 'focus' | 'keyboard' | 'mouse' | 'pointer' | 'progress' | 'touch' | 'unknown' | 'wheel';
|
||||
export type EventArgsType = 'change' | 'clipboard' | 'drag' | 'error' | 'focus' | 'keyboard' | 'mouse' | 'pointer' | 'progress' | 'touch' | 'unknown' | 'wheel' | 'toggle';
|
||||
|
||||
export interface UIEventArgs {
|
||||
type: string;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
{
|
||||
private readonly Func<Task> _handleSubmitDelegate; // Cache to avoid per-render allocations
|
||||
|
||||
private EditContext? _fixedEditContext;
|
||||
private EditContext? _editContext;
|
||||
private bool _hasSetEditContextExplicitly;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an instance of <see cref="EditForm"/>.
|
||||
|
|
@ -36,7 +37,16 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
/// also supply <see cref="Model"/>, since the model value will be taken
|
||||
/// from the <see cref="EditContext.Model"/> property.
|
||||
/// </summary>
|
||||
[Parameter] public EditContext? EditContext { get; set; }
|
||||
[Parameter]
|
||||
public EditContext? EditContext
|
||||
{
|
||||
get => _editContext;
|
||||
set
|
||||
{
|
||||
_editContext = value;
|
||||
_hasSetEditContextExplicitly = value != null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the top-level model object for the form. An edit context will
|
||||
|
|
@ -73,11 +83,16 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
/// <inheritdoc />
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
if ((EditContext == null) == (Model == null))
|
||||
if (_hasSetEditContextExplicitly && Model != null)
|
||||
{
|
||||
throw new InvalidOperationException($"{nameof(EditForm)} requires a {nameof(Model)} " +
|
||||
$"parameter, or an {nameof(EditContext)} parameter, but not both.");
|
||||
}
|
||||
else if (!_hasSetEditContextExplicitly && Model == null)
|
||||
{
|
||||
throw new InvalidOperationException($"{nameof(EditForm)} requires either a {nameof(Model)} " +
|
||||
$"parameter, or an {nameof(EditContext)} parameter, please provide one of these.");
|
||||
}
|
||||
|
||||
// If you're using OnSubmit, it becomes your responsibility to trigger validation manually
|
||||
// (e.g., so you can display a "pending" state in the UI). In that case you don't want the
|
||||
|
|
@ -89,31 +104,31 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
$"{nameof(EditForm)}, do not also supply {nameof(OnValidSubmit)} or {nameof(OnInvalidSubmit)}.");
|
||||
}
|
||||
|
||||
// Update _fixedEditContext if we don't have one yet, or if they are supplying a
|
||||
// Update _editContext if we don't have one yet, or if they are supplying a
|
||||
// potentially new EditContext, or if they are supplying a different Model
|
||||
if (_fixedEditContext == null || EditContext != null || Model != _fixedEditContext.Model)
|
||||
if (Model != null && Model != _editContext?.Model)
|
||||
{
|
||||
_fixedEditContext = EditContext ?? new EditContext(Model!);
|
||||
_editContext = new EditContext(Model!);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void BuildRenderTree(RenderTreeBuilder builder)
|
||||
{
|
||||
Debug.Assert(_fixedEditContext != null);
|
||||
Debug.Assert(_editContext != null);
|
||||
|
||||
// If _fixedEditContext changes, tear down and recreate all descendants.
|
||||
// If _editContext changes, tear down and recreate all descendants.
|
||||
// This is so we can safely use the IsFixed optimization on CascadingValue,
|
||||
// optimizing for the common case where _fixedEditContext never changes.
|
||||
builder.OpenRegion(_fixedEditContext.GetHashCode());
|
||||
// optimizing for the common case where _editContext never changes.
|
||||
builder.OpenRegion(_editContext.GetHashCode());
|
||||
|
||||
builder.OpenElement(0, "form");
|
||||
builder.AddMultipleAttributes(1, AdditionalAttributes);
|
||||
builder.AddAttribute(2, "onsubmit", _handleSubmitDelegate);
|
||||
builder.OpenComponent<CascadingValue<EditContext>>(3);
|
||||
builder.AddAttribute(4, "IsFixed", true);
|
||||
builder.AddAttribute(5, "Value", _fixedEditContext);
|
||||
builder.AddAttribute(6, "ChildContent", ChildContent?.Invoke(_fixedEditContext));
|
||||
builder.AddAttribute(5, "Value", _editContext);
|
||||
builder.AddAttribute(6, "ChildContent", ChildContent?.Invoke(_editContext));
|
||||
builder.CloseComponent();
|
||||
builder.CloseElement();
|
||||
|
||||
|
|
@ -122,26 +137,26 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
|
||||
private async Task HandleSubmitAsync()
|
||||
{
|
||||
Debug.Assert(_fixedEditContext != null);
|
||||
Debug.Assert(_editContext != null);
|
||||
|
||||
if (OnSubmit.HasDelegate)
|
||||
{
|
||||
// When using OnSubmit, the developer takes control of the validation lifecycle
|
||||
await OnSubmit.InvokeAsync(_fixedEditContext);
|
||||
await OnSubmit.InvokeAsync(_editContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, the system implicitly runs validation on form submission
|
||||
var isValid = _fixedEditContext.Validate(); // This will likely become ValidateAsync later
|
||||
var isValid = _editContext.Validate(); // This will likely become ValidateAsync later
|
||||
|
||||
if (isValid && OnValidSubmit.HasDelegate)
|
||||
{
|
||||
await OnValidSubmit.InvokeAsync(_fixedEditContext);
|
||||
await OnValidSubmit.InvokeAsync(_editContext);
|
||||
}
|
||||
|
||||
if (!isValid && OnInvalidSubmit.HasDelegate)
|
||||
{
|
||||
await OnInvalidSubmit.InvokeAsync(_fixedEditContext);
|
||||
await OnInvalidSubmit.InvokeAsync(_editContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,12 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
/// </summary>
|
||||
[Parameter] public Expression<Func<TValue>>? ValueExpression { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display name for this field.
|
||||
/// <para>This value is used when generating error messages when the input value fails to parse correctly.</para>
|
||||
/// </summary>
|
||||
[Parameter] public string? DisplayName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the associated <see cref="Forms.EditContext"/>.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
}
|
||||
else
|
||||
{
|
||||
validationErrorMessage = string.Format(ParsingErrorMessage, FieldIdentifier.FieldName);
|
||||
validationErrorMessage = string.Format(ParsingErrorMessage, DisplayName ?? FieldIdentifier.FieldName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
else
|
||||
{
|
||||
result = default;
|
||||
validationErrorMessage = $"The {input.FieldIdentifier.FieldName} field is not valid.";
|
||||
validationErrorMessage = $"The {input.DisplayName ?? input.FieldIdentifier.FieldName} field is not valid.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
}
|
||||
else
|
||||
{
|
||||
validationErrorMessage = string.Format(ParsingErrorMessage, FieldIdentifier.FieldName);
|
||||
validationErrorMessage = string.Format(ParsingErrorMessage, DisplayName ?? FieldIdentifier.FieldName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,6 +122,8 @@ namespace Microsoft.AspNetCore.Components.Web
|
|||
[EventHandler("onpointerlockerror", typeof(EventArgs), true, true)]
|
||||
[EventHandler("onreadystatechange", typeof(EventArgs), true, true)]
|
||||
[EventHandler("onscroll", typeof(EventArgs), true, true)]
|
||||
|
||||
[EventHandler("ontoggle", typeof(EventArgs), true, true)]
|
||||
public static class EventHandlers
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,120 @@
|
|||
// 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.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components.Rendering;
|
||||
using Microsoft.AspNetCore.Components.RenderTree;
|
||||
using Microsoft.AspNetCore.Components.Test.Helpers;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.Forms
|
||||
{
|
||||
public class EditFormTest
|
||||
{
|
||||
|
||||
[Fact]
|
||||
public async Task ThrowsIfBothEditContextAndModelAreSupplied()
|
||||
{
|
||||
// Arrange
|
||||
var editForm = new EditForm
|
||||
{
|
||||
EditContext = new EditContext(new TestModel()),
|
||||
Model = new TestModel()
|
||||
};
|
||||
var testRenderer = new TestRenderer();
|
||||
var componentId = testRenderer.AssignRootComponentId(editForm);
|
||||
|
||||
// Act/Assert
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(
|
||||
() => testRenderer.RenderRootComponentAsync(componentId));
|
||||
Assert.StartsWith($"{nameof(EditForm)} requires a {nameof(EditForm.Model)} parameter, or an {nameof(EditContext)} parameter, but not both.", ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ThrowsIfBothEditContextAndModelAreNull()
|
||||
{
|
||||
// Arrange
|
||||
var editForm = new EditForm();
|
||||
var testRenderer = new TestRenderer();
|
||||
var componentId = testRenderer.AssignRootComponentId(editForm);
|
||||
|
||||
// Act/Assert
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(
|
||||
() => testRenderer.RenderRootComponentAsync(componentId));
|
||||
Assert.StartsWith($"{nameof(EditForm)} requires either a {nameof(EditForm.Model)} parameter, or an {nameof(EditContext)} parameter, please provide one of these.", ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReturnsEditContextWhenModelParameterUsed()
|
||||
{
|
||||
// Arrange
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestEditFormHostComponent
|
||||
{
|
||||
Model = model
|
||||
};
|
||||
var editFormComponent = await RenderAndGetTestEditFormComponentAsync(rootComponent);
|
||||
|
||||
// Act
|
||||
var returnedEditContext = editFormComponent.EditContext;
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(returnedEditContext);
|
||||
Assert.Same(model, returnedEditContext.Model);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReturnsEditContextWhenEditContextParameterUsed()
|
||||
{
|
||||
// Arrange
|
||||
var editContext = new EditContext(new TestModel());
|
||||
var rootComponent = new TestEditFormHostComponent
|
||||
{
|
||||
EditContext = editContext
|
||||
};
|
||||
var editFormComponent = await RenderAndGetTestEditFormComponentAsync(rootComponent);
|
||||
|
||||
// Act
|
||||
var returnedEditContext = editFormComponent.EditContext;
|
||||
|
||||
// Assert
|
||||
Assert.Same(editContext, returnedEditContext);
|
||||
}
|
||||
|
||||
private static EditForm FindEditFormComponent(CapturedBatch batch)
|
||||
=> batch.ReferenceFrames
|
||||
.Where(f => f.FrameType == RenderTreeFrameType.Component)
|
||||
.Select(f => f.Component)
|
||||
.OfType<EditForm>()
|
||||
.Single();
|
||||
|
||||
private static async Task<EditForm> RenderAndGetTestEditFormComponentAsync(TestEditFormHostComponent hostComponent)
|
||||
{
|
||||
var testRenderer = new TestRenderer();
|
||||
var componentId = testRenderer.AssignRootComponentId(hostComponent);
|
||||
await testRenderer.RenderRootComponentAsync(componentId);
|
||||
return FindEditFormComponent(testRenderer.Batches.Single());
|
||||
}
|
||||
|
||||
class TestModel
|
||||
{
|
||||
public string StringProperty { get; set; }
|
||||
}
|
||||
|
||||
class TestEditFormHostComponent : AutoRenderComponent
|
||||
{
|
||||
public EditContext EditContext { get; set; }
|
||||
public TestModel Model { get; set; }
|
||||
|
||||
protected override void BuildRenderTree(RenderTreeBuilder builder)
|
||||
{
|
||||
builder.OpenComponent<EditForm>(0);
|
||||
builder.AddAttribute(1, "Model", Model);
|
||||
builder.AddAttribute(2, "EditContext", EditContext);
|
||||
builder.CloseComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,10 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components.Rendering;
|
||||
using Microsoft.AspNetCore.Components.RenderTree;
|
||||
using Microsoft.AspNetCore.Components.Test.Helpers;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -35,7 +32,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
// Arrange
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestInputHostComponent<string, TestInputComponent<string>> { EditContext = new EditContext(model), ValueExpression = () => model.StringProperty };
|
||||
await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
|
||||
// Act/Assert
|
||||
rootComponent.EditContext = new EditContext(model);
|
||||
|
|
@ -51,7 +48,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
var rootComponent = new TestInputHostComponent<string, TestInputComponent<string>> { EditContext = new EditContext(model) };
|
||||
|
||||
// Act/Assert
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => RenderAndGetTestInputComponentAsync(rootComponent));
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => InputRenderer.RenderAndGetComponent(rootComponent));
|
||||
Assert.Contains($"{typeof(TestInputComponent<string>)} requires a value for the 'ValueExpression' parameter. Normally this is provided automatically when using 'bind-Value'.", ex.Message);
|
||||
}
|
||||
|
||||
|
|
@ -68,7 +65,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
};
|
||||
|
||||
// Act
|
||||
var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("some value", inputComponent.CurrentValue);
|
||||
|
|
@ -87,7 +84,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
};
|
||||
|
||||
// Act
|
||||
var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
|
||||
// Assert
|
||||
Assert.Same(rootComponent.EditContext, inputComponent.EditContext);
|
||||
|
|
@ -106,7 +103,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
};
|
||||
|
||||
// Act
|
||||
var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(FieldIdentifier.Create(() => model.StringProperty), inputComponent.FieldIdentifier);
|
||||
|
|
@ -123,7 +120,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
Value = "initial value",
|
||||
ValueExpression = () => model.StringProperty
|
||||
};
|
||||
var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
Assert.Equal("initial value", inputComponent.CurrentValue);
|
||||
|
||||
// Act
|
||||
|
|
@ -146,7 +143,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
ValueChanged = val => valueChangedCallLog.Add(val),
|
||||
ValueExpression = () => model.StringProperty
|
||||
};
|
||||
var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
Assert.Empty(valueChangedCallLog);
|
||||
|
||||
// Act
|
||||
|
|
@ -169,7 +166,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
ValueChanged = val => valueChangedCallLog.Add(val),
|
||||
ValueExpression = () => model.StringProperty
|
||||
};
|
||||
var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
Assert.Empty(valueChangedCallLog);
|
||||
|
||||
// Act
|
||||
|
|
@ -190,7 +187,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
Value = "initial value",
|
||||
ValueExpression = () => model.StringProperty
|
||||
};
|
||||
var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
Assert.False(rootComponent.EditContext.IsModified(() => model.StringProperty));
|
||||
|
||||
// Act
|
||||
|
|
@ -213,7 +210,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
var fieldIdentifier = FieldIdentifier.Create(() => model.StringProperty);
|
||||
|
||||
// Act/Assert: Initially, it's valid and unmodified
|
||||
var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
Assert.Equal("valid", inputComponent.CssClass); // no Class was specified
|
||||
|
||||
// Act/Assert: Modify the field
|
||||
|
|
@ -251,7 +248,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
var fieldIdentifier = FieldIdentifier.Create(() => model.StringProperty);
|
||||
|
||||
// Act/Assert
|
||||
var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
Assert.Equal("my-class other-class valid", inputComponent.CssClass);
|
||||
|
||||
// Act/Assert: Retains custom class when changing field class
|
||||
|
|
@ -270,7 +267,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
Value = new DateTime(1915, 3, 2),
|
||||
ValueExpression = () => model.DateProperty
|
||||
};
|
||||
var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
|
||||
// Act/Assert
|
||||
Assert.Equal("1915/03/02", inputComponent.CurrentValueAsString);
|
||||
|
|
@ -289,7 +286,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
ValueExpression = () => model.DateProperty
|
||||
};
|
||||
var fieldIdentifier = FieldIdentifier.Create(() => model.DateProperty);
|
||||
var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
var numValidationStateChanges = 0;
|
||||
rootComponent.EditContext.OnValidationStateChanged += (sender, eventArgs) => { numValidationStateChanges++; };
|
||||
|
||||
|
|
@ -319,7 +316,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
ValueExpression = () => model.DateProperty
|
||||
};
|
||||
var fieldIdentifier = FieldIdentifier.Create(() => model.DateProperty);
|
||||
var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
var numValidationStateChanges = 0;
|
||||
rootComponent.EditContext.OnValidationStateChanged += (sender, eventArgs) => { numValidationStateChanges++; };
|
||||
|
||||
|
|
@ -470,21 +467,6 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
Assert.Equal("userSpecifiedValue", component.AdditionalAttributes["aria-invalid"]);
|
||||
}
|
||||
|
||||
private static TComponent FindComponent<TComponent>(CapturedBatch batch)
|
||||
=> batch.ReferenceFrames
|
||||
.Where(f => f.FrameType == RenderTreeFrameType.Component)
|
||||
.Select(f => f.Component)
|
||||
.OfType<TComponent>()
|
||||
.Single();
|
||||
|
||||
private static async Task<TComponent> RenderAndGetTestInputComponentAsync<TValue, TComponent>(TestInputHostComponent<TValue, TComponent> hostComponent) where TComponent : TestInputComponent<TValue>
|
||||
{
|
||||
var testRenderer = new TestRenderer();
|
||||
var componentId = testRenderer.AssignRootComponentId(hostComponent);
|
||||
await testRenderer.RenderRootComponentAsync(componentId);
|
||||
return FindComponent<TComponent>(testRenderer.Batches.Single());
|
||||
}
|
||||
|
||||
class TestModel
|
||||
{
|
||||
public string StringProperty { get; set; }
|
||||
|
|
@ -530,7 +512,7 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
}
|
||||
}
|
||||
|
||||
class TestDateInputComponent : TestInputComponent<DateTime>
|
||||
private class TestDateInputComponent : TestInputComponent<DateTime>
|
||||
{
|
||||
protected override string FormatValueAsString(DateTime value)
|
||||
=> value.ToString("yyyy/MM/dd");
|
||||
|
|
@ -549,35 +531,5 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TestInputHostComponent<TValue, TComponent> : AutoRenderComponent where TComponent : TestInputComponent<TValue>
|
||||
{
|
||||
public Dictionary<string, object> AdditionalAttributes { get; set; }
|
||||
|
||||
public EditContext EditContext { get; set; }
|
||||
|
||||
public TValue Value { get; set; }
|
||||
|
||||
public Action<TValue> ValueChanged { get; set; }
|
||||
|
||||
public Expression<Func<TValue>> ValueExpression { get; set; }
|
||||
|
||||
protected override void BuildRenderTree(RenderTreeBuilder builder)
|
||||
{
|
||||
builder.OpenComponent<CascadingValue<EditContext>>(0);
|
||||
builder.AddAttribute(1, "Value", EditContext);
|
||||
builder.AddAttribute(2, "ChildContent", new RenderFragment(childBuilder =>
|
||||
{
|
||||
childBuilder.OpenComponent<TComponent>(0);
|
||||
childBuilder.AddAttribute(0, "Value", Value);
|
||||
childBuilder.AddAttribute(1, "ValueChanged",
|
||||
EventCallback.Factory.Create(this, ValueChanged));
|
||||
childBuilder.AddAttribute(2, "ValueExpression", ValueExpression);
|
||||
childBuilder.AddMultipleAttributes(3, AdditionalAttributes);
|
||||
childBuilder.CloseComponent();
|
||||
}));
|
||||
builder.CloseComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.Forms
|
||||
{
|
||||
public class InputDateTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task ValidationErrorUsesDisplayAttributeName()
|
||||
{
|
||||
// Arrange
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestInputHostComponent<DateTime, TestInputDateComponent>
|
||||
{
|
||||
EditContext = new EditContext(model),
|
||||
ValueExpression = () => model.DateProperty,
|
||||
AdditionalAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "DisplayName", "Date property" }
|
||||
}
|
||||
};
|
||||
var fieldIdentifier = FieldIdentifier.Create(() => model.DateProperty);
|
||||
var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
|
||||
// Act
|
||||
await inputComponent.SetCurrentValueAsStringAsync("invalidDate");
|
||||
|
||||
// Assert
|
||||
var validationMessages = rootComponent.EditContext.GetValidationMessages(fieldIdentifier);
|
||||
Assert.NotEmpty(validationMessages);
|
||||
Assert.Contains("The Date property field must be a date.", validationMessages);
|
||||
}
|
||||
|
||||
private class TestModel
|
||||
{
|
||||
public DateTime DateProperty { get; set; }
|
||||
}
|
||||
|
||||
private class TestInputDateComponent : InputDate<DateTime>
|
||||
{
|
||||
public async Task SetCurrentValueAsStringAsync(string value)
|
||||
{
|
||||
// This is equivalent to the subclass writing to CurrentValueAsString
|
||||
// (e.g., from @bind), except to simplify the test code there's an InvokeAsync
|
||||
// here. In production code it wouldn't normally be required because @bind
|
||||
// calls run on the sync context anyway.
|
||||
await InvokeAsync(() => { base.CurrentValueAsString = value; });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.Forms
|
||||
{
|
||||
public class InputNumberTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task ValidationErrorUsesDisplayAttributeName()
|
||||
{
|
||||
// Arrange
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestInputHostComponent<int, TestInputNumberComponent>
|
||||
{
|
||||
EditContext = new EditContext(model),
|
||||
ValueExpression = () => model.SomeNumber,
|
||||
AdditionalAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "DisplayName", "Some number" }
|
||||
}
|
||||
};
|
||||
var fieldIdentifier = FieldIdentifier.Create(() => model.SomeNumber);
|
||||
var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
|
||||
// Act
|
||||
await inputComponent.SetCurrentValueAsStringAsync("notANumber");
|
||||
|
||||
// Assert
|
||||
var validationMessages = rootComponent.EditContext.GetValidationMessages(fieldIdentifier);
|
||||
Assert.NotEmpty(validationMessages);
|
||||
Assert.Contains("The Some number field must be a number.", validationMessages);
|
||||
}
|
||||
|
||||
private class TestModel
|
||||
{
|
||||
public int SomeNumber { get; set; }
|
||||
}
|
||||
|
||||
private class TestInputNumberComponent : InputNumber<int>
|
||||
{
|
||||
public async Task SetCurrentValueAsStringAsync(string value)
|
||||
{
|
||||
// This is equivalent to the subclass writing to CurrentValueAsString
|
||||
// (e.g., from @bind), except to simplify the test code there's an InvokeAsync
|
||||
// here. In production code it wouldn't normally be required because @bind
|
||||
// calls run on the sync context anyway.
|
||||
await InvokeAsync(() => { base.CurrentValueAsString = value; });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components.RenderTree;
|
||||
using Microsoft.AspNetCore.Components.Test.Helpers;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.Forms
|
||||
{
|
||||
internal static class InputRenderer
|
||||
{
|
||||
public static async Task<TComponent> RenderAndGetComponent<TValue, TComponent>(TestInputHostComponent<TValue, TComponent> hostComponent)
|
||||
where TComponent : InputBase<TValue>
|
||||
{
|
||||
var testRenderer = new TestRenderer();
|
||||
var componentId = testRenderer.AssignRootComponentId(hostComponent);
|
||||
await testRenderer.RenderRootComponentAsync(componentId);
|
||||
return FindComponent<TComponent>(testRenderer.Batches.Single());
|
||||
}
|
||||
|
||||
private static TComponent FindComponent<TComponent>(CapturedBatch batch)
|
||||
=> batch.ReferenceFrames
|
||||
.Where(f => f.FrameType == RenderTreeFrameType.Component)
|
||||
.Select(f => f.Component)
|
||||
.OfType<TComponent>()
|
||||
.Single();
|
||||
}
|
||||
}
|
||||
|
|
@ -2,12 +2,8 @@
|
|||
// 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.Linq.Expressions;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components.Rendering;
|
||||
using Microsoft.AspNetCore.Components.RenderTree;
|
||||
using Microsoft.AspNetCore.Components.Test.Helpers;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.Forms
|
||||
|
|
@ -19,12 +15,12 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
{
|
||||
// Arrange
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestInputSelectHostComponent<TestEnum>
|
||||
var rootComponent = new TestInputHostComponent<TestEnum, TestInputSelect<TestEnum>>
|
||||
{
|
||||
EditContext = new EditContext(model),
|
||||
ValueExpression = () => model.NotNullableEnum
|
||||
};
|
||||
var inputSelectComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputSelectComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
|
||||
// Act
|
||||
inputSelectComponent.CurrentValueAsString = "Two";
|
||||
|
|
@ -38,12 +34,12 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
{
|
||||
// Arrange
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestInputSelectHostComponent<TestEnum>
|
||||
var rootComponent = new TestInputHostComponent<TestEnum, TestInputSelect<TestEnum>>
|
||||
{
|
||||
EditContext = new EditContext(model),
|
||||
ValueExpression = () => model.NotNullableEnum
|
||||
};
|
||||
var inputSelectComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputSelectComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
|
||||
// Act
|
||||
inputSelectComponent.CurrentValueAsString = "";
|
||||
|
|
@ -57,12 +53,12 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
{
|
||||
// Arrange
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestInputSelectHostComponent<TestEnum?>
|
||||
var rootComponent = new TestInputHostComponent<TestEnum?, TestInputSelect<TestEnum?>>
|
||||
{
|
||||
EditContext = new EditContext(model),
|
||||
ValueExpression = () => model.NullableEnum
|
||||
};
|
||||
var inputSelectComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputSelectComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
|
||||
// Act
|
||||
inputSelectComponent.CurrentValueAsString = "Two";
|
||||
|
|
@ -76,12 +72,12 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
{
|
||||
// Arrange
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestInputSelectHostComponent<TestEnum?>
|
||||
var rootComponent = new TestInputHostComponent<TestEnum?, TestInputSelect<TestEnum?>>
|
||||
{
|
||||
EditContext = new EditContext(model),
|
||||
ValueExpression = () => model.NullableEnum
|
||||
};
|
||||
var inputSelectComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputSelectComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
|
||||
// Act
|
||||
inputSelectComponent.CurrentValueAsString = "";
|
||||
|
|
@ -96,12 +92,12 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
{
|
||||
// Arrange
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestInputSelectHostComponent<Guid>
|
||||
var rootComponent = new TestInputHostComponent<Guid, TestInputSelect<Guid>>
|
||||
{
|
||||
EditContext = new EditContext(model),
|
||||
ValueExpression = () => model.NotNullableGuid
|
||||
};
|
||||
var inputSelectComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputSelectComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
|
||||
// Act
|
||||
var guid = Guid.NewGuid();
|
||||
|
|
@ -117,12 +113,12 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
{
|
||||
// Arrange
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestInputSelectHostComponent<Guid?>
|
||||
var rootComponent = new TestInputHostComponent<Guid?, TestInputSelect<Guid?>>
|
||||
{
|
||||
EditContext = new EditContext(model),
|
||||
ValueExpression = () => model.NullableGuid
|
||||
};
|
||||
var inputSelectComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputSelectComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
|
||||
// Act
|
||||
var guid = Guid.NewGuid();
|
||||
|
|
@ -138,12 +134,12 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
{
|
||||
// Arrange
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestInputSelectHostComponent<int>
|
||||
var rootComponent = new TestInputHostComponent<int, TestInputSelect<int>>
|
||||
{
|
||||
EditContext = new EditContext(model),
|
||||
ValueExpression = () => model.NotNullableInt
|
||||
};
|
||||
var inputSelectComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputSelectComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
|
||||
// Act
|
||||
inputSelectComponent.CurrentValueAsString = "42";
|
||||
|
|
@ -158,12 +154,12 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
{
|
||||
// Arrange
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestInputSelectHostComponent<int?>
|
||||
var rootComponent = new TestInputHostComponent<int?, TestInputSelect<int?>>
|
||||
{
|
||||
EditContext = new EditContext(model),
|
||||
ValueExpression = () => model.NullableInt
|
||||
};
|
||||
var inputSelectComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
|
||||
var inputSelectComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
|
||||
// Act
|
||||
inputSelectComponent.CurrentValueAsString = "42";
|
||||
|
|
@ -172,19 +168,30 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
Assert.Equal(42, inputSelectComponent.CurrentValue);
|
||||
}
|
||||
|
||||
private static TestInputSelect<TValue> FindInputSelectComponent<TValue>(CapturedBatch batch)
|
||||
=> batch.ReferenceFrames
|
||||
.Where(f => f.FrameType == RenderTreeFrameType.Component)
|
||||
.Select(f => f.Component)
|
||||
.OfType<TestInputSelect<TValue>>()
|
||||
.Single();
|
||||
|
||||
private static async Task<TestInputSelect<TValue>> RenderAndGetTestInputComponentAsync<TValue>(TestInputSelectHostComponent<TValue> hostComponent)
|
||||
[Fact]
|
||||
public async Task ValidationErrorUsesDisplayAttributeName()
|
||||
{
|
||||
var testRenderer = new TestRenderer();
|
||||
var componentId = testRenderer.AssignRootComponentId(hostComponent);
|
||||
await testRenderer.RenderRootComponentAsync(componentId);
|
||||
return FindInputSelectComponent<TValue>(testRenderer.Batches.Single());
|
||||
// Arrange
|
||||
var model = new TestModel();
|
||||
var rootComponent = new TestInputHostComponent<int, TestInputSelect<int>>
|
||||
{
|
||||
EditContext = new EditContext(model),
|
||||
ValueExpression = () => model.NotNullableInt,
|
||||
AdditionalAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "DisplayName", "Some number" }
|
||||
}
|
||||
};
|
||||
var fieldIdentifier = FieldIdentifier.Create(() => model.NotNullableInt);
|
||||
var inputSelectComponent = await InputRenderer.RenderAndGetComponent(rootComponent);
|
||||
|
||||
// Act
|
||||
await inputSelectComponent.SetCurrentValueAsStringAsync("invalidNumber");
|
||||
|
||||
// Assert
|
||||
var validationMessages = rootComponent.EditContext.GetValidationMessages(fieldIdentifier);
|
||||
Assert.NotEmpty(validationMessages);
|
||||
Assert.Contains("The Some number field is not valid.", validationMessages);
|
||||
}
|
||||
|
||||
enum TestEnum
|
||||
|
|
@ -218,25 +225,13 @@ namespace Microsoft.AspNetCore.Components.Forms
|
|||
get => base.CurrentValueAsString;
|
||||
set => base.CurrentValueAsString = value;
|
||||
}
|
||||
}
|
||||
|
||||
class TestInputSelectHostComponent<TValue> : AutoRenderComponent
|
||||
{
|
||||
public EditContext EditContext { get; set; }
|
||||
|
||||
public Expression<Func<TValue>> ValueExpression { get; set; }
|
||||
|
||||
protected override void BuildRenderTree(RenderTreeBuilder builder)
|
||||
public async Task SetCurrentValueAsStringAsync(string value)
|
||||
{
|
||||
builder.OpenComponent<CascadingValue<EditContext>>(0);
|
||||
builder.AddAttribute(1, "Value", EditContext);
|
||||
builder.AddAttribute(2, "ChildContent", new RenderFragment(childBuilder =>
|
||||
{
|
||||
childBuilder.OpenComponent<TestInputSelect<TValue>>(0);
|
||||
childBuilder.AddAttribute(0, "ValueExpression", ValueExpression);
|
||||
childBuilder.CloseComponent();
|
||||
}));
|
||||
builder.CloseComponent();
|
||||
// This is equivalent to the subclass writing to CurrentValueAsString
|
||||
// (e.g., from @bind), except to simplify the test code there's an InvokeAsync
|
||||
// here. In production code it wouldn't normally be required because @bind
|
||||
// calls run on the sync context anyway.
|
||||
await InvokeAsync(() => { base.CurrentValueAsString = value; });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using Microsoft.AspNetCore.Components.Rendering;
|
||||
using Microsoft.AspNetCore.Components.Test.Helpers;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.Forms
|
||||
{
|
||||
internal class TestInputHostComponent<TValue, TComponent> : AutoRenderComponent where TComponent : InputBase<TValue>
|
||||
{
|
||||
public Dictionary<string, object> AdditionalAttributes { get; set; }
|
||||
|
||||
public EditContext EditContext { get; set; }
|
||||
|
||||
public TValue Value { get; set; }
|
||||
|
||||
public Action<TValue> ValueChanged { get; set; }
|
||||
|
||||
public Expression<Func<TValue>> ValueExpression { get; set; }
|
||||
|
||||
protected override void BuildRenderTree(RenderTreeBuilder builder)
|
||||
{
|
||||
builder.OpenComponent<CascadingValue<EditContext>>(0);
|
||||
builder.AddAttribute(1, "Value", EditContext);
|
||||
builder.AddAttribute(2, "ChildContent", new RenderFragment(childBuilder =>
|
||||
{
|
||||
childBuilder.OpenComponent<TComponent>(0);
|
||||
childBuilder.AddAttribute(0, "Value", Value);
|
||||
childBuilder.AddAttribute(1, "ValueChanged",
|
||||
EventCallback.Factory.Create(this, ValueChanged));
|
||||
childBuilder.AddAttribute(2, "ValueExpression", ValueExpression);
|
||||
childBuilder.AddMultipleAttributes(3, AdditionalAttributes);
|
||||
childBuilder.CloseComponent();
|
||||
}));
|
||||
builder.CloseComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -44,6 +44,15 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
|
|||
Browser.Equal("1", () => Browser.FindElement(By.Id("count")).Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PrerenderingWaitsForAsyncDisposableComponents()
|
||||
{
|
||||
Navigate("/prerendered/prerendered-async-disposal");
|
||||
|
||||
// Prerendered output shows "not connected"
|
||||
Browser.Equal("After async disposal", () => Browser.FindElement(By.Id("disposal-message")).Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanUseJSInteropFromOnAfterRenderAsync()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -216,6 +216,10 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
Browser.Equal("Fourth", () => boundValue.Text);
|
||||
Assert.Equal("Fourth choice", target.SelectedOption.Text);
|
||||
|
||||
// verify that changing an option value and selected value at the same time works.
|
||||
Browser.FindElement(By.Id("change-variable-value")).Click();
|
||||
Browser.Equal("Sixth", () => boundValue.Text);
|
||||
|
||||
// Verify we can select options whose value is empty
|
||||
// https://github.com/dotnet/aspnetcore/issues/17735
|
||||
target.SelectByText("Empty value");
|
||||
|
|
|
|||
|
|
@ -115,6 +115,24 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
Browser.Equal("onmousedown,onmouseup,", () => output.Text);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void Toggle_CanTrigger()
|
||||
{
|
||||
Browser.MountTestComponent<ToggleEventComponent>();
|
||||
|
||||
var detailsToggle = Browser.FindElement(By.Id("details-toggle"));
|
||||
|
||||
var output = Browser.FindElement(By.Id("output"));
|
||||
Assert.Equal(string.Empty, output.Text);
|
||||
|
||||
// Click
|
||||
var actions = new Actions(Browser).Click(detailsToggle);
|
||||
|
||||
actions.Perform();
|
||||
Browser.Equal("ontoggle,", () => output.Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PointerDown_CanTrigger()
|
||||
{
|
||||
|
|
@ -270,6 +288,17 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
Browser.Contains(expectedMessage, () => errorLog.Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RenderAttributesBeforeConnectedCallBack()
|
||||
{
|
||||
Browser.MountTestComponent<RenderAttributesBeforeConnectedCallback>();
|
||||
var element = Browser.FindElement(By.TagName("custom-web-component-data-from-attribute"));
|
||||
|
||||
var expectedContent = "success";
|
||||
|
||||
Browser.Contains(expectedContent, () => element.Text);
|
||||
}
|
||||
|
||||
void SendKeysSequentially(IWebElement target, string text)
|
||||
{
|
||||
// Calling it for each character works around some chars being skipped
|
||||
|
|
|
|||
|
|
@ -109,6 +109,17 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
Assert.Equal(expected, app.FindElement(By.Id("test-info")).Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanArriveAtPageWithCatchAllParameter()
|
||||
{
|
||||
SetUrlViaPushState("/WithCatchAllParameter/life/the/universe/and/everything%20%3D%2042");
|
||||
|
||||
var app = Browser.MountTestComponent<TestRouter>();
|
||||
var expected = $"The answer: life/the/universe/and/everything = 42.";
|
||||
|
||||
Assert.Equal(expected, app.FindElement(By.Id("test-info")).Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanArriveAtNonDefaultPage()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
@implements IAsyncDisposable
|
||||
@code{
|
||||
[Parameter] public EventCallback<string> SetMessage { get; set; }
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
await SetMessage.InvokeAsync("Before async disposal");
|
||||
await Task.Yield();
|
||||
await SetMessage.InvokeAsync("After async disposal");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
@page "/prerendered-async-disposal"
|
||||
|
||||
<p>
|
||||
This component shows that prerendering will work for components that implement IAsyncDisposable to finish
|
||||
disposing before rendering the output as html.
|
||||
</p>
|
||||
|
||||
<p id="disposal-message">@_message</p>
|
||||
|
||||
@if (!_hideComponent)
|
||||
{
|
||||
<AsyncDisposableComponent SetMessage="@SetMessage" />
|
||||
}
|
||||
|
||||
@code {
|
||||
private bool _hideComponent = false;
|
||||
private string _message = "Uninitialized";
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await Task.Yield();
|
||||
_hideComponent = true;
|
||||
}
|
||||
|
||||
private void SetMessage(string message) => _message = message;
|
||||
}
|
||||
|
|
@ -242,6 +242,7 @@
|
|||
<optgroup label="Some choices">
|
||||
<!-- Show it also works with optgroup -->
|
||||
<option value=@string.Empty>Empty value</option>
|
||||
<option value="@variableValue">Variable value</option>
|
||||
<option value=@SelectableValue.First>First choice</option>
|
||||
<option value=@SelectableValue.Second>Second choice</option>
|
||||
<option value=@SelectableValue.Third>Third choice</option>
|
||||
|
|
@ -253,6 +254,7 @@
|
|||
</select>
|
||||
<span id="select-box-value">@selectValue</span>
|
||||
<button id="select-box-add-option" @onclick="AddAndSelectNewSelectOption">Add and select new item</button>
|
||||
<button id="change-variable-value" @onclick="ChangeVariableValueToSixth">Change variable value to Sixth.</button>
|
||||
</p>
|
||||
|
||||
<h2>Select (markup block)</h2>
|
||||
|
|
@ -383,13 +385,21 @@
|
|||
DateTime? timeStepTextboxNullableDateTimeValue = null;
|
||||
|
||||
bool includeFourthOption = false;
|
||||
enum SelectableValue { First, Second, Third, Fourth }
|
||||
enum SelectableValue { First, Second, Third, Fourth, Fifth, Sixth }
|
||||
SelectableValue? selectValue = SelectableValue.Second;
|
||||
SelectableValue? selectMarkupValue = SelectableValue.Second;
|
||||
|
||||
SelectableValue variableValue = SelectableValue.Fifth;
|
||||
|
||||
void AddAndSelectNewSelectOption()
|
||||
{
|
||||
includeFourthOption = true;
|
||||
selectValue = SelectableValue.Fourth;
|
||||
}
|
||||
|
||||
void ChangeVariableValueToSixth()
|
||||
{
|
||||
selectValue = SelectableValue.Sixth;
|
||||
variableValue = SelectableValue.Sixth;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@
|
|||
<option value="BasicTestApp.RedTextComponent">Red text</option>
|
||||
<option value="BasicTestApp.ReliabilityComponent">Server reliability component</option>
|
||||
<option value="BasicTestApp.RenderFragmentToggler">Render fragment renderer</option>
|
||||
<option value="BasicTestApp.RenderAttributesBeforeConnectedCallback">Render attributes before ConnectedCallback</option>
|
||||
<option value="BasicTestApp.ReorderingFocusComponent">Reordering focus retention</option>
|
||||
<option value="BasicTestApp.RouterTest.NavigationManagerComponent">NavigationManager Test</option>
|
||||
<option value="BasicTestApp.RouterTest.TestRouter">Router</option>
|
||||
|
|
@ -82,6 +83,7 @@
|
|||
<option value="BasicTestApp.TextOnlyComponent">Plain text</option>
|
||||
<option value="BasicTestApp.TouchEventComponent">Touch events</option>
|
||||
<option value="BasicTestApp.SelectVariantsComponent">Select with component options</option>
|
||||
<option value="BasicTestApp.ToggleEventComponent">Toggle Event</option>
|
||||
</select>
|
||||
|
||||
<span id="runtime-info"><code><tt>@System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription</tt></code></span>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
<h1>Render Attributes Before connectedCallback</h1>
|
||||
|
||||
<p>
|
||||
When the connectedcallback event fires, it's nice to have the attributes of the HTML element set already,
|
||||
as data is usually passed to the component using custom attributes.
|
||||
</p>
|
||||
|
||||
|
||||
<custom-web-component-data-from-attribute myattribute="@attributeString"></custom-web-component-data-from-attribute>
|
||||
|
||||
|
||||
@code {
|
||||
string attributeString = "success";
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
@page "/WithCatchAllParameter/{*theAnswer}"
|
||||
<div id="test-info">The answer: @TheAnswer.</div>
|
||||
|
||||
@code
|
||||
{
|
||||
[Parameter] public string TheAnswer { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<div>
|
||||
<p>
|
||||
Output: <span id="output">@message</span>
|
||||
</p>
|
||||
|
||||
|
||||
<p>Open the details.</p>
|
||||
|
||||
<details id="details-toggle" @ontoggle="OnToggle">
|
||||
<summary>Summary</summary>
|
||||
<p></p>
|
||||
<p>Detailed content</p>
|
||||
</details>
|
||||
|
||||
</div>
|
||||
|
||||
@code {
|
||||
string message { get; set; }
|
||||
|
||||
void OnToggle(EventArgs e)
|
||||
{
|
||||
message += "ontoggle,";
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
<!-- Used for specific test cases -->
|
||||
<script src="js/jsinteroptests.js"></script>
|
||||
<script src="js/renderattributestest.js"></script>
|
||||
<script src="js/webComponentPerformingJsInterop.js"></script>
|
||||
|
||||
<script>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
// This web component is used from the RenderAttributesBeforeConnectedCallback test case
|
||||
|
||||
window.customElements.define('custom-web-component-data-from-attribute', class extends HTMLElement {
|
||||
connectedCallback() {
|
||||
let myattribute = this.getAttribute('myattribute') || 'failed';
|
||||
|
||||
this.innerHTML = myattribute;
|
||||
}
|
||||
});
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
<!-- Used for specific test cases -->
|
||||
<script src="js/jsinteroptests.js"></script>
|
||||
<script src="js/renderattributestest.js"></script>
|
||||
<script src="js/webComponentPerformingJsInterop.js"></script>
|
||||
|
||||
<div id="blazor-error-ui">
|
||||
|
|
|
|||
|
|
@ -71,7 +71,9 @@ namespace Microsoft.AspNetCore.Cryptography
|
|||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
|
||||
#if NETSTANDARD2_0
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
#endif
|
||||
public static bool TimeConstantBuffersAreEqual(byte* bufA, byte* bufB, uint count)
|
||||
{
|
||||
bool areEqual = true;
|
||||
|
|
|
|||
|
|
@ -141,7 +141,9 @@ namespace Microsoft.AspNetCore.Cryptography.SafeHandles
|
|||
|
||||
// http://msdn.microsoft.com/en-us/library/ms683152(v=vs.85).aspx
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
#if NETSTANDARD2_0
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
#endif
|
||||
[DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode)]
|
||||
internal static extern bool FreeLibrary(IntPtr hModule);
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,9 @@ namespace Microsoft.AspNetCore.Cryptography.SafeHandles
|
|||
return newHandle;
|
||||
}
|
||||
|
||||
#if NETSTANDARD2_0
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||
#endif
|
||||
private void AllocateImpl(IntPtr cb)
|
||||
{
|
||||
handle = Marshal.AllocHGlobal(cb); // actually calls LocalAlloc
|
||||
|
|
|
|||
|
|
@ -12,14 +12,18 @@ namespace Microsoft.AspNetCore.Cryptography
|
|||
internal unsafe static class UnsafeBufferUtil
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#if NETSTANDARD2_0
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
#endif
|
||||
public static void BlockCopy(void* from, void* to, int byteCount)
|
||||
{
|
||||
BlockCopy(from, to, checked((uint)byteCount)); // will be checked before invoking the delegate
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#if NETSTANDARD2_0
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
#endif
|
||||
public static void BlockCopy(void* from, void* to, uint byteCount)
|
||||
{
|
||||
if (byteCount != 0)
|
||||
|
|
@ -28,7 +32,9 @@ namespace Microsoft.AspNetCore.Cryptography
|
|||
}
|
||||
}
|
||||
|
||||
#if NETSTANDARD2_0
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||
#endif
|
||||
public static void BlockCopy(LocalAllocHandle from, void* to, uint byteCount)
|
||||
{
|
||||
bool refAdded = false;
|
||||
|
|
@ -46,7 +52,9 @@ namespace Microsoft.AspNetCore.Cryptography
|
|||
}
|
||||
}
|
||||
|
||||
#if NETSTANDARD2_0
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||
#endif
|
||||
public static void BlockCopy(void* from, LocalAllocHandle to, uint byteCount)
|
||||
{
|
||||
bool refAdded = false;
|
||||
|
|
@ -64,7 +72,9 @@ namespace Microsoft.AspNetCore.Cryptography
|
|||
}
|
||||
}
|
||||
|
||||
#if NETSTANDARD2_0
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||
#endif
|
||||
public static void BlockCopy(LocalAllocHandle from, LocalAllocHandle to, IntPtr length)
|
||||
{
|
||||
if (length == IntPtr.Zero)
|
||||
|
|
@ -116,7 +126,9 @@ namespace Microsoft.AspNetCore.Cryptography
|
|||
/// Securely clears a memory buffer.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#if NETSTANDARD2_0
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
#endif
|
||||
public static void SecureZeroMemory(byte* buffer, int byteCount)
|
||||
{
|
||||
SecureZeroMemory(buffer, checked((uint)byteCount));
|
||||
|
|
@ -126,7 +138,9 @@ namespace Microsoft.AspNetCore.Cryptography
|
|||
/// Securely clears a memory buffer.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#if NETSTANDARD2_0
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
#endif
|
||||
public static void SecureZeroMemory(byte* buffer, uint byteCount)
|
||||
{
|
||||
if (byteCount != 0)
|
||||
|
|
@ -145,7 +159,9 @@ namespace Microsoft.AspNetCore.Cryptography
|
|||
/// Securely clears a memory buffer.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#if NETSTANDARD2_0
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
#endif
|
||||
public static void SecureZeroMemory(byte* buffer, ulong byteCount)
|
||||
{
|
||||
if (byteCount != 0)
|
||||
|
|
@ -163,7 +179,9 @@ namespace Microsoft.AspNetCore.Cryptography
|
|||
/// <summary>
|
||||
/// Securely clears a memory buffer.
|
||||
/// </summary>
|
||||
#if NETSTANDARD2_0
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
#endif
|
||||
public static void SecureZeroMemory(byte* buffer, IntPtr length)
|
||||
{
|
||||
if (sizeof(IntPtr) == 4)
|
||||
|
|
|
|||
|
|
@ -82,13 +82,17 @@ namespace Microsoft.AspNetCore.Cryptography
|
|||
[In] uint dwFlags);
|
||||
|
||||
[DllImport(BCRYPT_LIB, CallingConvention = CallingConvention.Winapi)]
|
||||
#if NETSTANDARD2_0
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
#endif
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa375399(v=vs.85).aspx
|
||||
internal static extern int BCryptDestroyHash(
|
||||
[In] IntPtr hHash);
|
||||
|
||||
[DllImport(BCRYPT_LIB, CallingConvention = CallingConvention.Winapi)]
|
||||
#if NETSTANDARD2_0
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
#endif
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa375404(v=vs.85).aspx
|
||||
internal static extern int BCryptDestroyKey(
|
||||
[In] IntPtr hKey);
|
||||
|
|
@ -240,7 +244,9 @@ namespace Microsoft.AspNetCore.Cryptography
|
|||
*/
|
||||
|
||||
[DllImport(NCRYPT_LIB, CallingConvention = CallingConvention.Winapi)]
|
||||
#if NETSTANDARD2_0
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
#endif
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/hh706799(v=vs.85).aspx
|
||||
internal static extern int NCryptCloseProtectionDescriptor(
|
||||
[In] IntPtr hDescriptor);
|
||||
|
|
|
|||
|
|
@ -78,7 +78,9 @@ namespace Microsoft.AspNetCore.DataProtection.Cng
|
|||
};
|
||||
var dataOut = default(DATA_BLOB);
|
||||
|
||||
#if NETSTANDARD2_0
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -168,7 +170,9 @@ namespace Microsoft.AspNetCore.DataProtection.Cng
|
|||
{
|
||||
var handleAcquired = false;
|
||||
|
||||
#if NETSTANDARD2_0
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -217,7 +221,9 @@ namespace Microsoft.AspNetCore.DataProtection.Cng
|
|||
};
|
||||
var dataOut = default(DATA_BLOB);
|
||||
|
||||
#if NETSTANDARD2_0
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -290,7 +296,9 @@ namespace Microsoft.AspNetCore.DataProtection.Cng
|
|||
{
|
||||
var handleAcquired = false;
|
||||
|
||||
#if NETSTANDARD2_0
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
<PropertyGroup>
|
||||
<ContainsFunctionalTestAssets>true</ContainsFunctionalTestAssets>
|
||||
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
|
||||
|
||||
<!-- https://github.com/dotnet/aspnetcore/issues/24182 -->
|
||||
<BuildHelixPayload>false</BuildHelixPayload>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ namespace InteropTestsClient
|
|||
services.AddLogging(configure =>
|
||||
{
|
||||
configure.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
|
||||
configure.AddConsole(loggerOptions =>
|
||||
configure.AddSimpleConsole(loggerOptions =>
|
||||
{
|
||||
loggerOptions.IncludeScopes = true;
|
||||
loggerOptions.DisableColors = true;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ namespace InteropTestsWebsite
|
|||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureLogging(builder =>
|
||||
{
|
||||
builder.AddConsole(o => o.DisableColors = true);
|
||||
builder.AddSimpleConsole(o => o.DisableColors = true);
|
||||
builder.SetMinimumLevel(LogLevel.Trace);
|
||||
})
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@
|
|||
"src\\Servers\\Kestrel\\Kestrel\\src\\Microsoft.AspNetCore.Server.Kestrel.csproj",
|
||||
"src\\Servers\\Kestrel\\Core\\src\\Microsoft.AspNetCore.Server.Kestrel.Core.csproj",
|
||||
"src\\Servers\\Kestrel\\Transport.Sockets\\src\\Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj",
|
||||
"src\\Servers\\Connections.Abstractions\\src\\Microsoft.AspNetCore.Connections.Abstractions.csproj"
|
||||
"src\\Servers\\Connections.Abstractions\\src\\Microsoft.AspNetCore.Connections.Abstractions.csproj",
|
||||
"src\\ObjectPool\\src\\Microsoft.Extensions.ObjectPool.csproj"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ using Microsoft.Extensions.Configuration;
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.ObjectPool;
|
||||
|
||||
namespace Microsoft.AspNetCore.Hosting
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.ObjectPool;
|
||||
|
||||
namespace Microsoft.AspNetCore.Hosting
|
||||
{
|
||||
|
|
|
|||
|
|
@ -19,9 +19,10 @@ namespace Microsoft.AspNetCore.Hosting
|
|||
/// <param name="timeout">The timeout for stopping gracefully. Once expired the
|
||||
/// server may terminate any remaining active connections.</param>
|
||||
/// <returns>A <see cref="Task"/> that completes when the <see cref="IWebHost"/> stops.</returns>
|
||||
public static Task StopAsync(this IWebHost host, TimeSpan timeout)
|
||||
public static async Task StopAsync(this IWebHost host, TimeSpan timeout)
|
||||
{
|
||||
return host.StopAsync(new CancellationTokenSource(timeout).Token);
|
||||
using var cts = new CancellationTokenSource(timeout);
|
||||
await host.StopAsync(cts.Token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ using Microsoft.Extensions.Hosting;
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
using Microsoft.Extensions.ObjectPool;
|
||||
using Xunit;
|
||||
|
||||
[assembly: HostingStartup(typeof(WebHostBuilderTests.TestHostingStartup))]
|
||||
|
|
|
|||
|
|
@ -198,7 +198,6 @@ namespace Microsoft.AspNetCore.Hosting
|
|||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[QuarantinedTest]
|
||||
public async Task WebHostStopAsyncUsesDefaultTimeoutIfGivenTokenDoesNotFire()
|
||||
{
|
||||
var data = new Dictionary<string, string>
|
||||
|
|
@ -313,7 +312,6 @@ namespace Microsoft.AspNetCore.Hosting
|
|||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[QuarantinedTest]
|
||||
public void WebHostApplicationLifetimeEventsOrderedCorrectlyDuringShutdown()
|
||||
{
|
||||
using (var host = CreateBuilder()
|
||||
|
|
|
|||
|
|
@ -80,9 +80,9 @@ namespace Microsoft.AspNetCore.Http
|
|||
{ Encoding.BigEndianUnicode },
|
||||
{ Encoding.Unicode },
|
||||
{ Encoding.UTF32 },
|
||||
#pragma warning disable CS0618, MSLIB0001 // Type or member is obsolete
|
||||
#pragma warning disable CS0618, SYSLIB0001 // Type or member is obsolete
|
||||
{ Encoding.UTF7 },
|
||||
#pragma warning restore CS0618, MSLIB0001 // Type or member is obsolete
|
||||
#pragma warning restore CS0618, SYSLIB0001 // Type or member is obsolete
|
||||
{ Encoding.UTF8 }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -276,9 +276,9 @@ namespace Microsoft.AspNetCore.Http.Features
|
|||
private static Encoding FilterEncoding(Encoding? encoding)
|
||||
{
|
||||
// UTF-7 is insecure and should not be honored. UTF-8 will succeed for most cases.
|
||||
#pragma warning disable CS0618, MSLIB0001 // Type or member is obsolete
|
||||
#pragma warning disable CS0618, SYSLIB0001 // Type or member is obsolete
|
||||
if (encoding == null || Encoding.UTF7.Equals(encoding))
|
||||
#pragma warning restore CS0618, MSLIB0001 // Type or member is obsolete
|
||||
#pragma warning restore CS0618, SYSLIB0001 // Type or member is obsolete
|
||||
{
|
||||
return Encoding.UTF8;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.Http
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// This calls StartAsync if it has not previoulsy been called.
|
||||
/// This calls StartAsync if it has not previously been called.
|
||||
/// It will complete the adapted pipe if it exists.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
|
|
@ -128,6 +128,11 @@ namespace Microsoft.AspNetCore.Http
|
|||
return;
|
||||
}
|
||||
|
||||
if (!_started)
|
||||
{
|
||||
await StartAsync();
|
||||
}
|
||||
|
||||
_completed = true;
|
||||
|
||||
if (_pipeWriter != null)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
// 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.Buffers;
|
||||
using System.IO;
|
||||
using System.IO.Pipelines;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Http.Features
|
||||
{
|
||||
public class StreamResponseBodyFeatureTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task CompleteAsyncCallsStartAsync()
|
||||
{
|
||||
// Arrange
|
||||
var stream = new MemoryStream();
|
||||
var streamResponseBodyFeature = new TestStreamResponseBodyFeature(stream);
|
||||
|
||||
// Act
|
||||
await streamResponseBodyFeature.CompleteAsync();
|
||||
|
||||
//Assert
|
||||
Assert.Equal(1, streamResponseBodyFeature.StartCalled);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CompleteAsyncWontCallsStartAsyncIfAlreadyStarted()
|
||||
{
|
||||
// Arrange
|
||||
var stream = new MemoryStream();
|
||||
var streamResponseBodyFeature = new TestStreamResponseBodyFeature(stream);
|
||||
await streamResponseBodyFeature.StartAsync();
|
||||
|
||||
// Act
|
||||
await streamResponseBodyFeature.CompleteAsync();
|
||||
|
||||
//Assert
|
||||
Assert.Equal(1, streamResponseBodyFeature.StartCalled);
|
||||
}
|
||||
}
|
||||
|
||||
public class TestStreamResponseBodyFeature : StreamResponseBodyFeature
|
||||
{
|
||||
public TestStreamResponseBodyFeature(Stream stream)
|
||||
: base(stream)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override Task StartAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
StartCalled++;
|
||||
return base.StartAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public int StartCalled { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -47,10 +47,10 @@ namespace Microsoft.AspNetCore.WebUtilities
|
|||
|
||||
public FormPipeReader(PipeReader pipeReader, Encoding encoding)
|
||||
{
|
||||
#pragma warning disable CS0618, MSLIB0001 // Type or member is obsolete
|
||||
#pragma warning disable CS0618, SYSLIB0001 // Type or member is obsolete
|
||||
if (encoding == Encoding.UTF7)
|
||||
{
|
||||
#pragma warning restore CS0618, MSLIB0001 // Type or member is obsolete
|
||||
#pragma warning restore CS0618, SYSLIB0001 // Type or member is obsolete
|
||||
throw new ArgumentException("UTF7 is unsupported and insecure. Please select a different encoding.");
|
||||
}
|
||||
|
||||
|
|
@ -271,7 +271,7 @@ namespace Microsoft.AspNetCore.WebUtilities
|
|||
var keyValueReader = new SequenceReader<byte>(keyValuePair);
|
||||
ReadOnlySequence<byte> value;
|
||||
|
||||
if (keyValueReader.TryReadTo(out var key, equalsDelimiter))
|
||||
if (keyValueReader.TryReadTo(out ReadOnlySequence<byte> key, equalsDelimiter))
|
||||
{
|
||||
if (key.Length > KeyLengthLimit)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@ namespace Microsoft.AspNetCore.WebUtilities
|
|||
MediaTypeHeaderValue.TryParse(section.ContentType, out var sectionMediaType);
|
||||
|
||||
var streamEncoding = sectionMediaType?.Encoding;
|
||||
#pragma warning disable CS0618, MSLIB0001 // Type or member is obsolete
|
||||
#pragma warning disable CS0618, SYSLIB0001 // Type or member is obsolete
|
||||
if (streamEncoding == null || streamEncoding == Encoding.UTF7)
|
||||
#pragma warning restore CS0618, MSLIB0001 // Type or member is obsolete
|
||||
#pragma warning restore CS0618, SYSLIB0001 // Type or member is obsolete
|
||||
{
|
||||
streamEncoding = Encoding.UTF8;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
<button class="btn btn-primary" type="submit">Download</button>
|
||||
</form>
|
||||
<p>
|
||||
<a id="delete" asp-page="DeletePersonalData" class="btn btn-primary">Delete</a>
|
||||
<a id="delete" asp-page="DeletePersonalData" class="btn btn-secondary">Delete</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ using Microsoft.AspNetCore.Hosting;
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Xunit;
|
||||
|
|
@ -122,6 +123,7 @@ namespace Microsoft.AspNetCore.Diagnostics
|
|||
}
|
||||
|
||||
[Fact]
|
||||
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/24146")]
|
||||
public async Task ClearsResponseBuffer_BeforeRequestIsReexecuted()
|
||||
{
|
||||
var expectedResponseBody = "New response body";
|
||||
|
|
|
|||
|
|
@ -132,6 +132,7 @@ namespace Templates.Test
|
|||
}
|
||||
|
||||
[Fact]
|
||||
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23992")]
|
||||
public async Task BlazorWasmStandalonePwaTemplate_Works()
|
||||
{
|
||||
var project = await ProjectFactory.GetOrCreateProject("blazorstandalonepwa", Output);
|
||||
|
|
@ -251,6 +252,7 @@ namespace Templates.Test
|
|||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23992")]
|
||||
// LocalDB doesn't work on non Windows platforms
|
||||
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
|
||||
public Task BlazorWasmHostedTemplate_IndividualAuth_Works_WithLocalDB()
|
||||
|
|
@ -259,6 +261,7 @@ namespace Templates.Test
|
|||
}
|
||||
|
||||
[Fact]
|
||||
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23992")]
|
||||
public Task BlazorWasmHostedTemplate_IndividualAuth_Works_WithOutLocalDB()
|
||||
{
|
||||
return BlazorWasmHostedTemplate_IndividualAuth_Works(false);
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ namespace Templates.Test.Helpers
|
|||
["ASPNETCORE_Logging__Console__LogLevel__Default"] = "Debug",
|
||||
["ASPNETCORE_Logging__Console__LogLevel__System"] = "Debug",
|
||||
["ASPNETCORE_Logging__Console__LogLevel__Microsoft"] = "Debug",
|
||||
["ASPNETCORE_Logging__Console__IncludeScopes"] = "true",
|
||||
["ASPNETCORE_Logging__Console__FormatterOptions__IncludeScopes"] = "true",
|
||||
};
|
||||
|
||||
var launchSettingsJson = Path.Combine(TemplateOutputDir, "Properties", "launchSettings.json");
|
||||
|
|
@ -185,7 +185,7 @@ namespace Templates.Test.Helpers
|
|||
["ASPNETCORE_Logging__Console__LogLevel__Default"] = "Debug",
|
||||
["ASPNETCORE_Logging__Console__LogLevel__System"] = "Debug",
|
||||
["ASPNETCORE_Logging__Console__LogLevel__Microsoft"] = "Debug",
|
||||
["ASPNETCORE_Logging__Console__IncludeScopes"] = "true",
|
||||
["ASPNETCORE_Logging__Console__FormatterOptions__IncludeScopes"] = "true",
|
||||
};
|
||||
|
||||
var projectDll = $"{ProjectName}.dll";
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ app {
|
|||
height: 3.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.main {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ app {
|
|||
height: 3.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.main {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging;
|
|||
namespace ComponentsWebAssembly_CSharp.Server.Pages
|
||||
{
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
[IgnoreAntiforgeryToken]
|
||||
public class ErrorModel : PageModel
|
||||
{
|
||||
public string RequestId { get; set; }
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue