merge release/3.1 to master

This commit is contained in:
wtgodbe 2019-10-16 13:23:32 -07:00
commit ba2ed9fae9
139 changed files with 2001 additions and 1516 deletions

View File

@ -46,7 +46,8 @@
<!-- Contact email address for NuGet packages and Linux installers. -->
<MaintainerEmail>nugetaspnet@microsoft.com</MaintainerEmail>
<PackageIconUrl>https://go.microsoft.com/fwlink/?LinkID=288859</PackageIconUrl>
<PackageIcon>packageIcon.png</PackageIcon>
<PackageIconFullPath>$(MSBuildThisFileDirectory)packageIcon.png</PackageIconFullPath>
<PackageProjectUrl>https://asp.net</PackageProjectUrl>
<NuspecBasePath>$(MSBuildProjectDirectory)</NuspecBasePath>
@ -55,6 +56,10 @@
<DefaultNetCoreTargetFramework>netcoreapp5.0</DefaultNetCoreTargetFramework>
</PropertyGroup>
<ItemGroup>
<None Include="$(PackageIconFullPath)" Pack="true" PackagePath="\"/>
</ItemGroup>
<!-- Warnings and errors -->
<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
@ -90,7 +95,7 @@
<TargetingPackInstallerBaseName>aspnetcore-targeting-pack</TargetingPackInstallerBaseName>
<!-- Used to only produce targeting pack installers/packages once per major.minor. -->
<IsTargetingPackBuilding Condition="'$(IsServicingBuild)' == 'true' AND '$(DotNetBuildFromSource)' != 'true'">false</IsTargetingPackBuilding>
<IsTargetingPackBuilding Condition="'$(AspNetCorePatchVersion)' != '0' OR '$(DotNetBuildFromSource)' == 'true'">false</IsTargetingPackBuilding>
<!--
Archives and installers using this prefix are intended for internal-use only.

View File

@ -58,7 +58,8 @@
<Import Project="eng\Baseline.Designer.props" />
<PropertyGroup Condition=" '$(IsPackable)' != 'false' AND '$(AspNetCorePatchVersion)' != '0' ">
<PropertyGroup
Condition=" '$(IsPackable)' != 'false' AND '$(AspNetCorePatchVersion)' != '0' AND '$(DisableServicingFeatures)' != 'true' ">
<IsPackageInThisPatch Condition="'$(IsPackageInThisPatch)' == ''">$(PackagesInPatch.Contains(' $(PackageId);'))</IsPackageInThisPatch>
</PropertyGroup>
@ -104,6 +105,12 @@
<Compile Include="$(SharedSourceRoot)ReferenceAssemblyInfo.cs" LinkBase="Properties" />
</ItemGroup>
<PropertyGroup Condition="'$(Language)' == 'C#'">
<!-- Reference assemblies should always use Major.Minor.0.0 for assembly versions even during servicing. Only the package version should be updated. -->
<!-- Pinning the implementation assemblies at Major.Minor.0.0 as we figure out compiling against ref assemblies. -->
<AssemblyVersion>$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion).0.0</AssemblyVersion>
</PropertyGroup>
<ItemGroup>
<KnownFrameworkReference Update="Microsoft.NETCore.App">
<!-- Always update the 'latest version', whether the repo is servicing or not. -->

View File

@ -3,6 +3,7 @@
<packageSources>
<clear />
<add key="dotnet-core" value="https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json" />
<add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" />
<add key="aspnet-blazor" value="https://dotnetfeed.blob.core.windows.net/aspnet-blazor/index.json" />
<add key="aspnet-extensions" value="https://dotnetfeed.blob.core.windows.net/aspnet-extensions/index.json" />
<add key="aspnet-entityframeworkcore" value="https://dotnetfeed.blob.core.windows.net/aspnet-entityframeworkcore/index.json" />

File diff suppressed because it is too large Load Diff

View File

@ -1,138 +1,91 @@
<!--
This file contains a list of all the packages and their versions which were released in the last servicing
build of ASP.NET Core 2.2.x. Update this list when preparing for a new patch.
This file contains a list of all the packages and their versions which were released in ASP.NET Core 3.0.0.
Update this list when preparing for a new patch.
-->
<Baseline Version="2.2.7">
<Package Id="dotnet-dev-certs" Version="2.2.0" />
<Package Id="dotnet-sql-cache" Version="2.2.0" />
<Package Id="dotnet-user-secrets" Version="2.2.0" />
<Package Id="dotnet-watch" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Antiforgery" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.ApiAuthorization.IdentityServer" Version="2.2.0-preview-35687" />
<Package Id="Microsoft.AspNetCore.ApplicationInsights.HostingStartup" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.AspNetCoreModule" Version="2.2.7" />
<Package Id="Microsoft.AspNetCore.AspNetCoreModuleV2" Version="2.2.7" />
<Package Id="Microsoft.AspNetCore.Authentication.Abstractions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Authentication.AzureAD.UI" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Authentication.AzureADB2C.UI" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Authentication.Core" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Authentication.Facebook" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Authentication.Google" Version="2.2.2" />
<Package Id="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Authentication.OAuth" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Authentication.Twitter" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Authentication.WsFederation" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Authorization.Policy" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Authorization" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.AzureAppServices.HostingStartup" Version="2.2.5" />
<Package Id="Microsoft.AspNetCore.AzureAppServicesIntegration" Version="2.2.5" />
<Package Id="Microsoft.AspNetCore.Connections.Abstractions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.CookiePolicy" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Cors" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Cryptography.Internal" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.DataProtection.Abstractions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.DataProtection.AzureKeyVault" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.DataProtection.AzureStorage" Version="2.2.7" />
<Package Id="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.DataProtection.Extensions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="2.2.5" />
<Package Id="Microsoft.AspNetCore.DataProtection.SystemWeb" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.DataProtection" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Diagnostics.Abstractions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="2.2.1" />
<Package Id="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Diagnostics" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.HostFiltering" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Hosting.Server.Abstractions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Hosting.WindowsServices" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
<Package Id="Microsoft.AspNetCore.Html.Abstractions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Http.Connections.Client" Version="1.1.0" />
<Package Id="Microsoft.AspNetCore.Http.Connections.Common" Version="1.1.0" />
<Package Id="Microsoft.AspNetCore.Http.Connections" Version="1.1.0" />
<Package Id="Microsoft.AspNetCore.Http.Extensions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Http.Features" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Http" Version="2.2.2" />
<Package Id="Microsoft.AspNetCore.HttpOverrides" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.HttpsPolicy" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Identity.Specification.Tests" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Identity.UI" Version="2.2.5" />
<Package Id="Microsoft.AspNetCore.Identity" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.JsonPatch" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Localization.Routing" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Localization" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.MiddlewareAnalysis" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Analyzers" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Api.Analyzers" Version="2.2.6" />
<Package Id="Microsoft.AspNetCore.Mvc.ApiExplorer" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<Package Id="Microsoft.AspNetCore.Mvc.Cors" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Mvc.DataAnnotations" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Formatters.Json" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Formatters.Xml" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Localization" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Razor.Extensions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Razor" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Mvc.RazorPages" Version="2.2.5" />
<Package Id="Microsoft.AspNetCore.Mvc.TagHelpers" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Testing" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Mvc.ViewFeatures" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.NodeServices" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Owin" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Razor.Language" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Razor.Runtime" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Razor" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.ResponseCaching.Abstractions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.ResponseCaching" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.ResponseCompression" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Rewrite" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Routing.Abstractions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Routing" Version="2.2.2" />
<Package Id="Microsoft.AspNetCore.Server.HttpSys" Version="2.2.6" />
<Package Id="Microsoft.AspNetCore.Server.IIS" Version="2.2.6" />
<Package Id="Microsoft.AspNetCore.Server.IISIntegration" Version="2.2.1" />
<Package Id="Microsoft.AspNetCore.Server.Kestrel.Core" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Server.Kestrel.Https" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets" Version="2.2.1" />
<Package Id="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.Session" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.SignalR.Client.Core" Version="1.1.0" />
<Package Id="Microsoft.AspNetCore.SignalR.Client" Version="1.1.0" />
<Package Id="Microsoft.AspNetCore.SignalR.Common" Version="1.1.0" />
<Package Id="Microsoft.AspNetCore.SignalR.Core" Version="1.1.0" />
<Package Id="Microsoft.AspNetCore.SignalR.Protocols.Json" Version="1.1.0" />
<Package Id="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="1.1.5" />
<Package Id="Microsoft.AspNetCore.SignalR.Redis" Version="1.1.5" />
<Package Id="Microsoft.AspNetCore.SignalR.Specification.Tests" Version="1.1.0" />
<Package Id="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="1.1.5" />
<Package Id="Microsoft.AspNetCore.SignalR" Version="1.1.0" />
<Package Id="Microsoft.AspNetCore.SpaServices.Extensions" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.SpaServices" Version="2.2.7" />
<Package Id="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.TestHost" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore.WebSockets" Version="2.2.1" />
<Package Id="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" />
<Package Id="Microsoft.AspNetCore" Version="2.2.0" />
<Package Id="Microsoft.CodeAnalysis.Razor" Version="2.2.0" />
<Package Id="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="2.2.0" />
<Package Id="Microsoft.Extensions.Identity.Core" Version="2.2.0" />
<Package Id="Microsoft.Extensions.Identity.Stores" Version="2.2.0" />
<Package Id="Microsoft.Net.Http.Headers" Version="2.2.0" />
<Package Id="Microsoft.Net.Sdk.Razor" Version="2.2.0" />
<Package Id="Microsoft.Owin.Security.Interop" Version="2.2.0" />
<Baseline Version="3.0.0">
<Package Id="AspNetCoreRuntime.3.0.x64" Version="3.0.0" />
<Package Id="AspNetCoreRuntime.3.0.x86" Version="3.0.0" />
<Package Id="dotnet-sql-cache" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.ApiAuthorization.IdentityServer" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.App.Runtime.win-x64" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.AzureAD.UI" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.AzureADB2C.UI" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.Certificate" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.Facebook" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.Google" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.Negotiate" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.Twitter" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.WsFederation" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authorization" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.AzureAppServices.HostingStartup" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.AzureAppServices.SiteExtension" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.AzureAppServicesIntegration" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Blazor" Version="3.0.0-preview9.19465.2" />
<Package Id="Microsoft.AspNetCore.Blazor.Build" Version="3.0.0-preview9.19465.2" />
<Package Id="Microsoft.AspNetCore.Blazor.DevServer" Version="3.0.0-preview9.19465.2" />
<Package Id="Microsoft.AspNetCore.Blazor.HttpClient" Version="3.0.0-preview9.19465.2" />
<Package Id="Microsoft.AspNetCore.Blazor.Server" Version="3.0.0-preview9.19465.2" />
<Package Id="Microsoft.AspNetCore.Blazor.Templates" Version="3.0.0-preview9.19465.2" />
<Package Id="Microsoft.AspNetCore.Components" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Components.Analyzers" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Components.Authorization" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Components.Forms" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Components.Web" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.ConcurrencyLimiter" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Connections.Abstractions" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Cryptography.Internal" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.DataProtection" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.DataProtection.Abstractions" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.DataProtection.AzureKeyVault" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.DataProtection.AzureStorage" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.DataProtection.Extensions" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.HeaderPropagation" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Hosting.WindowsServices" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Http.Connections.Client" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Http.Connections.Common" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Http.Features" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Identity.Specification.Tests" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Identity.UI" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.JsonPatch" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Metadata" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.MiddlewareAnalysis" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Testing" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.NodeServices" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Owin" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.SignalR.Client" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.SignalR.Client.Core" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.SignalR.Common" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.SignalR.Protocols.Json" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.SignalR.Specification.Tests" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.SpaServices" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.TestHost" Version="3.0.0" />
<Package Id="Microsoft.dotnet-openapi" Version="3.0.0" />
<Package Id="Microsoft.DotNet.Web.Client.ItemTemplates" Version="3.0.0" />
<Package Id="Microsoft.DotNet.Web.ItemTemplates" Version="3.0.0" />
<Package Id="Microsoft.DotNet.Web.ProjectTemplates.3.0" Version="3.0.0" />
<Package Id="Microsoft.DotNet.Web.Spa.ProjectTemplates.3.0" Version="3.0.0" />
<Package Id="Microsoft.Extensions.ApiDescription.Client" Version="3.0.0" />
<Package Id="Microsoft.Extensions.ApiDescription.Server" Version="3.0.0" />
<Package Id="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="3.0.0" />
<Package Id="Microsoft.Extensions.Identity.Core" Version="3.0.0" />
<Package Id="Microsoft.Extensions.Identity.Stores" Version="3.0.0" />
</Baseline>

View File

@ -4,8 +4,8 @@ This file contains a list of the package IDs which are patching in a given relea
CAUTION: due to limitations in MSBuild, the format of the PackagesInPatch property is picky.
When adding a new package, make sure the new line ends with a semicolon and starts with a space.
Later on, this will be checked using this condition:
Directory.Build.props checks this property using the following condition:
<IsPackageInThisPatch>$(PackagesInPatch.Contains(' $(PackageId);'))</IsPackageInThisPatch>
-->
<Project>
@ -15,59 +15,14 @@ Later on, this will be checked using this condition:
<PropertyGroup Condition=" '$(VersionPrefix)' == '3.0.1' ">
<PackagesInPatch>
</PackagesInPatch>
</PropertyGroup>
<PropertyGroup Condition=" '$(VersionPrefix)' == '2.2.2' ">
<PackagesInPatch>
@aspnet/signalr;
Microsoft.AspNetCore.AspNetCoreModuleV2;
Microsoft.AspNetCore.Authentication.Google;
Microsoft.AspNetCore.Http;
Microsoft.AspNetCore.Mvc.Core;
Microsoft.AspNetCore.Routing;
Microsoft.AspNetCore.Server.IIS;
java:signalr;
</PackagesInPatch>
</PropertyGroup>
<PropertyGroup Condition=" '$(VersionPrefix)' == '2.2.4' ">
<PackagesInPatch>
@aspnet/signalr;
Microsoft.AspNetCore.AspNetCoreModuleV2;
</PackagesInPatch>
</PropertyGroup>
<PropertyGroup Condition=" '$(VersionPrefix)' == '2.2.5' ">
<PackagesInPatch>
Microsoft.AspNetCore.AspNetCoreModule;
Microsoft.AspNetCore.AspNetCoreModuleV2;
Microsoft.AspNetCore.Identity.UI;
java:signalr;
Microsoft.AspNetCore.SignalR.Protocols.MessagePack;
Microsoft.AspNetCore.SignalR.Redis;
Microsoft.AspNetCore.SignalR.StackExchangeRedis;
Microsoft.AspNetCore.DataProtection.StackExchangeRedis;
Microsoft.AspNetCore.Mvc.Core;
Microsoft.AspNetCore.Mvc.RazorPages;
Microsoft.AspNetCore.AzureAppServicesIntegration;
Microsoft.AspNetCore.AzureAppServices.HostingStartup;
Microsoft.AspNetCore.AzureAppServices.SiteExtension;
</PackagesInPatch>
</PropertyGroup>
<PropertyGroup Condition=" '$(VersionPrefix)' == '2.2.6' ">
<PackagesInPatch>
Microsoft.AspNetCore.Mvc.Api.Analyzers;
Microsoft.AspNetCore.Server.HttpSys;
Microsoft.AspNetCore.Server.IIS;
</PackagesInPatch>
</PropertyGroup>
<PropertyGroup Condition=" '$(VersionPrefix)' == '2.2.7' ">
<PackagesInPatch>
Microsoft.AspNetCore.DataProtection.AzureStorage;
Microsoft.AspNetCore.Hosting;
Microsoft.AspNetCore.SpaServices;
</PackagesInPatch>
</PropertyGroup>
<PropertyGroup Condition=" '$(VersionPrefix)' == '2.2.8' ">
<PackagesInPatch>
Microsoft.Net.Http.Headers;
Microsoft.AspNetCore.CookiePolicy;
Microsoft.AspNetCore.DataProtection.EntityFrameworkCore;
@microsoft/signalr;
Microsoft.Net.Http.Headers;
Microsoft.AspNetCore.Http.Abstractions;
Microsoft.AspNetCore.Http.Features;
Microsoft.AspNetCore.CookiePolicy;
</PackagesInPatch>
</PropertyGroup>
</Project>

View File

@ -412,17 +412,17 @@
<Uri>https://github.com/aspnet/Extensions</Uri>
<Sha>1dfe8bc2af511822677789c29a0c800f7cca1d7b</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.GenAPI" Version="1.0.0-beta.19462.4">
<Dependency Name="Microsoft.DotNet.GenAPI" Version="1.0.0-beta.19510.3">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>f8546fbab59a74a66c83b8cb76b3f6877ce1d374</Sha>
<Sha>f70d1fca3d5d4045be75694006f1bee0e0aec572</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="1.0.0-beta.19462.4">
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="1.0.0-beta.19510.3">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>f8546fbab59a74a66c83b8cb76b3f6877ce1d374</Sha>
<Sha>f70d1fca3d5d4045be75694006f1bee0e0aec572</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="2.0.0-beta.19462.4">
<Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="2.0.0-beta.19510.3">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>f8546fbab59a74a66c83b8cb76b3f6877ce1d374</Sha>
<Sha>f70d1fca3d5d4045be75694006f1bee0e0aec572</Sha>
</Dependency>
<Dependency Name="Microsoft.AspNetCore.Testing" Version="5.0.0-alpha1.19512.1" CoherentParentDependency="Microsoft.EntityFrameworkCore">
<Uri>https://github.com/aspnet/Extensions</Uri>

View File

@ -20,8 +20,15 @@
<AspNetCoreMajorMinorVersion>$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion)</AspNetCoreMajorMinorVersion>
<!-- Additional assembly attributes are already configured to include the source revision ID. -->
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
<!--
Until package baselines are updated (see aspnet/AspNetCore#12702), ignore them and PatchConfig.props. This also
gives us time to build the entire repo and settle the infrastructure. Do _not_ do this when stabilizing versions.
-->
<DisableServicingFeatures
Condition=" '$(DisableServicingFeatures)' == '' AND '$(StabilizePackageVersion)' != 'true' ">true</DisableServicingFeatures>
<!-- Servicing builds have different characteristics for the way dependencies, baselines, and versions are handled. -->
<IsServicingBuild Condition=" '$(PreReleaseVersionLabel)' == 'servicing' ">true</IsServicingBuild>
<IsServicingBuild
Condition=" '$(DisableServicingFeatures)' != 'true' AND '$(PreReleaseVersionLabel)' == 'servicing' ">true</IsServicingBuild>
<VersionPrefix>$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion).$(AspNetCorePatchVersion)</VersionPrefix>
<!-- TargetingPackVersionPrefix is used by projects, like .deb and .rpm, which use slightly different version formats. -->
<TargetingPackVersionPrefix>$(VersionPrefix)</TargetingPackVersionPrefix>
@ -55,7 +62,7 @@
-->
<PropertyGroup Label="Automated">
<!-- Packages from dotnet/arcade -->
<MicrosoftDotNetGenAPIPackageVersion>1.0.0-beta.19462.4</MicrosoftDotNetGenAPIPackageVersion>
<MicrosoftDotNetGenAPIPackageVersion>1.0.0-beta.19510.3</MicrosoftDotNetGenAPIPackageVersion>
<!-- Packages from dotnet/roslyn -->
<MicrosoftNetCompilersToolsetPackageVersion>3.4.0-beta1-19456-03</MicrosoftNetCompilersToolsetPackageVersion>
<!-- Packages from dotnet/core-setup -->

View File

@ -0,0 +1,6 @@
param(
[string] $token
)
Write-Host "##vso[task.setvariable variable=VSS_NUGET_ACCESSTOKEN]$token"
Write-Host "##vso[task.setvariable variable=VSS_NUGET_URI_PREFIXES]https://dnceng.pkgs.visualstudio.com/;https://pkgs.dev.azure.com/dnceng/;https://devdiv.pkgs.visualstudio.com/;https://pkgs.dev.azure.com/devdiv/"

View File

@ -5,6 +5,13 @@ param(
$ErrorActionPreference = "Stop"
Set-StrictMode -Version 2.0
# `tools.ps1` checks $ci to perform some actions. Since the post-build
# scripts don't necessarily execute in the same agent that run the
# build.ps1/sh script this variable isn't automatically set.
$ci = $true
. $PSScriptRoot\..\tools.ps1
$ExtractPackage = {
param(
[string] $PackagePath # Full path to a NuGet package

View File

@ -0,0 +1,95 @@
parameters:
artifactsPublishingAdditionalParameters: ''
publishInstallersAndChecksums: false
stages:
- stage: NetCore_3_Tools_Validation_Publish
dependsOn: validate
variables:
- template: ../common-variables.yml
displayName: .NET 3 Tools - Validation Publishing
jobs:
- template: ../setup-maestro-vars.yml
- job: publish_assets
displayName: Publish Assets
dependsOn: setupMaestroVars
variables:
- group: DotNet-Blob-Feed
- group: AzureDevOps-Artifact-Feeds-Pats
- name: BARBuildId
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
- name: IsStableBuild
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ]
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.NETCore_3_Tools_Validation_Channel_Id))
pool:
vmImage: 'windows-2019'
steps:
- task: DownloadBuildArtifacts@0
displayName: Download Package Artifacts
inputs:
buildType: current
artifactName: PackageArtifacts
- task: DownloadBuildArtifacts@0
displayName: Download Blob Artifacts
inputs:
buildType: current
artifactName: BlobArtifacts
- task: DownloadBuildArtifacts@0
displayName: Download Asset Manifests
inputs:
buildType: current
artifactName: AssetManifests
- task: NuGetToolInstaller@1
displayName: 'Install NuGet.exe'
# This is necessary whenever we want to publish/restore to an AzDO private feed
- task: NuGetAuthenticate@0
displayName: 'Authenticate to AzDO Feeds'
- task: PowerShell@2
displayName: Enable cross-org publishing
inputs:
filePath: eng\common\enable-cross-org-publishing.ps1
arguments: -token $(dn-bot-dnceng-artifact-feeds-rw)
- task: PowerShell@2
displayName: Publish Assets
inputs:
filePath: eng\common\sdk-task.ps1
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
/p:ArtifactsCategory=$(_DotNetValidationArtifactsCategory)
/p:IsStableBuild=$(IsStableBuild)
/p:IsInternalBuild=$(IsInternalBuild)
/p:RepositoryName=$(Build.Repository.Name)
/p:CommitSha=$(Build.SourceVersion)
/p:NugetPath=$(NuGetExeToolPath)
/p:AzdoTargetFeedPAT='$(dn-bot-dnceng-universal-packages-rw)'
/p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)'
/p:BARBuildId=$(BARBuildId)
/p:MaestroApiEndpoint='$(MaestroApiEndPoint)'
/p:BuildAssetRegistryToken='$(MaestroApiAccessToken)'
/p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/'
/p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
/p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts/'
/p:Configuration=Release
/p:PublishInstallersAndChecksums=${{ parameters.publishInstallersAndChecksums }}
/p:InstallersTargetStaticFeed=$(InstallersBlobFeedUrl)
/p:InstallersAzureAccountKey=$(dotnetcli-storage-key)
/p:ChecksumsTargetStaticFeed=$(ChecksumsBlobFeedUrl)
/p:ChecksumsAzureAccountKey=$(dotnetclichecksums-storage-key)
/p:PublishToAzureDevOpsNuGetFeeds=true
/p:AzureDevOpsStaticShippingFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
/p:AzureDevOpsStaticShippingFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
/p:AzureDevOpsStaticTransportFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
/p:AzureDevOpsStaticTransportFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
/p:AzureDevOpsStaticSymbolsFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json'
/p:AzureDevOpsStaticSymbolsFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
${{ parameters.artifactsPublishingAdditionalParameters }}
- template: ../../steps/promote-build.yml
parameters:
ChannelId: ${{ variables.NETCore_3_Tools_Validation_Channel_Id }}

View File

@ -4,18 +4,18 @@ parameters:
publishInstallersAndChecksums: false
stages:
- stage: NetCore_Dev30_Publish
- stage: NetCore_3_Tools_Publish
dependsOn: validate
variables:
- template: ../common-variables.yml
displayName: .NET Core 3.0 Dev Publishing
displayName: .NET 3 Tools Publishing
jobs:
- template: ../setup-maestro-vars.yml
- job:
displayName: Symbol Publishing
dependsOn: setupMaestroVars
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.PublicDevRelease_30_Channel_Id))
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.NetCore_3_Tools_Channel_Id))
variables:
- group: DotNet-Symbol-Server-Pats
pool:
@ -56,7 +56,7 @@ stages:
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
- name: IsStableBuild
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ]
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.PublicDevRelease_30_Channel_Id))
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.NetCore_3_Tools_Channel_Id))
pool:
vmImage: 'windows-2019'
steps:
@ -85,10 +85,14 @@ stages:
- task: NuGetAuthenticate@0
displayName: 'Authenticate to AzDO Feeds'
- task: PowerShell@2
displayName: Enable cross-org publishing
inputs:
filePath: eng\common\enable-cross-org-publishing.ps1
arguments: -token $(dn-bot-dnceng-artifact-feeds-rw)
- task: PowerShell@2
displayName: Publish Assets
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
inputs:
filePath: eng\common\sdk-task.ps1
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
@ -113,14 +117,14 @@ stages:
/p:ChecksumsTargetStaticFeed=$(ChecksumsBlobFeedUrl)
/p:ChecksumsAzureAccountKey=$(dotnetclichecksums-storage-key)
/p:PublishToAzureDevOpsNuGetFeeds=true
/p:AzureDevOpsStaticShippingFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3/nuget/v3/index.json'
/p:AzureDevOpsStaticShippingFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
/p:AzureDevOpsStaticShippingFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
/p:AzureDevOpsStaticTransportFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3-transport/nuget/v3/index.json'
/p:AzureDevOpsStaticTransportFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
/p:AzureDevOpsStaticTransportFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
/p:AzureDevOpsStaticSymbolsFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3-symbols/nuget/v3/index.json'
/p:AzureDevOpsStaticSymbolsFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json'
/p:AzureDevOpsStaticSymbolsFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
${{ parameters.artifactsPublishingAdditionalParameters }}
- template: ../../steps/promote-build.yml
parameters:
ChannelId: ${{ variables.PublicDevRelease_30_Channel_Id }}
ChannelId: ${{ variables.NetCore_3_Tools_Channel_Id }}

View File

@ -85,10 +85,14 @@ stages:
- task: NuGetAuthenticate@0
displayName: 'Authenticate to AzDO Feeds'
- task: PowerShell@2
displayName: Enable cross-org publishing
inputs:
filePath: eng\common\enable-cross-org-publishing.ps1
arguments: -token $(dn-bot-dnceng-artifact-feeds-rw)
- task: PowerShell@2
displayName: Publish Assets
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
inputs:
filePath: eng\common\sdk-task.ps1
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet

View File

@ -85,10 +85,14 @@ stages:
- task: NuGetAuthenticate@0
displayName: 'Authenticate to AzDO Feeds'
- task: PowerShell@2
displayName: Enable cross-org publishing
inputs:
filePath: eng\common\enable-cross-org-publishing.ps1
arguments: -token $(dn-bot-dnceng-artifact-feeds-rw)
- task: PowerShell@2
displayName: Publish Assets
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
inputs:
filePath: eng\common\sdk-task.ps1
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet

View File

@ -84,10 +84,14 @@ stages:
- task: NuGetAuthenticate@0
displayName: 'Authenticate to AzDO Feeds'
- task: PowerShell@2
displayName: Enable cross-org publishing
inputs:
filePath: eng\common\enable-cross-org-publishing.ps1
arguments: -token $(dn-bot-dnceng-artifact-feeds-rw)
- task: PowerShell@2
displayName: Publish Assets
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
inputs:
filePath: eng\common\sdk-task.ps1
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet

View File

@ -85,10 +85,14 @@ stages:
- task: NuGetAuthenticate@0
displayName: 'Authenticate to AzDO Feeds'
- task: PowerShell@2
displayName: Enable cross-org publishing
inputs:
filePath: eng\common\enable-cross-org-publishing.ps1
arguments: -token $(dn-bot-dnceng-artifact-feeds-rw)
- task: PowerShell@2
displayName: Publish Assets
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
inputs:
filePath: eng\common\sdk-task.ps1
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet

View File

@ -85,10 +85,14 @@ stages:
- task: NuGetAuthenticate@0
displayName: 'Authenticate to AzDO Feeds'
- task: PowerShell@2
displayName: Enable cross-org publishing
inputs:
filePath: eng\common\enable-cross-org-publishing.ps1
arguments: -token $(dn-bot-dnceng-artifact-feeds-rw)
- task: PowerShell@2
displayName: Publish Assets
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
inputs:
filePath: eng\common\sdk-task.ps1
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet

View File

@ -85,10 +85,14 @@ stages:
- task: NuGetAuthenticate@0
displayName: 'Authenticate to AzDO Feeds'
- task: PowerShell@2
displayName: Enable cross-org publishing
inputs:
filePath: eng\common\enable-cross-org-publishing.ps1
arguments: -token $(dn-bot-dnceng-artifact-feeds-rw)
- task: PowerShell@2
displayName: Publish Assets
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
inputs:
filePath: eng\common\sdk-task.ps1
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet

View File

@ -21,7 +21,7 @@ stages:
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
- name: IsStableBuild
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ]
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.PublicValidationRelease_30_Channel_Id))
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.NetCore_Tools_Validation_Channel_Id))
pool:
vmImage: 'windows-2019'
steps:
@ -50,10 +50,14 @@ stages:
- task: NuGetAuthenticate@0
displayName: 'Authenticate to AzDO Feeds'
- task: PowerShell@2
displayName: Enable cross-org publishing
inputs:
filePath: eng\common\enable-cross-org-publishing.ps1
arguments: -token $(dn-bot-dnceng-artifact-feeds-rw)
- task: PowerShell@2
displayName: Publish Assets
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
inputs:
filePath: eng\common\sdk-task.ps1
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
@ -88,4 +92,4 @@ stages:
- template: ../../steps/promote-build.yml
parameters:
ChannelId: ${{ variables.PublicValidationRelease_30_Channel_Id }}
ChannelId: ${{ variables.NetCore_Tools_Validation_Channel_Id }}

View File

@ -3,10 +3,6 @@ variables:
- group: DotNet-DotNetCli-Storage
- group: DotNet-MSRC-Storage
# .NET Core 3 Dev
- name: PublicDevRelease_30_Channel_Id
value: 3
# .NET Core 3.1 Dev
- name: PublicDevRelease_31_Channel_Id
value: 128
@ -16,13 +12,21 @@ variables:
value: 131
# .NET Tools - Validation
- name: PublicValidationRelease_30_Channel_Id
- name: NetCore_Tools_Validation_Channel_Id
value: 9
# .NET Tools - Latest
- name: NetCore_Tools_Latest_Channel_Id
value: 2
# .NET 3 Tools - Validation
- name: NETCore_3_Tools_Validation_Channel_Id
value: 390
# .NET 3 Tools - Latest
- name: NetCore_3_Tools_Channel_Id
value: 344
# .NET Core 3.0 Internal Servicing
- name: InternalServicing_30_Channel_Id
value: 184

View File

@ -101,12 +101,6 @@ stages:
artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
- template: \eng\common\templates\post-build\channels\netcore-dev-30.yml
parameters:
symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
- template: \eng\common\templates\post-build\channels\netcore-dev-31.yml
parameters:
symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
@ -119,11 +113,22 @@ stages:
artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
- template: \eng\common\templates\post-build\channels\public-validation-release.yml
- template: \eng\common\templates\post-build\channels\netcore-tools-validation.yml
parameters:
artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
- template: \eng\common\templates\post-build\channels\netcore-3-tools-validation.yml
parameters:
artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
- template: \eng\common\templates\post-build\channels\netcore-3-tools.yml
parameters:
symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
- template: \eng\common\templates\post-build\channels\netcore-release-30.yml
parameters:
symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}

View File

@ -52,6 +52,7 @@
<_RefSourceOutputPath>$([System.IO.Directory]::GetParent('$(MSBuildProjectDirectory)'))/ref/</_RefSourceOutputPath>
<_RefSourceFileName>$(AssemblyName).$(_RefSourceFileTFM).cs</_RefSourceFileName>
<_ManualRefSourceFileName>$(AssemblyName).Manual.cs</_ManualRefSourceFileName>
<_RefSourceFileOutputPath>$(_RefSourceOutputPath)$(_RefSourceFileName)</_RefSourceFileOutputPath>
</PropertyGroup>
@ -87,10 +88,16 @@
</ItemGroup>
<PropertyGroup>
<_ManualReferenceAssemblyContent />
<_ManualReferenceAssemblyContent Condition="Exists('$(_RefSourceOutputPath)$(_ManualRefSourceFileName)')">
<![CDATA[
<Compile Include="$(_ManualRefSourceFileName)" />]]>
</_ManualReferenceAssemblyContent>
<ReferencesContent>
<![CDATA[
<ItemGroup Condition="'%24(TargetFramework)' == '$(_RefProjectFileTFM)'">
<Compile Include="$(_RefSourceFileName)" />
<Compile Include="$(_RefSourceFileName)" />]]>$(_ManualReferenceAssemblyContent)<![CDATA[
@(FilteredOriginalReferences->'<Reference Include="%(Identity)" />', '%0A ')
</ItemGroup>
]]>

View File

@ -36,7 +36,8 @@
-->
<UseLatestPackageReferences Condition=" '$(UseLatestPackageReferences)' == '' AND '$(IsServicingBuild)' != 'true' ">true</UseLatestPackageReferences>
<UseLatestPackageReferences Condition=" '$(UseLatestPackageReferences)' == '' AND '$(IsImplementationProject)' != 'true' ">true</UseLatestPackageReferences>
<UseLatestPackageReferences Condition=" '$(UseLatestPackageReferences)' == '' AND '$(IsImplementationProject)' == 'true' AND ( '$(IsServicingBuild)' != 'true' OR '$(IsPackable)' == 'true' ) ">true</UseLatestPackageReferences>
<UseLatestPackageReferences
Condition=" '$(UseLatestPackageReferences)' == '' AND '$(IsImplementationProject)' == 'true' AND '$(IsPackable)' == 'true' ">true</UseLatestPackageReferences>
<UseLatestPackageReferences Condition=" '$(UseLatestPackageReferences)' == '' ">false</UseLatestPackageReferences>
<!--
@ -122,7 +123,7 @@
Text="Cannot reference &quot;%(_InvalidReferenceToNonSharedFxAssembly.Identity)&quot;. This dependency is not in the shared framework. See docs/SharedFramework.md for instructions on how to modify what is in the shared framework." />
</Target>
<Target Name="_WarnAboutRedundantRef" AfterTargets="ResolveFrameworkReferences">
<Target Name="_WarnAboutRedundantRef" AfterTargets="ResolveFrameworkReferences;ProcessFrameworkReferences">
<Warning Condition="@(FrameworkReference->WithMetadataValue('Identity', 'Microsoft.AspNetCore.App')->Count()) &gt; 1"
Text="Redundant &lt;FrameworkReference&gt;. If you have an explicit item in the project file, you might be able to remove it. Some SDKs, like Microsoft.NET.Sdk.Web, add this implicitly." />
</Target>

View File

@ -3,7 +3,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
<StartArguments>-s https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json</StartArguments>
<StartArguments>-s https://api.nuget.org/v3/index.json</StartArguments>
<StartWorkingDirectory>$(MSBuildThisFileDirectory)../../</StartWorkingDirectory>
</PropertyGroup>

View File

@ -12,14 +12,14 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NuGet.Build.Tasks" Version="5.1.0-rtm.5921" />
<PackageReference Include="NuGet.Build.Tasks" Version="5.3.0" />
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="2.1.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'">
<PackageReference Include="Microsoft.Build.Framework" Version="15.8.166" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="15.8.166" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.8.166" />
<PackageReference Include="Microsoft.Build.Framework" Version="16.3.0" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="16.3.0" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="16.3.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net472'">

View File

@ -25,7 +25,7 @@
},
"msbuild-sdks": {
"Yarn.MSBuild": "1.15.2",
"Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19462.4",
"Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19462.4"
"Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19510.3",
"Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19510.3"
}
}

BIN
packageIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@ -25,6 +25,7 @@
<ItemGroup>
<NuspecProperty Include="OutputBinary=$(OutputPath)$(AssemblyName).dll" />
<NuspecProperty Include="OutputSymbol=$(OutputPath)$(AssemblyName).pdb" />
<NuspecProperty Include="PackageIcon=$(PackageIconFullPath)" />
</ItemGroup>
</Project>

View File

@ -2,10 +2,12 @@
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
$CommonMetadataElements$
<icon>packageIcon.png</icon>
</metadata>
<files>
<file src="$OutputBinary$" target="analyzers\dotnet\cs\" />
<file src="$OutputSymbol$" target="analyzers\dotnet\cs\" />
<file src="$PackageIcon$" target="" />
</files>
</package>

View File

@ -23,6 +23,7 @@
<NuspecProperty Include="componentsversion=$(ComponentsPackageVersion)" />
<NuspecProperty Include="razorversion=$(MicrosoftAspNetCoreRazorDesignPackageVersion)" />
<NuspecProperty Include="blazormonoversion=$(MicrosoftAspNetCoreBlazorMonoPackageVersion)" />
<NuspecProperty Include="PackageIcon=$(PackageIconFullPath)" />
</ItemGroup>
<ItemGroup>

View File

@ -5,6 +5,7 @@
<dependencies>
<dependency id="Microsoft.AspNetCore.Blazor.Mono" version="$blazormonoversion$" include="all" />
</dependencies>
<icon>packageIcon.png</icon>
</metadata>
<files>
<file src="..\..\..\THIRD-PARTY-NOTICES.txt" />
@ -12,5 +13,6 @@
<file src="targets\**" target="targets" />
<file src="$publishdir$**\*" target="tools/" />
<file src="..\..\..\Web.JS\dist\$configuration$\blazor.*.js" target="tools/blazor" />
<file src="$PackageIcon$" target="" />
</files>
</package>

View File

@ -33,6 +33,7 @@
<NuspecProperty Include="publishDir=$(PublishDir)" />
<NuspecProperty Include="componentsrootdir=..\..\..\" />
<NuspecProperty Include="blazorversion=$(PackageVersion)" />
<NuspecProperty Include="PackageIcon=$(PackageIconFullPath)" />
</ItemGroup>
</Project>

View File

@ -2,10 +2,12 @@
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
$CommonMetadataElements$
<icon>packageIcon.png</icon>
</metadata>
<files>
<file src="build\**" target="build" />
<file src="$publishDir$**\*" target="tools" />
<file src="$componentsrootdir$THIRD-PARTY-NOTICES.txt" target=".\THIRD-PARTY-NOTICES.txt" />
<file src="$PackageIcon$" target="" />
</files>
</package>

View File

@ -15,6 +15,10 @@
<IsProjectReferenceProvider>false</IsProjectReferenceProvider>
</PropertyGroup>
<ItemGroup>
<NuspecProperty Include="PackageIcon=$(PackageIconFullPath)" />
</ItemGroup>
<ItemGroup>
<UpToDateCheckInput Include="content\**\.template.config.src\**\*.*" />
</ItemGroup>

View File

@ -5,11 +5,13 @@
<packageTypes>
<packageType name="Template" />
</packageTypes>
<icon>packageIcon.png</icon>
</metadata>
<files>
<file
src="content/**"
exclude="**/bin/**;**/obj/**;**/.template.config.src/**;content/Directory.Build.props;content/Directory.Build.targets;"
target="Content" />
<file src="$PackageIcon$" target="" />
</files>
</package>

View File

@ -23,6 +23,14 @@
<Reference Include="System.Buffers" />
</ItemGroup>
<!-- These references were removed in 3.0 -->
<ItemGroup>
<SuppressBaselineReference Include="Microsoft.AspNetCore.Components.Analyzers" />
<SuppressBaselineReference Include="Microsoft.AspNetCore.Authorization" />
<SuppressBaselineReference Include="Microsoft.JSInterop" />
<SuppressBaselineReference Include="System.ComponentModel.Annotations" />
</ItemGroup>
<Target Name="_GetNuspecDependencyPackageVersions">
<MSBuild Targets="_GetPackageVersionInfo"
BuildInParallel="$(BuildInParallel)"
@ -47,6 +55,7 @@
<NuspecProperty Condition="'$(DotNetBuildFromSource)' != 'true'" Include="systemComponentModelAnnotationsPackageVersion=$(SystemComponentModelAnnotationsPackageVersion)" />
<NuspecProperty Include="AssemblyName=$(AssemblyName)" />
<NuspecProperty Include="OutputPath=$(OutputPath)" />
<NuspecProperty Include="PackageIcon=$(PackageIconFullPath)" />
</ItemGroup>
</Project>

View File

@ -15,11 +15,13 @@
<dependency id="Microsoft.JSInterop" version="$jsInteropPackageVersion$" exclude="Build,Analyzers" />
</group>
</dependencies>
<icon>packageIcon.png</icon>
</metadata>
<files>
<file src="$OutputPath$**\$AssemblyName$.dll" target="lib\" />
<file src="$OutputPath$**\$AssemblyName$.pdb" target="lib\" />
<file src="$OutputPath$**\$AssemblyName$.xml" target="lib\" />
<file src="$PackageIcon$" target="" />
<file src="..\..\THIRD-PARTY-NOTICES.txt" target=".\THIRD-PARTY-NOTICES.txt" />
</files>
</package>

View File

@ -9,11 +9,13 @@
<dependency id="Microsoft.JSInterop" version="$jsInteropPackageVersion$" exclude="Build,Analyzers" />
</group>
</dependencies>
<icon>packageIcon.png</icon>
</metadata>
<files>
<file src="$OutputPath$**\$AssemblyName$.dll" target="lib\" />
<file src="$OutputPath$**\$AssemblyName$.pdb" target="lib\" />
<file src="$OutputPath$**\$AssemblyName$.xml" target="lib\" />
<file src="$PackageIcon$" target="" />
<file src="..\..\THIRD-PARTY-NOTICES.txt" target=".\THIRD-PARTY-NOTICES.txt" />
</files>
</package>

View File

@ -13,8 +13,16 @@
<link href="css/site.css" rel="stylesheet" />
</head>
<body>
<component type="typeof(App)" render-mode="ServerPrerendered" />
<app><component type="typeof(App)" render-mode="ServerPrerendered" /></app>
<script src="_framework/blazor.server.js"></script>
<script src="_framework/blazor.server.js" autostart="false"></script>
<script>
(function start() {
Blazor.start({
logLevel: 1, // LogLevel.Debug
configureSignalR: builder => builder.configureLogging("debug") // LogLevel.Debug
});
})()
</script>
</body>
</html>

View File

@ -1,4 +1,4 @@
<div class="top-row pl-4 navbar navbar-dark">
<div class="top-row pl-4 navbar navbar-dark">
<a class="navbar-brand" href="">BlazorServerApp</a>
<button class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>

View File

@ -1,9 +1,10 @@
{
"detailedErrors": true,
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
"Microsoft": "Debug"
}
}
}

View File

@ -113,19 +113,21 @@ app {
#blazor-error-ui {
background: lightyellow;
position: fixed;
border: "1px solid";
border-color: black;
width: 100%;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 5px;
top: 5px;
right: 0.75rem;
top: 0.5rem;
}
@media (max-width: 767.98px) {

View File

@ -101,7 +101,7 @@ export function discoverComponents(document: Document): ComponentDescriptor[] {
discoveredComponents.push(entry);
}
return discoveredComponents;
return discoveredComponents.sort((a, b) => a.sequence - b.sequence);
}

View File

@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.Components.Forms
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { }
protected override void OnParametersSet() { }
}
public abstract partial class InputBase<TValue> : Microsoft.AspNetCore.Components.ComponentBase
public abstract partial class InputBase<TValue> : Microsoft.AspNetCore.Components.ComponentBase, System.IDisposable
{
protected InputBase() { }
[Microsoft.AspNetCore.Components.ParameterAttribute(CaptureUnmatchedValues=true)]
@ -58,8 +58,10 @@ namespace Microsoft.AspNetCore.Components.Forms
public Microsoft.AspNetCore.Components.EventCallback<TValue> ValueChanged { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
[Microsoft.AspNetCore.Components.ParameterAttribute]
public System.Linq.Expressions.Expression<System.Func<TValue>> ValueExpression { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
protected virtual void Dispose(bool disposing) { }
protected virtual string FormatValueAsString(TValue value) { throw null; }
public override System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) { throw null; }
void System.IDisposable.Dispose() { }
protected abstract bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage);
}
public partial class InputCheckbox : Microsoft.AspNetCore.Components.Forms.InputBase<bool>

View File

@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.Components.Forms
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { }
protected override void OnParametersSet() { }
}
public abstract partial class InputBase<TValue> : Microsoft.AspNetCore.Components.ComponentBase
public abstract partial class InputBase<TValue> : Microsoft.AspNetCore.Components.ComponentBase, System.IDisposable
{
protected InputBase() { }
[Microsoft.AspNetCore.Components.ParameterAttribute(CaptureUnmatchedValues=true)]
@ -58,8 +58,10 @@ namespace Microsoft.AspNetCore.Components.Forms
public Microsoft.AspNetCore.Components.EventCallback<TValue> ValueChanged { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
[Microsoft.AspNetCore.Components.ParameterAttribute]
public System.Linq.Expressions.Expression<System.Func<TValue>> ValueExpression { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
protected virtual void Dispose(bool disposing) { }
protected virtual string FormatValueAsString(TValue value) { throw null; }
public override System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) { throw null; }
void System.IDisposable.Dispose() { }
protected abstract bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage);
}
public partial class InputCheckbox : Microsoft.AspNetCore.Components.Forms.InputBase<bool>

View File

@ -13,8 +13,9 @@ namespace Microsoft.AspNetCore.Components.Forms
/// integrates with an <see cref="Forms.EditContext"/>, which must be supplied
/// as a cascading parameter.
/// </summary>
public abstract class InputBase<TValue> : ComponentBase
public abstract class InputBase<TValue> : ComponentBase, IDisposable
{
private readonly EventHandler<ValidationStateChangedEventArgs> _validationStateChangedHandler;
private bool _previousParsingAttemptFailed;
private ValidationMessageStore _parsingValidationMessages;
private Type _nullableUnderlyingType;
@ -122,7 +123,15 @@ namespace Microsoft.AspNetCore.Components.Forms
}
/// <summary>
/// Formats the value as a string. Derived classes can override this to determine the formatting used for <see cref="CurrentValueAsString"/>.
/// Constructs an instance of <see cref="InputBase{TValue}"/>.
/// </summary>
protected InputBase()
{
_validationStateChangedHandler = (sender, eventArgs) => StateHasChanged();
}
/// <summary>
/// Formats the value as a string. Derived classes can override this to determine the formating used for <see cref="CurrentValueAsString"/>.
/// </summary>
/// <param name="value">The value to format.</param>
/// <returns>A string representation of the value.</returns>
@ -193,6 +202,8 @@ namespace Microsoft.AspNetCore.Components.Forms
EditContext = CascadedEditContext;
FieldIdentifier = FieldIdentifier.Create(ValueExpression);
_nullableUnderlyingType = Nullable.GetUnderlyingType(typeof(TValue));
EditContext.OnValidationStateChanged += _validationStateChangedHandler;
}
else if (CascadedEditContext != EditContext)
{
@ -208,5 +219,19 @@ namespace Microsoft.AspNetCore.Components.Forms
// For derived components, retain the usual lifecycle with OnInit/OnParametersSet/etc.
return base.SetParametersAsync(ParameterView.Empty);
}
protected virtual void Dispose(bool disposing)
{
}
void IDisposable.Dispose()
{
if (EditContext != null)
{
EditContext.OnValidationStateChanged -= _validationStateChangedHandler;
}
Dispose(disposing: true);
}
}
}

View File

@ -175,7 +175,7 @@ namespace Microsoft.AspNetCore.Components.Routing
var prefixLength = prefix.Length;
if (value.Length > prefixLength)
{
return value.StartsWith(prefix, StringComparison.Ordinal)
return value.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)
&& (
// Only match when there's a separator character either at the end of the
// prefix or right after it.

View File

@ -294,7 +294,7 @@ namespace Microsoft.AspNetCore.Components.Forms
rootComponent.EditContext.OnValidationStateChanged += (sender, eventArgs) => { numValidationStateChanges++; };
// Act
inputComponent.CurrentValueAsString = "1991/11/20";
await inputComponent.SetCurrentValueAsStringAsync("1991/11/20");
// Assert
var receivedParsedValue = valueChangedArgs.Single();
@ -324,14 +324,14 @@ namespace Microsoft.AspNetCore.Components.Forms
rootComponent.EditContext.OnValidationStateChanged += (sender, eventArgs) => { numValidationStateChanges++; };
// Act/Assert 1: Transition to invalid
inputComponent.CurrentValueAsString = "1991/11/40";
await inputComponent.SetCurrentValueAsStringAsync("1991/11/40");
Assert.Empty(valueChangedArgs);
Assert.True(rootComponent.EditContext.IsModified(fieldIdentifier));
Assert.Equal(new[] { "Bad date value" }, rootComponent.EditContext.GetValidationMessages(fieldIdentifier));
Assert.Equal(1, numValidationStateChanges);
// Act/Assert 2: Transition to valid
inputComponent.CurrentValueAsString = "1991/11/20";
await inputComponent.SetCurrentValueAsStringAsync("1991/11/20");
var receivedParsedValue = valueChangedArgs.Single();
Assert.Equal(1991, receivedParsedValue.Year);
Assert.Equal(11, receivedParsedValue.Month);
@ -341,6 +341,65 @@ namespace Microsoft.AspNetCore.Components.Forms
Assert.Equal(2, numValidationStateChanges);
}
[Fact]
public async Task RespondsToValidationStateChangeNotifications()
{
// Arrange
var model = new TestModel();
var rootComponent = new TestInputHostComponent<string, TestInputComponent<string>>
{
EditContext = new EditContext(model),
ValueExpression = () => model.StringProperty
};
var fieldIdentifier = FieldIdentifier.Create(() => model.StringProperty);
var renderer = new TestRenderer();
var rootComponentId = renderer.AssignRootComponentId(rootComponent);
await renderer.RenderRootComponentAsync(rootComponentId);
// Initally, it rendered one batch and is valid
var batch1 = renderer.Batches.Single();
var componentFrame1 = batch1.GetComponentFrames<TestInputComponent<string>>().Single();
var inputComponentId = componentFrame1.ComponentId;
var component = (TestInputComponent<string>)componentFrame1.Component;
Assert.Equal("valid", component.CssClass);
// Act: update the field state in the EditContext and notify
var messageStore = new ValidationMessageStore(rootComponent.EditContext);
messageStore.Add(fieldIdentifier, "Some message");
await renderer.Dispatcher.InvokeAsync(rootComponent.EditContext.NotifyValidationStateChanged);
// Assert: The input component rendered itself again and now has the new class
var batch2 = renderer.Batches.Skip(1).Single();
Assert.Equal(inputComponentId, batch2.DiffsByComponentId.Keys.Single());
Assert.Equal("invalid", component.CssClass);
}
[Fact]
public async Task UnsubscribesFromValidationStateChangeNotifications()
{
// Arrange
var model = new TestModel();
var rootComponent = new TestInputHostComponent<string, TestInputComponent<string>>
{
EditContext = new EditContext(model),
ValueExpression = () => model.StringProperty
};
var fieldIdentifier = FieldIdentifier.Create(() => model.StringProperty);
var renderer = new TestRenderer();
var rootComponentId = renderer.AssignRootComponentId(rootComponent);
await renderer.RenderRootComponentAsync(rootComponentId);
var component = renderer.Batches.Single().GetComponentFrames<TestInputComponent<string>>().Single().Component;
// Act: dispose, then update the field state in the EditContext and notify
((IDisposable)component).Dispose();
var messageStore = new ValidationMessageStore(rootComponent.EditContext);
messageStore.Add(fieldIdentifier, "Some message");
await renderer.Dispatcher.InvokeAsync(rootComponent.EditContext.NotifyValidationStateChanged);
// Assert: No additional render
Assert.Empty(renderer.Batches.Skip(1));
}
private static TComponent FindComponent<TComponent>(CapturedBatch batch)
=> batch.ReferenceFrames
.Where(f => f.FrameType == RenderTreeFrameType.Component)
@ -376,7 +435,6 @@ namespace Microsoft.AspNetCore.Components.Forms
public new string CurrentValueAsString
{
get => base.CurrentValueAsString;
set { base.CurrentValueAsString = value; }
}
public new IReadOnlyDictionary<string, object> AdditionalAttributes => base.AdditionalAttributes;
@ -391,6 +449,15 @@ namespace Microsoft.AspNetCore.Components.Forms
{
throw new NotImplementedException();
}
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; });
}
}
class TestDateInputComponent : TestInputComponent<DateTime>

View File

@ -16,13 +16,13 @@ using Xunit.Abstractions;
namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
{
public class MultipleComponentsTest : ServerTestBase<BasicTestAppServerSiteFixture<PrerenderedStartup>>
public class MultipleComponentsTest : ServerTestBase<BasicTestAppServerSiteFixture<MultipleComponents>>
{
private const string MarkerPattern = ".*?<!--Blazor:(.*?)-->.*?";
public MultipleComponentsTest(
BrowserFixture browserFixture,
BasicTestAppServerSiteFixture<PrerenderedStartup> serverFixture,
BasicTestAppServerSiteFixture<MultipleComponents> serverFixture,
ITestOutputHelper output)
: base(browserFixture, serverFixture, output)
{
@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
[Fact]
public void DoesNotStartMultipleConnections()
{
Navigate("/prerendered/multiple-components");
Navigate("/multiple-components");
BeginInteractivity();
Browser.Exists(By.CssSelector("h3.interactive"));
@ -60,17 +60,18 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
});
}
[Fact]
public void CanRenderMultipleRootComponents()
{
Navigate("/prerendered/multiple-components");
Navigate("/multiple-components");
var greets = Browser.FindElements(By.CssSelector(".greet-wrapper .greet")).Select(e => e.Text).ToArray();
Assert.Equal(5, greets.Length); // 1 statically rendered + 3 prerendered + 1 server prerendered
Assert.Equal(7, greets.Length); // 1 statically rendered + 5 prerendered + 1 server prerendered
Assert.DoesNotContain("Hello Red fish", greets);
Assert.Single(greets, "Hello John");
Assert.Single(greets, "Hello Abraham");
Assert.Equal(2, greets.Where(g => g == "Hello Blue fish").Count());
Assert.Equal(3, greets.Where(g => string.Equals("Hello", g)).Count()); // 3 server prerendered without parameters
var content = Browser.FindElement(By.Id("test-container")).GetAttribute("innerHTML");
var markers = ReadMarkers(content);
@ -86,7 +87,11 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
false,
true,
false,
true
true,
false,
true,
false,
true,
};
Assert.Equal(expectedComponentSequence, componentSequence);
@ -96,6 +101,8 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
Browser.Exists(By.CssSelector("h3.interactive"));
var updatedGreets = Browser.FindElements(By.CssSelector(".greet-wrapper .greet")).Select(e => e.Text).ToArray();
Assert.Equal(7, updatedGreets.Where(g => string.Equals("Hello Alfred", g)).Count());
Assert.Equal(2, updatedGreets.Where(g => g == "Hello Red fish").Count());
Assert.Equal(2, updatedGreets.Where(g => g == "Hello Blue fish").Count());
Assert.Single(updatedGreets.Where(g => string.Equals("Hello Albert", g)));
Assert.Single(updatedGreets.Where(g => string.Equals("Hello Abraham", g)));
}

View File

@ -376,6 +376,24 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
Browser.Equal("Premium", () => selectedTicketClassDisplay.Text);
}
[Fact]
public void InputComponentsRespondToAsynchronouslyAddedMessages()
{
var appElement = Browser.MountTestComponent<TypicalValidationComponent>();
var input = appElement.FindElement(By.CssSelector(".username input"));
var triggerAsyncErrorButton = appElement.FindElement(By.CssSelector(".username button"));
var messagesAccessor = CreateValidationMessagesAccessor(appElement);
// Initially shows no error
Browser.Empty(() => messagesAccessor());
Browser.Equal("valid", () => input.GetAttribute("class"));
// Can trigger async error
triggerAsyncErrorButton.Click();
Browser.Equal(new[] { "This is invalid, asynchronously" }, messagesAccessor);
Browser.Equal("invalid", () => input.GetAttribute("class"));
}
private Func<string[]> CreateValidationMessagesAccessor(IWebElement appElement)
{
return () => appElement.FindElements(By.ClassName("validation-message"))

View File

@ -1,7 +1,7 @@
@using System.ComponentModel.DataAnnotations
@using Microsoft.AspNetCore.Components.Forms
<EditForm Model="@person" OnValidSubmit="@HandleValidSubmit">
<EditForm EditContext="@editContext" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<p class="name">
@ -42,6 +42,10 @@
<p class="is-evil">
Is evil: <InputCheckbox @bind-Value="person.IsEvil" />
</p>
<p class="username">
Username (optional): <InputText @bind-Value="person.Username" />
<button type="button" @onclick="@TriggerAsyncValidationError">Trigger async error</button>
</p>
<button type="submit">Submit</button>
@ -52,6 +56,14 @@
@code {
Person person = new Person();
EditContext editContext;
ValidationMessageStore customValidationMessageStore;
protected override void OnInitialized()
{
editContext = new EditContext(person);
customValidationMessageStore = new ValidationMessageStore(editContext);
}
// Usually this would be in a different file
class Person
@ -83,6 +95,8 @@
[Required, EnumDataType(typeof(TicketClass))]
public TicketClass TicketClass { get; set; }
public string Username { get; set; }
}
enum TicketClass { Economy, Premium, First }
@ -93,4 +107,22 @@
{
submissionLog.Add("OnValidSubmit");
}
void TriggerAsyncValidationError()
{
customValidationMessageStore.Clear();
// Note that this method returns void, so the renderer doesn't react to
// its async flow by default. This is to simulate some external system
// implementing async validation.
Task.Run(async () =>
{
// The duration of the delay doesn't matter to the test, as long as it's not
// so long that we time out. Picking a value that's long enough for humans
// to observe the asynchrony too.
await Task.Delay(500);
customValidationMessageStore.Add(editContext.Field(nameof(Person.Username)), "This is invalid, asynchronously");
_ = InvokeAsync(editContext.NotifyValidationStateChanged);
});
}
}

View File

@ -14,7 +14,7 @@
<li><NavLink href="/subdir/Default.html">With extension</NavLink></li>
<li><NavLink href="/subdir/Other">Other</NavLink></li>
<li><NavLink href="Other" Match=NavLinkMatch.All>Other with base-relative URL (matches all)</NavLink></li>
<li><NavLink href="/subdir/Other?abc=123">Other with query</NavLink></li>
<li><NavLink href="/subdir/other?abc=123">Other with query</NavLink></li>
<li><NavLink href="/subdir/Other#blah">Other with hash</NavLink></li>
<li><NavLink href="/subdir/WithParameters/Name/Abc">With parameters</NavLink></li>
<li><NavLink href="/subdir/WithParameters/Name/Abc/LastName/McDef">With more parameters</NavLink></li>

View File

@ -0,0 +1,51 @@
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace TestServer
{
public class MultipleComponents
{
public MultipleComponents(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddServerSideBlazor();
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.Map("/multiple-components", app =>
{
app.UseStaticFiles();
app.UseAuthentication();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapFallbackToPage("/MultipleComponents");
endpoints.MapBlazorHub();
});
});
}
}
}

View File

@ -1,59 +1,29 @@
@page "/multiple-components"
@using BasicTestApp.MultipleComponents;
<!DOCTYPE html>
<html>
<head>
<title>Multiple component entry points</title>
<base href="~/" />
@* This page is used to validate the ability to render multiple root components in a blazor server-side application.
*@
</head>
<body>
<div id="test-container">
@(await Html.RenderComponentAsync<GreeterComponent>(RenderMode.ServerPrerendered))
@(await Html.RenderComponentAsync<GreeterComponent>(RenderMode.Server))
<component type="typeof(GreeterComponent)" render-mode="Static" param-name='"John"' />
<component type="typeof(GreeterComponent)" render-mode="Server"/>
<div id="container">
@{
Layout = "./MultipleComponentsLayout.cshtml";
}
@(await Html.RenderComponentAsync<GreeterComponent>(RenderMode.ServerPrerendered))
@(await Html.RenderComponentAsync<GreeterComponent>(RenderMode.Server))
<component type="typeof(GreeterComponent)" render-mode="Static" param-name='"John"' />
<component type="typeof(GreeterComponent)" render-mode="Server" />
<div id="container">
<p>Some content before</p>
<component type="typeof(GreeterComponent)" render-mode="Server"/>
<component type="typeof(GreeterComponent)" render-mode="Server" />
<p>Some content between</p>
<component type="typeof(GreeterComponent)" render-mode="ServerPrerendered"/>
<component type="typeof(GreeterComponent)" render-mode="ServerPrerendered" />
<p>Some content after</p>
<div id="nested-an-extra-level">
<p>Some content before</p>
<component type="typeof(GreeterComponent)" render-mode="Server"/>
<component type="typeof(GreeterComponent)" render-mode="ServerPrerendered"/>
<component type="typeof(GreeterComponent)" render-mode="Server" />
<component type="typeof(GreeterComponent)" render-mode="ServerPrerendered" />
<p>Some content after</p>
</div>
</div>
<div id="container">
</div>
<div id="container">
<component type="typeof(GreeterComponent)" render-mode="Server" param-name='"Albert"' />
<component type="typeof(GreeterComponent)" render-mode="ServerPrerendered" param-name='"Abraham"' />
</div>
</div>
@*
So that E2E tests can make assertions about both the prerendered and
interactive states, we only load the .js file when told to.
*@
<hr />
<button id="load-boot-script" onclick="start()">Load boot script</button>
<script src="_framework/blazor.server.js" autostart="false"></script>
<script>
// Used by InteropOnInitializationComponent
function setElementValue(element, newValue) {
element.value = newValue;
return element.value;
}
function start() {
Blazor.start({
logLevel: 1 // LogLevel.Debug
});
}
</script>
</body>
</html>
</div>

View File

@ -0,0 +1,43 @@
@using BasicTestApp.MultipleComponents;
<!DOCTYPE html>
<html>
<head>
<title>Multiple component entry points</title>
<base href="~/" />
@* This page is used to validate the ability to render multiple root components in a blazor server-side application.
*@
</head>
<body>
<div id="test-container">
<component type="typeof(GreeterComponent)" render-mode="Server" param-name='"Red fish"' />
<component type="typeof(GreeterComponent)" render-mode="ServerPrerendered" param-name='"Blue fish"' />
@RenderBody()
<component type="typeof(GreeterComponent)" render-mode="Server" param-name='"Red fish"' />
<component type="typeof(GreeterComponent)" render-mode="ServerPrerendered" param-name='"Blue fish"' />
</div>
@*
So that E2E tests can make assertions about both the prerendered and
interactive states, we only load the .js file when told to.
*@
<hr />
<button id="load-boot-script" onclick="start()">Load boot script</button>
<script src="_framework/blazor.server.js" autostart="false"></script>
<script>
// Used by InteropOnInitializationComponent
function setElementValue(element, newValue) {
element.value = newValue;
return element.value;
}
function start() {
Blazor.start({
logLevel: 1 // LogLevel.Debug
});
}
</script>
</body>
</html>

View File

@ -1,15 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
@ -28,6 +23,7 @@ namespace TestServer
["Server authentication"] = (BuildWebHost<ServerAuthenticationStartup>(CreateAdditionalArgs(args)), "/subdir"),
["CORS (WASM)"] = (BuildWebHost<CorsStartup>(CreateAdditionalArgs(args)), "/subdir"),
["Prerendering (Server-side)"] = (BuildWebHost<PrerenderedStartup>(CreateAdditionalArgs(args)), "/prerendered"),
["Multiple components (Server-side)"] = (BuildWebHost<MultipleComponents>(CreateAdditionalArgs(args)), "/multiple-components"),
["Globalization + Localization (Server-side)"] = (BuildWebHost<InternationalizationStartup>(CreateAdditionalArgs(args)), "/subdir"),
["Server-side blazor"] = (BuildWebHost<ServerStartup>(CreateAdditionalArgs(args)), "/subdir"),
["Hosted client-side blazor"] = (BuildWebHost<ClientStartup>(CreateAdditionalArgs(args)), "/subdir"),

View File

@ -38,10 +38,17 @@ This package is an internal implementation of the .NET Core SDK and is not meant
<!-- Reference implementation assemblies in addition to ref assemblies to get xml docs -->
<ReferenceImplementationAssemblies>true</ReferenceImplementationAssemblies>
<!-- We are ignoring MSB3243 warnings since implemenation and reference assemblies are versioned differently. We need both to compose the targeting pack with reference assemblies and xml docs. -->
<MSBuildWarningsAsMessages>MSB3243</MSBuildWarningsAsMessages >
<!-- Platform manifest data -->
<FrameworkListFileName>FrameworkList.xml</FrameworkListFileName>
<FrameworkListOutputPath>$(ArtifactsObjDir)$(FrameworkListFileName)</FrameworkListOutputPath>
<!-- Platform manifest and package override metatdata -->
<ReferencePackSharedFxVersion>$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion).0</ReferencePackSharedFxVersion>
<ReferencePackSharedFxVersion Condition="'$(VersionSuffix)' != ''">$(ReferencePackSharedFxVersion)-$(VersionSuffix)</ReferencePackSharedFxVersion>
<ReferencePlatformManifestOutputPath>$(ArtifactsObjDir)ref\PlatformManifest.txt</ReferencePlatformManifestOutputPath>
</PropertyGroup>
<ItemGroup>
@ -80,7 +87,7 @@ This package is an internal implementation of the .NET Core SDK and is not meant
</BuildDependsOn>
<!-- No-op when in source build -->
<BuildDependsOn Condition="'$(IsTargetingPackBuilding)' != 'false' and '$(DotNetBuildFromSource)' == 'true'"/>
<BuildDependsOn Condition="'$(IsTargetingPackBuilding)' == 'false'"/>
</PropertyGroup>
<!-- Override the default MSBuild targets so that nothing is returned from the project since it represents a collection of assemblies. -->
@ -95,6 +102,7 @@ This package is an internal implementation of the .NET Core SDK and is not meant
<!-- This target finds the reference assemblies. -->
<Target Name="_ResolveTargetingPackContent"
Returns="@(AspNetCoreReferenceAssemblyPath)"
BeforeTargets="_GetPackageFiles"
DependsOnTargets="ResolveReferences;FindReferenceAssembliesForReferences">
<ItemGroup>
@ -111,6 +119,7 @@ This package is an internal implementation of the .NET Core SDK and is not meant
Exclude="
@(_SelectedExtensionsRefAssemblies);
@(ReferencePathWithRefAssemblies->WithMetadataValue('NuGetPackageId', 'Microsoft.NETCore.App.Ref'));
@(ReferencePathWithRefAssemblies->WithMetadataValue('IsReferenceAssembly', 'false'));
@(ReferencePathWithRefAssemblies->WithMetadataValue('ReferenceGrouping', 'Microsoft.NETCore.App'));" />
<AspNetCoreReferenceAssemblyPath
@ -118,11 +127,23 @@ This package is an internal implementation of the .NET Core SDK and is not meant
<AspNetCoreReferenceDocXml Include="@(_ResolvedProjectReferencePaths->WithMetadataValue('IsReferenceAssembly', 'false')->'%(RootDir)%(Directory)%(FileName).xml')" />
<AspNetCoreReferenceDocXml Include="@(_SelectedExtensionsRefAssemblies->'$(MicrosoftInternalExtensionsRefsPath)%(FileName).xml')" />
</ItemGroup>
<RepoTasks.GenerateSharedFrameworkDepsFile
DepsFilePath="$(ProjectDepsFilePath)"
TargetFramework="$(TargetFramework)"
FrameworkName="$(TargetingPackName)"
FrameworkVersion="$(ReferencePackSharedFxVersion)"
References="@(AspNetCoreReferenceAssemblyPath)"
RuntimeIdentifier="$(TargetRuntimeIdentifier)"
RuntimePackageName="$(PackageId)"
PlatformManifestOutputPath="$(ReferencePlatformManifestOutputPath)" />
<ItemGroup>
<RefPackContent Include="@(AspNetCoreReferenceAssemblyPath)" PackagePath="$(RefAssemblyPackagePath)" />
<RefPackContent Include="@(AspNetCoreReferenceDocXml)" PackagePath="$(RefAssemblyPackagePath)" />
<RefPackContent Include="$(TargetDir)$(PackageConflictManifestFileName)" PackagePath="$(ManifestsPackagePath)" />
<RefPackContent Include="$(PlatformManifestOutputPath)" PackagePath="$(ManifestsPackagePath)" />
<RefPackContent Include="$(ReferencePlatformManifestOutputPath)" PackagePath="$(ManifestsPackagePath)" />
</ItemGroup>
</Target>
@ -130,9 +151,10 @@ This package is an internal implementation of the .NET Core SDK and is not meant
DependsOnTargets="ResolveReferences"
Inputs="$(MSBuildAllProjects)"
Outputs="$(TargetDir)$(PackageConflictManifestFileName)">
<ItemGroup>
<_AspNetCoreAppPackageOverrides Include="@(ReferencePath->'%(NuGetPackageId)|%(NuGetPackageVersion)')" Condition=" '%(ReferencePath.NuGetPackageId)' != 'Microsoft.NETCore.App' AND '%(ReferencePath.NuGetSourceType)' == 'Package' " />
<_AspNetCoreAppPackageOverrides Include="@(ReferencePath->'%(FileName)|$(SharedFxVersion)')" Condition=" '%(ReferencePath.ReferenceSourceTarget)' == 'ProjectReference' " />
<_AspNetCoreAppPackageOverrides Include="@(ReferencePath->'%(FileName)|$(ReferencePackSharedFxVersion)')" Condition=" '%(ReferencePath.ReferenceSourceTarget)' == 'ProjectReference' AND '%(ReferencePath.IsReferenceAssembly)' == 'true' " />
</ItemGroup>
<WriteLinesToFile

View File

@ -53,6 +53,13 @@
</ItemGroup>
<Target Name="GenerateTestData" BeforeTargets="GetAssemblyAttributes" DependsOnTargets="InitializeSourceControlInformation">
<!-- Use the ref pack logic to compute the list of expected targeting pack content -->
<MSBuild Projects="$(RepoRoot)src\Framework\ref\Microsoft.AspNetCore.App.Ref.csproj"
Targets="_ResolveTargetingPackContent"
SkipNonexistentProjects="false">
<Output TaskParameter="TargetOutputs" ItemName="_TargetingPackDependencies" />
</MSBuild>
<!-- This target is defined in eng/targets/Packaging.targets and included in every C# and F# project. -->
<MSBuild Projects="$(RepoRoot)src\Framework\src\Microsoft.AspNetCore.App.Runtime.csproj"
Targets="_GetPackageVersionInfo"
@ -68,6 +75,11 @@
</MSBuild>
<ItemGroup>
<AssemblyAttribute Include="Microsoft.AspNetCore.TestData">
<_Parameter1>TargetingPackDependencies</_Parameter1>
<_Parameter2>@(_TargetingPackDependencies)</_Parameter2>
</AssemblyAttribute>
<AssemblyAttribute Include="Microsoft.AspNetCore.TestData">
<_Parameter1>RepositoryCommit</_Parameter1>
<_Parameter2>$(SourceRevisionId)</_Parameter2>

View File

@ -59,8 +59,15 @@ namespace Microsoft.AspNetCore
public void PlatformManifestListsAllFiles()
{
var platformManifestPath = Path.Combine(_targetingPackRoot, "data", "PlatformManifest.txt");
var expectedAssemblies = TestData.GetSharedFxDependencies()
var expectedAssemblies = TestData.GetTargetingPackDependencies()
.Split(';', StringSplitOptions.RemoveEmptyEntries)
.Select(i =>
{
var fileName = Path.GetFileName(i);
return fileName.EndsWith(".dll", StringComparison.Ordinal)
? fileName.Substring(0, fileName.Length - 4)
: fileName;
})
.ToHashSet();
_output.WriteLine("==== file contents ====");

View File

@ -18,6 +18,8 @@ namespace Microsoft.AspNetCore
public static string GetSharedFxDependencies() => GetTestDataValue("SharedFxDependencies");
public static string GetTargetingPackDependencies() => GetTestDataValue("TargetingPackDependencies");
public static string GetTestDataValue(string key)
=> typeof(TestData).Assembly.GetCustomAttributes<TestDataAttribute>().Single(d => d.Key == key).Value;
}

View File

@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Hosting.StaticWebAssets
}
else
{
return InnerProvider.GetDirectoryContents(physicalPath);
return InnerProvider.GetDirectoryContents(physicalPath.Value);
}
}
@ -59,7 +59,7 @@ namespace Microsoft.AspNetCore.Hosting.StaticWebAssets
}
else
{
return InnerProvider.GetFileInfo(physicalPath);
return InnerProvider.GetFileInfo(physicalPath.Value);
}
}

View File

@ -9,6 +9,7 @@
<Compile Include="$(SharedSourceRoot)EventSource.Testing\TestEventListener.cs" />
<Compile Include="$(SharedSourceRoot)EventSource.Testing\TestCounterListener.cs" />
<Content Include="testroot\**\*" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" />
<None Remove="testroot\wwwroot\Static Web Assets.txt" />
<Content Include="Microsoft.AspNetCore.Hosting.StaticWebAssets.xml" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

View File

@ -37,6 +37,17 @@ namespace Microsoft.AspNetCore.Hosting.StaticWebAssets
Assert.Equal("/_content", provider.BasePath);
}
[Fact]
public void StaticWebAssetsFileProvider_FindsFileWithSpaces()
{
// Arrange & Act
var provider = new StaticWebAssetsFileProvider("/_content",
Path.Combine(AppContext.BaseDirectory, "testroot", "wwwroot"));
// Assert
Assert.True(provider.GetFileInfo("/_content/Static Web Assets.txt").Exists);
}
[Fact]
public void GetFileInfo_DoesNotMatch_IncompletePrefixSegments()
{

View File

@ -0,0 +1 @@
This file is here to validate that the static web assets file provider respect spaces.

View File

@ -0,0 +1,13 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
[assembly: TypeForwardedTo(typeof(IEndpointFeature))]
[assembly: TypeForwardedTo(typeof(IRouteValuesFeature))]
[assembly: TypeForwardedTo(typeof(Endpoint))]
[assembly: TypeForwardedTo(typeof(EndpointMetadataCollection))]
[assembly: TypeForwardedTo(typeof(RouteValueDictionary))]

View File

@ -5,6 +5,7 @@
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'">
<Compile Include="Microsoft.AspNetCore.Routing.Abstractions.netcoreapp.cs" />
<Compile Include="Microsoft.AspNetCore.Routing.Abstractions.Manual.cs" />
<Reference Include="Microsoft.AspNetCore.Http.Abstractions" />
</ItemGroup>
</Project>

View File

@ -23,7 +23,7 @@
<Target Name="Build" DependsOnTargets="DebBuild" />
<Target Name="Pack" />
<Target Name="DebBuild" DependsOnTargets="$(DebBuildDependsOn)">
<Target Name="DebBuild" DependsOnTargets="$(DebBuildDependsOn)" Condition="'$(IsTargetingPackBuilding)' != 'false'">
<!-- Generate debian_config.json. We can't simply use WriteLinesToFile because of https://github.com/Microsoft/msbuild/issues/1622. Use our custom GenerateFileFromTemplate task instead -->
<PropertyGroup>
<DebianConfigProperties>

View File

@ -32,7 +32,7 @@
<Target Name="Build" DependsOnTargets="RpmBuild" />
<Target Name="Pack" />
<Target Name="RpmBuild" DependsOnTargets="$(RpmBuildDependsOn)">
<Target Name="RpmBuild" DependsOnTargets="$(RpmBuildDependsOn)" Condition="'$(IsTargetingPackBuilding)' != 'false'">
<!-- Create layout: Create changelog -->
<PropertyGroup>
<ChangeLogProps>DATE=$([System.DateTime]::UtcNow.ToString(ddd MMM dd yyyy))</ChangeLogProps>

View File

@ -11,7 +11,8 @@ param(
[Parameter(Mandatory=$true)][string]$PackageVersion,
[Parameter(Mandatory=$true)][string]$RepoRoot,
[Parameter(Mandatory=$true)][string]$MajorVersion,
[Parameter(Mandatory=$true)][string]$MinorVersion
[Parameter(Mandatory=$true)][string]$MinorVersion,
[Parameter(Mandatory=$true)][string]$PackageIconPath
)
$NuGetDir = Join-Path $RepoRoot "artifacts\Tools\nuget\$Name\$Architecture"
@ -24,8 +25,8 @@ if (-not (Test-Path $NuGetDir)) {
if (-not (Test-Path $NuGetExe)) {
# Using 3.5.0 to workaround https://github.com/NuGet/Home/issues/5016
Write-Output "Downloading nuget.exe to $NuGetExe"
wget https://dist.nuget.org/win-x86-commandline/v3.5.0/nuget.exe -OutFile $NuGetExe
wget https://dist.nuget.org/win-x86-commandline/v5.3.0/nuget.exe -OutFile $NuGetExe
}
& $NuGetExe pack $NuspecFile -Version $PackageVersion -OutputDirectory $OutputDirectory -NoDefaultExcludes -NoPackageAnalysis -Properties ASPNETCORE_RUNTIME_MSI=$MsiPath`;ASPNETCORE_CAB_FILE=$CabPath`;ARCH=$Architecture`;MAJOR=$MajorVersion`;MINOR=$MinorVersion`;
& $NuGetExe pack $NuspecFile -Version $PackageVersion -OutputDirectory $OutputDirectory -NoDefaultExcludes -NoPackageAnalysis -Properties ASPNETCORE_RUNTIME_MSI=$MsiPath`;ASPNETCORE_CAB_FILE=$CabPath`;ARCH=$Architecture`;MAJOR=$MajorVersion`;MINOR=$MinorVersion`;PACKAGE_ICON_PATH=$PackageIconPath`;
Exit $LastExitCode

View File

@ -24,6 +24,10 @@
<ToolsetInstallerNuspecFile>$(RepoRoot)\src\Installers\Windows\SharedFramework\SharedFrameworkPackage.nuspec</ToolsetInstallerNuspecFile>
</PropertyGroup>
<ItemGroup>
<NuspecProperty Include="PackageIcon=$(PackageIconFullPath)" />
</ItemGroup>
<ItemGroup>
<WixExtension Include="WixDependencyExtension">
<HintPath>$(WixExtDir)\WixDependencyExtension.dll</HintPath>
@ -101,6 +105,7 @@
'$(_GeneratedPackageVersion)' ^
'$(RepoRoot)' ^
'$(AspNetCoreMajorVersion)' ^
'$(AspNetCoreMinorVersion)'" />
'$(AspNetCoreMinorVersion)' ^
'$(PackageIconFullPath)'" />
</Target>
</Project>

View File

@ -8,6 +8,7 @@
<owners>Microsoft</owners>
<licenseUrl>https://www.microsoft.com/net/dotnet_library_license.htm</licenseUrl>
<projectUrl>https://github.com/aspnet/aspnetcore</projectUrl>
<icon>packageIcon.png</icon>
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<description>$MAJOR$.$MINOR$ ASP.NET Core TargetingPack ($ARCH$) Windows Installer MSI as a .nupkg for internal Visual Studio build consumption</description>
<copyright>© Microsoft Corporation. All rights reserved.</copyright>
@ -15,5 +16,6 @@
<files>
<file src="$ASPNETCORE_RUNTIME_MSI$" />
<file src="$ASPNETCORE_CAB_FILE$" />
<file src="$PACKAGE_ICON_PATH$" target="" />
</files>
</package>

View File

@ -9,6 +9,7 @@
<OutputName>$(Name)-$(Platform)</OutputName>
<OutputType>Package</OutputType>
<IsShipping>true</IsShipping>
<SkipCopyToArtifactsDirectory Condition="'$(IsTargetingPackBuilding)' == 'false'">true</SkipCopyToArtifactsDirectory>
<ProjectGuid>0AC34F1B-8056-4FFB-A398-E6BB7D67B48D</ProjectGuid>
<HarvestDirectoryAutoGenerateGuids>true</HarvestDirectoryAutoGenerateGuids>
<HarvestDirectorySuppressSpecificWarnings>5150;5151</HarvestDirectorySuppressSpecificWarnings>
@ -22,6 +23,10 @@
<ToolsetInstallerNuspecFile>$(RepoRoot)\src\Installers\Windows\TargetingPack\TargetingPackPackage.nuspec</ToolsetInstallerNuspecFile>
</PropertyGroup>
<ItemGroup>
<NuspecProperty Include="PackageIcon=$(PackageIconFullPath)" />
</ItemGroup>
<ItemGroup>
<WixExtension Include="WixDependencyExtension">
<HintPath>$(WixExtDir)\WixDependencyExtension.dll</HintPath>
@ -97,6 +102,7 @@
'$(_GeneratedPackageVersion)' ^
'$(RepoRoot)' ^
'$(AspNetCoreMajorVersion)' ^
'$(AspNetCoreMinorVersion)'" />
'$(AspNetCoreMinorVersion)' ^
'$(PackageIconFullPath)'" />
</Target>
</Project>

View File

@ -8,11 +8,13 @@
<owners>Microsoft</owners>
<licenseUrl>https://www.microsoft.com/net/dotnet_library_license.htm</licenseUrl>
<projectUrl>https://github.com/aspnet/aspnetcore</projectUrl>
<icon>packageIcon.png</icon>
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<description>$MAJOR$.$MINOR$ ASP.NET Core TargetingPack ($ARCH$) Windows Installer MSI as a .nupkg for internal Visual Studio build consumption</description>
<copyright>© Microsoft Corporation. All rights reserved.</copyright>
</metadata>
<files>
<file src="$ASPNETCORE_RUNTIME_MSI$" />
<file src="$PACKAGE_ICON_PATH$" target="" />
</files>
</package>

View File

@ -63,7 +63,7 @@
</Target>
<Target Name="CopyToArtifactsDirectory"
Condition=" '$(IsShipping)' == 'true' "
Condition=" '$(IsShipping)' == 'true' AND '$(SkipCopyToArtifactsDirectory)' != 'true' "
AfterTargets="Build">
<Copy SourceFiles="$(TargetPath)" DestinationFiles="$(InstallersOutputPath)$(PackageFileName)" />
<ItemGroup>

View File

@ -823,6 +823,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
{
public TooManyModelErrorsException(string message) { }
}
public sealed partial class ValueProviderException : System.Exception
{
public ValueProviderException(string message) { }
public ValueProviderException(string message, System.Exception innerException) { }
}
public partial class ValueProviderFactoryContext
{
public ValueProviderFactoryContext(Microsoft.AspNetCore.Mvc.ActionContext context) { }

View File

@ -203,6 +203,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
throw new ArgumentNullException(nameof(exception));
}
if ((exception is InputFormatterException || exception is ValueProviderException)
&& !string.IsNullOrEmpty(exception.Message))
{
// InputFormatterException, ValueProviderException is a signal that the message is safe to expose to clients
return TryAddModelError(key, exception.Message);
}
if (ErrorCount >= MaxAllowedErrors - 1)
{
EnsureMaxErrorsReachedRecorded();
@ -311,9 +318,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
return TryAddModelError(key, errorMessage);
}
else if (exception is InputFormatterException && !string.IsNullOrEmpty(exception.Message))
else if ((exception is InputFormatterException || exception is ValueProviderException)
&& !string.IsNullOrEmpty(exception.Message))
{
// InputFormatterException is a signal that the message is safe to expose to clients
// InputFormatterException, ValueProviderException is a signal that the message is safe to expose to clients
return TryAddModelError(key, exception.Message);
}

View File

@ -0,0 +1,33 @@
// 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;
namespace Microsoft.AspNetCore.Mvc.ModelBinding
{
/// <summary>
/// Exception thrown by <see cref="IValueProviderFactory"/> when the input is unable to be read.
/// </summary>
public sealed class ValueProviderException : Exception
{
/// <summary>
/// Initializes a new instance of <see cref="ValueProviderException"/> with the specified <paramref name="message"/>.
/// </summary>
/// <param name="message">The exception message.</param>
public ValueProviderException(string message)
: base(message)
{
}
/// <summary>
/// Initializes a new instance of <see cref="ValueProviderException"/> with the specified <paramref name="message"/> and
/// inner exception that is the cause of this exception.
/// </summary>
/// <param name="message">The exception message.</param>
/// <param name="innerException">The exception that is the cause of the current exception.</param>
public ValueProviderException(string message, Exception innerException)
: base(message, innerException)
{
}
}
}

View File

@ -1207,8 +1207,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public void TryAddModelException_AddsErrorMessage_ForInputFormatterException()
{
// Arrange
var expectedMessage = "This is an InputFormatterException";
var dictionary = new ModelStateDictionary();
var exception = new InputFormatterException("This is an InputFormatterException.");
var exception = new InputFormatterException(expectedMessage);
// Act
dictionary.TryAddModelException("key", exception);
@ -1217,7 +1218,25 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var entry = Assert.Single(dictionary);
Assert.Equal("key", entry.Key);
var error = Assert.Single(entry.Value.Errors);
Assert.Same(exception, error.Exception);
Assert.Equal(expectedMessage, error.ErrorMessage);
}
[Fact]
public void TryAddModelException_AddsErrorMessage_ForValueProviderException()
{
// Arrange
var expectedMessage = "This is an ValueProviderException";
var dictionary = new ModelStateDictionary();
var exception = new ValueProviderException(expectedMessage);
// Act
dictionary.TryAddModelException("key", exception);
// Assert
var entry = Assert.Single(dictionary);
Assert.Equal("key", entry.Key);
var error = Assert.Single(entry.Value.Errors);
Assert.Equal(expectedMessage, error.ErrorMessage);
}
[Fact]
@ -1227,9 +1246,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var expectedMessage = "This is an InputFormatterException";
var dictionary = new ModelStateDictionary();
var bindingMetadataProvider = new DefaultBindingMetadataProvider();
var compositeProvider = new DefaultCompositeMetadataDetailsProvider(new[] { bindingMetadataProvider });
var provider = new DefaultModelMetadataProvider(compositeProvider, new OptionsAccessor());
var provider = new EmptyModelMetadataProvider();
var metadata = provider.GetMetadataForType(typeof(int));
// Act
@ -1242,6 +1259,26 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
Assert.Equal(expectedMessage, error.ErrorMessage);
}
[Fact]
public void ModelStateDictionary_AddsErrorMessage_ForValueProviderException()
{
// Arrange
var expectedMessage = "This is an ValueProviderException";
var dictionary = new ModelStateDictionary();
var provider = new EmptyModelMetadataProvider();
var metadata = provider.GetMetadataForType(typeof(int));
// Act
dictionary.TryAddModelError("key", new ValueProviderException(expectedMessage), metadata);
// Assert
var entry = Assert.Single(dictionary);
Assert.Equal("key", entry.Key);
var error = Assert.Single(entry.Value.Errors);
Assert.Equal(expectedMessage, error.ErrorMessage);
}
[Fact]
public void ModelStateDictionary_ClearEntriesThatMatchWithKey_NonEmptyKey()
{

View File

@ -19,6 +19,7 @@
<ItemGroup>
<NuspecProperty Include="OutputBinary=$(OutputPath)$(AssemblyName).dll" />
<NuspecProperty Include="OutputSymbol=$(OutputPath)$(AssemblyName).pdb" />
<NuspecProperty Include="PackageIcon=$(PackageIconFullPath)" />
</ItemGroup>
</Project>

View File

@ -2,10 +2,12 @@
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
$CommonMetadataElements$
<icon>packageIcon.png</icon>
</metadata>
<files>
<file src="$OutputBinary$" target="analyzers\dotnet\cs\" />
<file src="$OutputSymbol$" target="analyzers\dotnet\cs\" />
<file src="$PackageIcon$" target="" />
</files>
</package>

View File

@ -24,6 +24,7 @@
<ItemGroup>
<NuspecProperty Include="OutputBinary=$(OutputPath)$(AssemblyName).dll" />
<NuspecProperty Include="OutputSymbol=$(OutputPath)$(AssemblyName).pdb" />
<NuspecProperty Include="PackageIcon=$(PackageIconFullPath)" />
</ItemGroup>
</Project>

View File

@ -2,10 +2,12 @@
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
$CommonMetadataElements$
<icon>packageIcon.png</icon>
</metadata>
<files>
<file src="$OutputBinary$" target="analyzers\dotnet\cs\" />
<file src="$OutputSymbol$" target="analyzers\dotnet\cs\" />
<file src="$PackageIcon$" target="" />
</files>
</package>

View File

@ -0,0 +1,13 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Runtime.CompilerServices;
[assembly: TypeForwardedTo(typeof(Microsoft.AspNetCore.Mvc.ApiExplorer.IApiDescriptionProvider))]
[assembly: TypeForwardedTo(typeof(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiDescription))]
[assembly: TypeForwardedTo(typeof(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiDescriptionProviderContext))]
[assembly: TypeForwardedTo(typeof(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiParameterDescription))]
[assembly: TypeForwardedTo(typeof(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiParameterRouteInfo))]
[assembly: TypeForwardedTo(typeof(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiRequestFormat))]
[assembly: TypeForwardedTo(typeof(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiResponseFormat))]
[assembly: TypeForwardedTo(typeof(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiResponseType))]

View File

@ -5,6 +5,7 @@
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'">
<Compile Include="Microsoft.AspNetCore.Mvc.ApiExplorer.netcoreapp.cs" />
<Compile Include="Microsoft.AspNetCore.Mvc.ApiExplorer.Manual.cs" />
<Reference Include="Microsoft.AspNetCore.Mvc.Core" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Mvc.Formatters;
[assembly: TypeForwardedTo(typeof(InputFormatterException))]

View File

@ -5,6 +5,7 @@
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'">
<Compile Include="Microsoft.AspNetCore.Mvc.Core.netcoreapp.cs" />
<Compile Include="Microsoft.AspNetCore.Mvc.Core.Manual.cs" />
<Reference Include="Microsoft.AspNetCore.Mvc.Abstractions" />
<Reference Include="Microsoft.AspNetCore.Authentication.Core" />
<Reference Include="Microsoft.AspNetCore.Authorization.Policy" />

View File

@ -137,6 +137,11 @@ namespace Microsoft.AspNetCore.Mvc
public ApiConventionTypeAttribute(System.Type conventionType) { }
public System.Type ConventionType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
}
public partial class ApiDescriptionActionData
{
public ApiDescriptionActionData() { }
public string GroupName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
}
[System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=false, Inherited=true)]
public partial class ApiExplorerSettingsAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiDescriptionGroupNameProvider, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiDescriptionVisibilityProvider
{

View File

@ -7,7 +7,7 @@ namespace Microsoft.AspNetCore.Mvc
/// Represents data used to build an <c>ApiDescription</c>, stored as part of the
/// <see cref="Abstractions.ActionDescriptor.Properties"/>.
/// </summary>
internal class ApiDescriptionActionData
public class ApiDescriptionActionData
{
/// <summary>
/// The <c>ApiDescription.GroupName</c> of <c>ApiDescription</c> objects for the associated

View File

@ -2476,7 +2476,12 @@ namespace Microsoft.AspNetCore.Mvc
throw new ArgumentNullException(nameof(prefix));
}
var valueProvider = await CompositeValueProvider.CreateAsync(ControllerContext);
var (success, valueProvider) = await CompositeValueProvider.TryCreateAsync(ControllerContext, ControllerContext.ValueProviderFactories);
if (!success)
{
return false;
}
return await TryUpdateModelAsync(model, prefix, valueProvider);
}
@ -2550,7 +2555,12 @@ namespace Microsoft.AspNetCore.Mvc
throw new ArgumentNullException(nameof(includeExpressions));
}
var valueProvider = await CompositeValueProvider.CreateAsync(ControllerContext);
var (success, valueProvider) = await CompositeValueProvider.TryCreateAsync(ControllerContext, ControllerContext.ValueProviderFactories);
if (!success)
{
return false;
}
return await ModelBindingHelper.TryUpdateModelAsync(
model,
prefix,
@ -2589,7 +2599,12 @@ namespace Microsoft.AspNetCore.Mvc
throw new ArgumentNullException(nameof(propertyFilter));
}
var valueProvider = await CompositeValueProvider.CreateAsync(ControllerContext);
var (success, valueProvider) = await CompositeValueProvider.TryCreateAsync(ControllerContext, ControllerContext.ValueProviderFactories);
if (!success)
{
return false;
}
return await ModelBindingHelper.TryUpdateModelAsync(
model,
prefix,
@ -2717,7 +2732,12 @@ namespace Microsoft.AspNetCore.Mvc
throw new ArgumentNullException(nameof(modelType));
}
var valueProvider = await CompositeValueProvider.CreateAsync(ControllerContext);
var (success, valueProvider) = await CompositeValueProvider.TryCreateAsync(ControllerContext, ControllerContext.ValueProviderFactories);
if (!success)
{
return false;
}
return await ModelBindingHelper.TryUpdateModelAsync(
model,
modelType,

View File

@ -59,7 +59,12 @@ namespace Microsoft.AspNetCore.Mvc.Controllers
async Task Bind(ControllerContext controllerContext, object controller, Dictionary<string, object> arguments)
{
var valueProvider = await CompositeValueProvider.CreateAsync(controllerContext);
var (success, valueProvider) = await CompositeValueProvider.TryCreateAsync(controllerContext, controllerContext.ValueProviderFactories);
if (!success)
{
return;
}
var parameters = actionDescriptor.Parameters;
for (var i = 0; i < parameters.Count; i++)

View File

@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
var problemDetails = new ProblemDetails();
if (!reader.Read())
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException(Resources.UnexpectedJsonEnd);
}

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
var problemDetails = new ValidationProblemDetails();
if (!reader.Read())
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException(Resources.UnexpectedJsonEnd);
}

View File

@ -80,6 +80,22 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
return new CompositeValueProvider(valueProviderFactoryContext.ValueProviders);
}
internal static async ValueTask<(bool success, CompositeValueProvider valueProvider)> TryCreateAsync(
ActionContext actionContext,
IList<IValueProviderFactory> factories)
{
try
{
var valueProvider = await CreateAsync(actionContext, factories);
return (true, valueProvider);
}
catch (ValueProviderException exception)
{
actionContext.ModelState.TryAddModelException(key: string.Empty, exception);
return (false, null);
}
}
/// <inheritdoc />
public virtual bool ContainsPrefix(string prefix)
{

View File

@ -2,8 +2,10 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Core;
namespace Microsoft.AspNetCore.Mvc.ModelBinding
{
@ -32,10 +34,20 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
private static async Task AddValueProviderAsync(ValueProviderFactoryContext context, HttpRequest request)
{
var formCollection = await request.ReadFormAsync();
if (formCollection.Files.Count > 0)
IFormCollection form;
try
{
var valueProvider = new FormFileValueProvider(formCollection.Files);
form = await request.ReadFormAsync();
}
catch (InvalidDataException ex)
{
throw new ValueProviderException(Resources.FormatFailedToReadRequestForm(ex.Message), ex);
}
if (form.Files.Count > 0)
{
var valueProvider = new FormFileValueProvider(form.Files);
context.ValueProviders.Add(valueProvider);
}
}

View File

@ -3,7 +3,10 @@
using System;
using System.Globalization;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Core;
namespace Microsoft.AspNetCore.Mvc.ModelBinding
{
@ -33,9 +36,20 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
private static async Task AddValueProviderAsync(ValueProviderFactoryContext context)
{
var request = context.ActionContext.HttpContext.Request;
IFormCollection form;
try
{
form = await request.ReadFormAsync();
}
catch (InvalidDataException ex)
{
throw new ValueProviderException(Resources.FormatFailedToReadRequestForm(ex.Message), ex);
}
var valueProvider = new FormValueProvider(
BindingSource.Form,
await request.ReadFormAsync(),
form,
CultureInfo.CurrentCulture);
context.ValueProviders.Add(valueProvider);

View File

@ -513,4 +513,7 @@
<data name="ApiConventions_Title_500" xml:space="preserve">
<value>An error occured while processing your request.</value>
</data>
<data name="FailedToReadRequestForm" xml:space="preserve">
<value>Failed to read the request form. {0}</value>
</data>
</root>

View File

@ -2607,6 +2607,31 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
Assert.NotEqual(0, binder.BindModelCount);
}
[Fact]
public async Task TryUpdateModel_ReturnsFalse_IfValueProviderFactoryThrows()
{
// Arrange
var modelName = "mymodel";
var valueProviderFactory = new Mock<IValueProviderFactory>();
valueProviderFactory.Setup(f => f.CreateValueProviderAsync(It.IsAny<ValueProviderFactoryContext>()))
.Throws(new ValueProviderException("some error"));
var controller = GetController(new StubModelBinder());
controller.ControllerContext.ValueProviderFactories.Add(valueProviderFactory.Object);
var model = new MyModel();
// Act
var result = await controller.TryUpdateModelAsync(model, modelName);
// Assert
Assert.False(result);
var modelState = Assert.Single(controller.ModelState);
Assert.Empty(modelState.Key);
var error = Assert.Single(modelState.Value.Errors);
Assert.Equal("some error", error.ErrorMessage);
}
[Fact]
public async Task TryUpdateModel_PropertyFilterOverload_UsesPassedArguments()
{
@ -3037,7 +3062,7 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
});
}
private static ControllerBase GetController(IModelBinder binder, IValueProvider valueProvider)
private static ControllerBase GetController(IModelBinder binder, IValueProvider valueProvider = null)
{
var metadataProvider = new EmptyModelMetadataProvider();
var services = new ServiceCollection();
@ -3056,11 +3081,11 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
stringLocalizerFactory: null),
};
valueProvider = valueProvider ?? new SimpleValueProvider();
valueProvider ??= new SimpleValueProvider();
var controllerContext = new ControllerContext()
{
HttpContext = httpContext,
ValueProviderFactories = new[] { new SimpleValueProviderFactory(valueProvider), },
ValueProviderFactories = new List<IValueProviderFactory> { new SimpleValueProviderFactory(valueProvider), },
};
var binderFactory = new Mock<IModelBinderFactory>();

View File

@ -1202,6 +1202,54 @@ namespace Microsoft.AspNetCore.Mvc.Controllers
Assert.Equal(250.0, transferInfo.Amount);
}
[Fact]
public async Task BinderDelegateRecordsErrorWhenValueProviderThrowsValueProviderException()
{
// Arrange
var actionDescriptor = new ControllerActionDescriptor()
{
BoundProperties = new List<ParameterDescriptor>(),
Parameters = new[] { new ParameterDescriptor { Name = "name", ParameterType = typeof(string) } },
};
var modelMetadataProvider = new EmptyModelMetadataProvider();
var modelBinderProvider = Mock.Of<IModelBinderProvider>();
var factory = TestModelBinderFactory.CreateDefault(modelBinderProvider);
var modelValidatorProvider = Mock.Of<IModelValidatorProvider>();
var parameterBinder = new ParameterBinder(
new EmptyModelMetadataProvider(),
factory,
GetObjectValidator(modelMetadataProvider, modelValidatorProvider),
_optionsAccessor,
NullLoggerFactory.Instance);
var valueProviderFactory = new Mock<IValueProviderFactory>();
valueProviderFactory.Setup(f => f.CreateValueProviderAsync(It.IsAny<ValueProviderFactoryContext>()))
.Throws(new ValueProviderException("Some error"));
var controllerContext = GetControllerContext(actionDescriptor);
controllerContext.ValueProviderFactories.Add(valueProviderFactory.Object);
var arguments = new Dictionary<string, object>(StringComparer.Ordinal);
var modelState = controllerContext.ModelState;
// Act
var binderDelegate = ControllerBinderDelegateProvider.CreateBinderDelegate(
parameterBinder,
factory,
TestModelMetadataProvider.CreateDefaultProvider(),
actionDescriptor,
_options);
await binderDelegate(controllerContext, new TestController(), arguments);
// Assert
var entry = Assert.Single(modelState);
Assert.Empty(entry.Key);
var error = Assert.Single(entry.Value.Errors);
Assert.Equal("Some error", error.ErrorMessage);
}
private static ControllerContext GetControllerContext(ControllerActionDescriptor descriptor = null)
{
var services = new ServiceCollection();

View File

@ -8,7 +8,7 @@ using Xunit;
namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
public class ProblemDetailsConverterTest
public class ProblemDetailsJsonConverterTest
{
private static JsonSerializerOptions JsonSerializerOptions => new JsonOptions().JsonSerializerOptions;
@ -41,6 +41,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
var json = $"{{\"type\":\"{type}\",\"title\":\"{title}\",\"status\":{status},\"detail\":\"{detail}\", \"instance\":\"{instance}\",\"traceId\":\"{traceId}\"}}";
var converter = new ProblemDetailsJsonConverter();
var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json));
reader.Read();
// Act
var problemDetails = converter.Read(ref reader, typeof(ProblemDetails), JsonSerializerOptions);
@ -59,6 +60,35 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
});
}
[Fact]
public void Read_UsingJsonSerializerWorks()
{
// Arrange
var type = "https://tools.ietf.org/html/rfc7231#section-6.5.4";
var title = "Not found";
var status = 404;
var detail = "Product not found";
var instance = "http://example.com/products/14";
var traceId = "|37dd3dd5-4a9619f953c40a16.";
var json = $"{{\"type\":\"{type}\",\"title\":\"{title}\",\"status\":{status},\"detail\":\"{detail}\", \"instance\":\"{instance}\",\"traceId\":\"{traceId}\"}}";
// Act
var problemDetails = JsonSerializer.Deserialize<ProblemDetails>(json, JsonSerializerOptions);
Assert.Equal(type, problemDetails.Type);
Assert.Equal(title, problemDetails.Title);
Assert.Equal(status, problemDetails.Status);
Assert.Equal(instance, problemDetails.Instance);
Assert.Equal(detail, problemDetails.Detail);
Assert.Collection(
problemDetails.Extensions,
kvp =>
{
Assert.Equal("traceId", kvp.Key);
Assert.Equal(traceId, kvp.Value.ToString());
});
}
[Fact]
public void Read_WithSomeMissingValues_Works()
{
@ -70,6 +100,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
var json = $"{{\"type\":\"{type}\",\"title\":\"{title}\",\"status\":{status},\"traceId\":\"{traceId}\"}}";
var converter = new ProblemDetailsJsonConverter();
var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json));
reader.Read();
// Act
var problemDetails = converter.Read(ref reader, typeof(ProblemDetails), JsonSerializerOptions);

View File

@ -9,7 +9,7 @@ using Xunit;
namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
public class ValidationProblemDetailsConverterTest
public class ValidationProblemDetailsJsonConverterTest
{
private static JsonSerializerOptions JsonSerializerOptions => new JsonOptions().JsonSerializerOptions;
@ -27,6 +27,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
"\"errors\":{\"key0\":[\"error0\"],\"key1\":[\"error1\",\"error2\"]}}";
var converter = new ValidationProblemDetailsJsonConverter();
var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json));
reader.Read();
// Act
var problemDetails = converter.Read(ref reader, typeof(ValidationProblemDetails), JsonSerializerOptions);
@ -65,12 +66,14 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
var title = "Not found";
var status = 404;
var traceId = "|37dd3dd5-4a9619f953c40a16.";
var json = $"{{\"type\":\"{type}\",\"title\":\"{title}\",\"status\":{status},\"traceId\":\"{traceId}\"}}";
var converter = new ProblemDetailsJsonConverter();
var json = $"{{\"type\":\"{type}\",\"title\":\"{title}\",\"status\":{status},\"traceId\":\"{traceId}\"," +
"\"errors\":{\"key0\":[\"error0\"],\"key1\":[\"error1\",\"error2\"]}}";
var converter = new ValidationProblemDetailsJsonConverter();
var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json));
reader.Read();
// Act
var problemDetails = converter.Read(ref reader, typeof(ProblemDetails), JsonSerializerOptions);
var problemDetails = converter.Read(ref reader, typeof(ValidationProblemDetails), JsonSerializerOptions);
Assert.Equal(type, problemDetails.Type);
Assert.Equal(title, problemDetails.Title);
@ -82,6 +85,56 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
Assert.Equal("traceId", kvp.Key);
Assert.Equal(traceId, kvp.Value.ToString());
});
Assert.Collection(
problemDetails.Errors.OrderBy(kvp => kvp.Key),
kvp =>
{
Assert.Equal("key0", kvp.Key);
Assert.Equal(new[] { "error0" }, kvp.Value);
},
kvp =>
{
Assert.Equal("key1", kvp.Key);
Assert.Equal(new[] { "error1", "error2" }, kvp.Value);
});
}
[Fact]
public void ReadUsingJsonSerializerWorks()
{
// Arrange
var type = "https://tools.ietf.org/html/rfc7231#section-6.5.4";
var title = "Not found";
var status = 404;
var traceId = "|37dd3dd5-4a9619f953c40a16.";
var json = $"{{\"type\":\"{type}\",\"title\":\"{title}\",\"status\":{status},\"traceId\":\"{traceId}\"," +
"\"errors\":{\"key0\":[\"error0\"],\"key1\":[\"error1\",\"error2\"]}}";
// Act
var problemDetails = JsonSerializer.Deserialize<ValidationProblemDetails>(json, JsonSerializerOptions);
Assert.Equal(type, problemDetails.Type);
Assert.Equal(title, problemDetails.Title);
Assert.Equal(status, problemDetails.Status);
Assert.Collection(
problemDetails.Extensions,
kvp =>
{
Assert.Equal("traceId", kvp.Key);
Assert.Equal(traceId, kvp.Value.ToString());
});
Assert.Collection(
problemDetails.Errors.OrderBy(kvp => kvp.Key),
kvp =>
{
Assert.Equal("key0", kvp.Key);
Assert.Equal(new[] { "error0" }, kvp.Value);
},
kvp =>
{
Assert.Equal("key1", kvp.Key);
Assert.Equal(new[] { "error1", "error2" }, kvp.Value);
});
}
[Fact]

Some files were not shown because too many files have changed in this diff Show More