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. --> <!-- Contact email address for NuGet packages and Linux installers. -->
<MaintainerEmail>nugetaspnet@microsoft.com</MaintainerEmail> <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> <PackageProjectUrl>https://asp.net</PackageProjectUrl>
<NuspecBasePath>$(MSBuildProjectDirectory)</NuspecBasePath> <NuspecBasePath>$(MSBuildProjectDirectory)</NuspecBasePath>
@ -55,6 +56,10 @@
<DefaultNetCoreTargetFramework>netcoreapp5.0</DefaultNetCoreTargetFramework> <DefaultNetCoreTargetFramework>netcoreapp5.0</DefaultNetCoreTargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Include="$(PackageIconFullPath)" Pack="true" PackagePath="\"/>
</ItemGroup>
<!-- Warnings and errors --> <!-- Warnings and errors -->
<PropertyGroup> <PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
@ -90,7 +95,7 @@
<TargetingPackInstallerBaseName>aspnetcore-targeting-pack</TargetingPackInstallerBaseName> <TargetingPackInstallerBaseName>aspnetcore-targeting-pack</TargetingPackInstallerBaseName>
<!-- Used to only produce targeting pack installers/packages once per major.minor. --> <!-- 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. Archives and installers using this prefix are intended for internal-use only.

View File

@ -58,7 +58,8 @@
<Import Project="eng\Baseline.Designer.props" /> <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> <IsPackageInThisPatch Condition="'$(IsPackageInThisPatch)' == ''">$(PackagesInPatch.Contains(' $(PackageId);'))</IsPackageInThisPatch>
</PropertyGroup> </PropertyGroup>
@ -104,6 +105,12 @@
<Compile Include="$(SharedSourceRoot)ReferenceAssemblyInfo.cs" LinkBase="Properties" /> <Compile Include="$(SharedSourceRoot)ReferenceAssemblyInfo.cs" LinkBase="Properties" />
</ItemGroup> </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> <ItemGroup>
<KnownFrameworkReference Update="Microsoft.NETCore.App"> <KnownFrameworkReference Update="Microsoft.NETCore.App">
<!-- Always update the 'latest version', whether the repo is servicing or not. --> <!-- Always update the 'latest version', whether the repo is servicing or not. -->

View File

@ -3,6 +3,7 @@
<packageSources> <packageSources>
<clear /> <clear />
<add key="dotnet-core" value="https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json" /> <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-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-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" /> <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 This file contains a list of all the packages and their versions which were released in ASP.NET Core 3.0.0.
build of ASP.NET Core 2.2.x. Update this list when preparing for a new patch. Update this list when preparing for a new patch.
--> -->
<Baseline Version="2.2.7">
<Package Id="dotnet-dev-certs" Version="2.2.0" /> <Baseline Version="3.0.0">
<Package Id="dotnet-sql-cache" Version="2.2.0" /> <Package Id="AspNetCoreRuntime.3.0.x64" Version="3.0.0" />
<Package Id="dotnet-user-secrets" Version="2.2.0" /> <Package Id="AspNetCoreRuntime.3.0.x86" Version="3.0.0" />
<Package Id="dotnet-watch" Version="2.2.0" /> <Package Id="dotnet-sql-cache" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Antiforgery" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.ApiAuthorization.IdentityServer" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.ApiAuthorization.IdentityServer" Version="2.2.0-preview-35687" /> <Package Id="Microsoft.AspNetCore.App.Runtime.win-x64" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.ApplicationInsights.HostingStartup" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Authentication.AzureAD.UI" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.AspNetCoreModule" Version="2.2.7" /> <Package Id="Microsoft.AspNetCore.Authentication.AzureADB2C.UI" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.AspNetCoreModuleV2" Version="2.2.7" /> <Package Id="Microsoft.AspNetCore.Authentication.Certificate" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.Abstractions" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Authentication.Facebook" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.AzureAD.UI" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Authentication.Google" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.AzureADB2C.UI" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.Core" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Authentication.Negotiate" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.Facebook" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.Google" Version="2.2.2" /> <Package Id="Microsoft.AspNetCore.Authentication.Twitter" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Authentication.WsFederation" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Authorization" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.OAuth" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.AzureAppServices.HostingStartup" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.AzureAppServices.SiteExtension" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.Twitter" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.AzureAppServicesIntegration" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Authentication.WsFederation" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Blazor" Version="3.0.0-preview9.19465.2" />
<Package Id="Microsoft.AspNetCore.Authentication" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Blazor.Build" Version="3.0.0-preview9.19465.2" />
<Package Id="Microsoft.AspNetCore.Authorization.Policy" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Blazor.DevServer" Version="3.0.0-preview9.19465.2" />
<Package Id="Microsoft.AspNetCore.Authorization" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Blazor.HttpClient" Version="3.0.0-preview9.19465.2" />
<Package Id="Microsoft.AspNetCore.AzureAppServices.HostingStartup" Version="2.2.5" /> <Package Id="Microsoft.AspNetCore.Blazor.Server" Version="3.0.0-preview9.19465.2" />
<Package Id="Microsoft.AspNetCore.AzureAppServicesIntegration" Version="2.2.5" /> <Package Id="Microsoft.AspNetCore.Blazor.Templates" Version="3.0.0-preview9.19465.2" />
<Package Id="Microsoft.AspNetCore.Connections.Abstractions" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Components" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.CookiePolicy" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Components.Analyzers" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Cors" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Components.Authorization" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Cryptography.Internal" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Components.Forms" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Components.Web" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.DataProtection.Abstractions" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.ConcurrencyLimiter" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.DataProtection.AzureKeyVault" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Connections.Abstractions" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.DataProtection.AzureStorage" Version="2.2.7" /> <Package Id="Microsoft.AspNetCore.Cryptography.Internal" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.DataProtection.Extensions" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.DataProtection" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="2.2.5" /> <Package Id="Microsoft.AspNetCore.DataProtection.Abstractions" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.DataProtection.SystemWeb" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.DataProtection.AzureKeyVault" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.DataProtection" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.DataProtection.AzureStorage" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Diagnostics.Abstractions" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="2.2.1" /> <Package Id="Microsoft.AspNetCore.DataProtection.Extensions" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Diagnostics" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.HostFiltering" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.HeaderPropagation" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Hosting.WindowsServices" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Hosting.Server.Abstractions" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Http.Connections.Client" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Hosting.WindowsServices" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Http.Connections.Common" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Hosting" Version="2.2.7" /> <Package Id="Microsoft.AspNetCore.Http.Features" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Html.Abstractions" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Identity.Specification.Tests" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Http.Connections.Client" Version="1.1.0" /> <Package Id="Microsoft.AspNetCore.Identity.UI" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Http.Connections.Common" Version="1.1.0" /> <Package Id="Microsoft.AspNetCore.JsonPatch" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Http.Connections" Version="1.1.0" /> <Package Id="Microsoft.AspNetCore.Metadata" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Http.Extensions" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.MiddlewareAnalysis" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Http.Features" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Http" Version="2.2.2" /> <Package Id="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.HttpOverrides" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Mvc.Testing" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.HttpsPolicy" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.NodeServices" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Owin" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Identity.Specification.Tests" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Identity.UI" Version="2.2.5" /> <Package Id="Microsoft.AspNetCore.SignalR.Client" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Identity" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.SignalR.Client.Core" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.JsonPatch" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.SignalR.Common" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Localization.Routing" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.SignalR.Protocols.Json" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Localization" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.MiddlewareAnalysis" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.SignalR.Specification.Tests" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Analyzers" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Api.Analyzers" Version="2.2.6" /> <Package Id="Microsoft.AspNetCore.SpaServices" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Mvc.ApiExplorer" Version="2.2.0" /> <Package Id="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" /> <Package Id="Microsoft.AspNetCore.TestHost" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Cors" Version="2.2.0" /> <Package Id="Microsoft.dotnet-openapi" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Mvc.DataAnnotations" Version="2.2.0" /> <Package Id="Microsoft.DotNet.Web.Client.ItemTemplates" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Formatters.Json" Version="2.2.0" /> <Package Id="Microsoft.DotNet.Web.ItemTemplates" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Formatters.Xml" Version="2.2.0" /> <Package Id="Microsoft.DotNet.Web.ProjectTemplates.3.0" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Localization" Version="2.2.0" /> <Package Id="Microsoft.DotNet.Web.Spa.ProjectTemplates.3.0" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Razor.Extensions" Version="2.2.0" /> <Package Id="Microsoft.Extensions.ApiDescription.Client" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Razor" Version="2.2.0" /> <Package Id="Microsoft.Extensions.ApiDescription.Server" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Mvc.RazorPages" Version="2.2.5" /> <Package Id="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Mvc.TagHelpers" Version="2.2.0" /> <Package Id="Microsoft.Extensions.Identity.Core" Version="3.0.0" />
<Package Id="Microsoft.AspNetCore.Mvc.Testing" Version="2.2.0" /> <Package Id="Microsoft.Extensions.Identity.Stores" Version="3.0.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> </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. 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. 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> <IsPackageInThisPatch>$(PackagesInPatch.Contains(' $(PackageId);'))</IsPackageInThisPatch>
--> -->
<Project> <Project>
@ -15,59 +15,14 @@ Later on, this will be checked using this condition:
<PropertyGroup Condition=" '$(VersionPrefix)' == '3.0.1' "> <PropertyGroup Condition=" '$(VersionPrefix)' == '3.0.1' ">
<PackagesInPatch> <PackagesInPatch>
</PackagesInPatch> Microsoft.Net.Http.Headers;
</PropertyGroup> Microsoft.AspNetCore.CookiePolicy;
<PropertyGroup Condition=" '$(VersionPrefix)' == '2.2.2' "> Microsoft.AspNetCore.DataProtection.EntityFrameworkCore;
<PackagesInPatch> @microsoft/signalr;
@aspnet/signalr; Microsoft.Net.Http.Headers;
Microsoft.AspNetCore.AspNetCoreModuleV2; Microsoft.AspNetCore.Http.Abstractions;
Microsoft.AspNetCore.Authentication.Google; Microsoft.AspNetCore.Http.Features;
Microsoft.AspNetCore.Http; Microsoft.AspNetCore.CookiePolicy;
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>
</PackagesInPatch> </PackagesInPatch>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

View File

@ -412,17 +412,17 @@
<Uri>https://github.com/aspnet/Extensions</Uri> <Uri>https://github.com/aspnet/Extensions</Uri>
<Sha>1dfe8bc2af511822677789c29a0c800f7cca1d7b</Sha> <Sha>1dfe8bc2af511822677789c29a0c800f7cca1d7b</Sha>
</Dependency> </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> <Uri>https://github.com/dotnet/arcade</Uri>
<Sha>f8546fbab59a74a66c83b8cb76b3f6877ce1d374</Sha> <Sha>f70d1fca3d5d4045be75694006f1bee0e0aec572</Sha>
</Dependency> </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> <Uri>https://github.com/dotnet/arcade</Uri>
<Sha>f8546fbab59a74a66c83b8cb76b3f6877ce1d374</Sha> <Sha>f70d1fca3d5d4045be75694006f1bee0e0aec572</Sha>
</Dependency> </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> <Uri>https://github.com/dotnet/arcade</Uri>
<Sha>f8546fbab59a74a66c83b8cb76b3f6877ce1d374</Sha> <Sha>f70d1fca3d5d4045be75694006f1bee0e0aec572</Sha>
</Dependency> </Dependency>
<Dependency Name="Microsoft.AspNetCore.Testing" Version="5.0.0-alpha1.19512.1" CoherentParentDependency="Microsoft.EntityFrameworkCore"> <Dependency Name="Microsoft.AspNetCore.Testing" Version="5.0.0-alpha1.19512.1" CoherentParentDependency="Microsoft.EntityFrameworkCore">
<Uri>https://github.com/aspnet/Extensions</Uri> <Uri>https://github.com/aspnet/Extensions</Uri>

View File

@ -20,8 +20,15 @@
<AspNetCoreMajorMinorVersion>$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion)</AspNetCoreMajorMinorVersion> <AspNetCoreMajorMinorVersion>$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion)</AspNetCoreMajorMinorVersion>
<!-- Additional assembly attributes are already configured to include the source revision ID. --> <!-- Additional assembly attributes are already configured to include the source revision ID. -->
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion> <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. --> <!-- 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> <VersionPrefix>$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion).$(AspNetCorePatchVersion)</VersionPrefix>
<!-- TargetingPackVersionPrefix is used by projects, like .deb and .rpm, which use slightly different version formats. --> <!-- TargetingPackVersionPrefix is used by projects, like .deb and .rpm, which use slightly different version formats. -->
<TargetingPackVersionPrefix>$(VersionPrefix)</TargetingPackVersionPrefix> <TargetingPackVersionPrefix>$(VersionPrefix)</TargetingPackVersionPrefix>
@ -55,7 +62,7 @@
--> -->
<PropertyGroup Label="Automated"> <PropertyGroup Label="Automated">
<!-- Packages from dotnet/arcade --> <!-- Packages from dotnet/arcade -->
<MicrosoftDotNetGenAPIPackageVersion>1.0.0-beta.19462.4</MicrosoftDotNetGenAPIPackageVersion> <MicrosoftDotNetGenAPIPackageVersion>1.0.0-beta.19510.3</MicrosoftDotNetGenAPIPackageVersion>
<!-- Packages from dotnet/roslyn --> <!-- Packages from dotnet/roslyn -->
<MicrosoftNetCompilersToolsetPackageVersion>3.4.0-beta1-19456-03</MicrosoftNetCompilersToolsetPackageVersion> <MicrosoftNetCompilersToolsetPackageVersion>3.4.0-beta1-19456-03</MicrosoftNetCompilersToolsetPackageVersion>
<!-- Packages from dotnet/core-setup --> <!-- 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" $ErrorActionPreference = "Stop"
Set-StrictMode -Version 2.0 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 = { $ExtractPackage = {
param( param(
[string] $PackagePath # Full path to a NuGet package [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 publishInstallersAndChecksums: false
stages: stages:
- stage: NetCore_Dev30_Publish - stage: NetCore_3_Tools_Publish
dependsOn: validate dependsOn: validate
variables: variables:
- template: ../common-variables.yml - template: ../common-variables.yml
displayName: .NET Core 3.0 Dev Publishing displayName: .NET 3 Tools Publishing
jobs: jobs:
- template: ../setup-maestro-vars.yml - template: ../setup-maestro-vars.yml
- job: - job:
displayName: Symbol Publishing displayName: Symbol Publishing
dependsOn: setupMaestroVars 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: variables:
- group: DotNet-Symbol-Server-Pats - group: DotNet-Symbol-Server-Pats
pool: pool:
@ -56,7 +56,7 @@ stages:
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
- name: IsStableBuild - name: IsStableBuild
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.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: pool:
vmImage: 'windows-2019' vmImage: 'windows-2019'
steps: steps:
@ -85,10 +85,14 @@ stages:
- task: NuGetAuthenticate@0 - task: NuGetAuthenticate@0
displayName: 'Authenticate to AzDO Feeds' 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 - task: PowerShell@2
displayName: Publish Assets displayName: Publish Assets
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
inputs: inputs:
filePath: eng\common\sdk-task.ps1 filePath: eng\common\sdk-task.ps1
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
@ -113,14 +117,14 @@ stages:
/p:ChecksumsTargetStaticFeed=$(ChecksumsBlobFeedUrl) /p:ChecksumsTargetStaticFeed=$(ChecksumsBlobFeedUrl)
/p:ChecksumsAzureAccountKey=$(dotnetclichecksums-storage-key) /p:ChecksumsAzureAccountKey=$(dotnetclichecksums-storage-key)
/p:PublishToAzureDevOpsNuGetFeeds=true /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: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: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)' /p:AzureDevOpsStaticSymbolsFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
${{ parameters.artifactsPublishingAdditionalParameters }} ${{ parameters.artifactsPublishingAdditionalParameters }}
- template: ../../steps/promote-build.yml - template: ../../steps/promote-build.yml
parameters: parameters:
ChannelId: ${{ variables.PublicDevRelease_30_Channel_Id }} ChannelId: ${{ variables.NetCore_3_Tools_Channel_Id }}

View File

@ -85,10 +85,14 @@ stages:
- task: NuGetAuthenticate@0 - task: NuGetAuthenticate@0
displayName: 'Authenticate to AzDO Feeds' 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 - task: PowerShell@2
displayName: Publish Assets displayName: Publish Assets
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
inputs: inputs:
filePath: eng\common\sdk-task.ps1 filePath: eng\common\sdk-task.ps1
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet

View File

@ -85,10 +85,14 @@ stages:
- task: NuGetAuthenticate@0 - task: NuGetAuthenticate@0
displayName: 'Authenticate to AzDO Feeds' 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 - task: PowerShell@2
displayName: Publish Assets displayName: Publish Assets
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
inputs: inputs:
filePath: eng\common\sdk-task.ps1 filePath: eng\common\sdk-task.ps1
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet

View File

@ -84,10 +84,14 @@ stages:
- task: NuGetAuthenticate@0 - task: NuGetAuthenticate@0
displayName: 'Authenticate to AzDO Feeds' 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 - task: PowerShell@2
displayName: Publish Assets displayName: Publish Assets
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
inputs: inputs:
filePath: eng\common\sdk-task.ps1 filePath: eng\common\sdk-task.ps1
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet

View File

@ -85,10 +85,14 @@ stages:
- task: NuGetAuthenticate@0 - task: NuGetAuthenticate@0
displayName: 'Authenticate to AzDO Feeds' 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 - task: PowerShell@2
displayName: Publish Assets displayName: Publish Assets
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
inputs: inputs:
filePath: eng\common\sdk-task.ps1 filePath: eng\common\sdk-task.ps1
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet

View File

@ -85,10 +85,14 @@ stages:
- task: NuGetAuthenticate@0 - task: NuGetAuthenticate@0
displayName: 'Authenticate to AzDO Feeds' 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 - task: PowerShell@2
displayName: Publish Assets displayName: Publish Assets
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
inputs: inputs:
filePath: eng\common\sdk-task.ps1 filePath: eng\common\sdk-task.ps1
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet

View File

@ -85,10 +85,14 @@ stages:
- task: NuGetAuthenticate@0 - task: NuGetAuthenticate@0
displayName: 'Authenticate to AzDO Feeds' 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 - task: PowerShell@2
displayName: Publish Assets displayName: Publish Assets
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
inputs: inputs:
filePath: eng\common\sdk-task.ps1 filePath: eng\common\sdk-task.ps1
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet

View File

@ -21,7 +21,7 @@ stages:
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
- name: IsStableBuild - name: IsStableBuild
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.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: pool:
vmImage: 'windows-2019' vmImage: 'windows-2019'
steps: steps:
@ -50,10 +50,14 @@ stages:
- task: NuGetAuthenticate@0 - task: NuGetAuthenticate@0
displayName: 'Authenticate to AzDO Feeds' 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 - task: PowerShell@2
displayName: Publish Assets displayName: Publish Assets
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
inputs: inputs:
filePath: eng\common\sdk-task.ps1 filePath: eng\common\sdk-task.ps1
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
@ -88,4 +92,4 @@ stages:
- template: ../../steps/promote-build.yml - template: ../../steps/promote-build.yml
parameters: 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-DotNetCli-Storage
- group: DotNet-MSRC-Storage - group: DotNet-MSRC-Storage
# .NET Core 3 Dev
- name: PublicDevRelease_30_Channel_Id
value: 3
# .NET Core 3.1 Dev # .NET Core 3.1 Dev
- name: PublicDevRelease_31_Channel_Id - name: PublicDevRelease_31_Channel_Id
value: 128 value: 128
@ -16,13 +12,21 @@ variables:
value: 131 value: 131
# .NET Tools - Validation # .NET Tools - Validation
- name: PublicValidationRelease_30_Channel_Id - name: NetCore_Tools_Validation_Channel_Id
value: 9 value: 9
# .NET Tools - Latest # .NET Tools - Latest
- name: NetCore_Tools_Latest_Channel_Id - name: NetCore_Tools_Latest_Channel_Id
value: 2 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 # .NET Core 3.0 Internal Servicing
- name: InternalServicing_30_Channel_Id - name: InternalServicing_30_Channel_Id
value: 184 value: 184

View File

@ -101,12 +101,6 @@ stages:
artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} 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 - template: \eng\common\templates\post-build\channels\netcore-dev-31.yml
parameters: parameters:
symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
@ -119,11 +113,22 @@ stages:
artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} 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: parameters:
artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} 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 - template: \eng\common\templates\post-build\channels\netcore-release-30.yml
parameters: parameters:
symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}

View File

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

View File

@ -36,7 +36,8 @@
--> -->
<UseLatestPackageReferences Condition=" '$(UseLatestPackageReferences)' == '' AND '$(IsServicingBuild)' != 'true' ">true</UseLatestPackageReferences> <UseLatestPackageReferences Condition=" '$(UseLatestPackageReferences)' == '' AND '$(IsServicingBuild)' != 'true' ">true</UseLatestPackageReferences>
<UseLatestPackageReferences Condition=" '$(UseLatestPackageReferences)' == '' AND '$(IsImplementationProject)' != '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> <UseLatestPackageReferences Condition=" '$(UseLatestPackageReferences)' == '' ">false</UseLatestPackageReferences>
<!-- <!--
@ -45,7 +46,7 @@
* when a project is a test or sample project * when a project is a test or sample project
We don't use project references between components in servicing builds between compontents to preserve the baseline as much as possible. We don't use project references between components in servicing builds between compontents to preserve the baseline as much as possible.
--> -->
<UseProjectReferences Condition=" '$(UseProjectReferences)' == '' AND '$(IsServicingBuild)' != 'true' ">true</UseProjectReferences> <UseProjectReferences Condition=" '$(UseProjectReferences)' == '' AND '$(IsServicingBuild)' != 'true' ">true</UseProjectReferences>
<UseProjectReferences Condition=" '$(UseProjectReferences)' == '' AND '$(IsImplementationProject)' != 'true' ">true</UseProjectReferences> <UseProjectReferences Condition=" '$(UseProjectReferences)' == '' AND '$(IsImplementationProject)' != 'true' ">true</UseProjectReferences>
<UseProjectReferences Condition=" '$(UseProjectReferences)' == '' ">false</UseProjectReferences> <UseProjectReferences Condition=" '$(UseProjectReferences)' == '' ">false</UseProjectReferences>
@ -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." /> 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>
<Target Name="_WarnAboutRedundantRef" AfterTargets="ResolveFrameworkReferences"> <Target Name="_WarnAboutRedundantRef" AfterTargets="ResolveFrameworkReferences;ProcessFrameworkReferences">
<Warning Condition="@(FrameworkReference->WithMetadataValue('Identity', 'Microsoft.AspNetCore.App')->Count()) &gt; 1" <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." /> 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> </Target>

View File

@ -3,7 +3,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> <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> <StartWorkingDirectory>$(MSBuildThisFileDirectory)../../</StartWorkingDirectory>
</PropertyGroup> </PropertyGroup>

View File

@ -12,14 +12,14 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <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" /> <PackageReference Include="Microsoft.Extensions.DependencyModel" Version="2.1.0" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'"> <ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'">
<PackageReference Include="Microsoft.Build.Framework" Version="15.8.166" /> <PackageReference Include="Microsoft.Build.Framework" Version="16.3.0" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="15.8.166" /> <PackageReference Include="Microsoft.Build.Tasks.Core" Version="16.3.0" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.8.166" /> <PackageReference Include="Microsoft.Build.Utilities.Core" Version="16.3.0" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net472'"> <ItemGroup Condition="'$(TargetFramework)' == 'net472'">

View File

@ -25,7 +25,7 @@
}, },
"msbuild-sdks": { "msbuild-sdks": {
"Yarn.MSBuild": "1.15.2", "Yarn.MSBuild": "1.15.2",
"Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19462.4", "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19510.3",
"Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19462.4" "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> <ItemGroup>
<NuspecProperty Include="OutputBinary=$(OutputPath)$(AssemblyName).dll" /> <NuspecProperty Include="OutputBinary=$(OutputPath)$(AssemblyName).dll" />
<NuspecProperty Include="OutputSymbol=$(OutputPath)$(AssemblyName).pdb" /> <NuspecProperty Include="OutputSymbol=$(OutputPath)$(AssemblyName).pdb" />
<NuspecProperty Include="PackageIcon=$(PackageIconFullPath)" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -23,6 +23,14 @@
<Reference Include="System.Buffers" /> <Reference Include="System.Buffers" />
</ItemGroup> </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"> <Target Name="_GetNuspecDependencyPackageVersions">
<MSBuild Targets="_GetPackageVersionInfo" <MSBuild Targets="_GetPackageVersionInfo"
BuildInParallel="$(BuildInParallel)" BuildInParallel="$(BuildInParallel)"
@ -47,6 +55,7 @@
<NuspecProperty Condition="'$(DotNetBuildFromSource)' != 'true'" Include="systemComponentModelAnnotationsPackageVersion=$(SystemComponentModelAnnotationsPackageVersion)" /> <NuspecProperty Condition="'$(DotNetBuildFromSource)' != 'true'" Include="systemComponentModelAnnotationsPackageVersion=$(SystemComponentModelAnnotationsPackageVersion)" />
<NuspecProperty Include="AssemblyName=$(AssemblyName)" /> <NuspecProperty Include="AssemblyName=$(AssemblyName)" />
<NuspecProperty Include="OutputPath=$(OutputPath)" /> <NuspecProperty Include="OutputPath=$(OutputPath)" />
<NuspecProperty Include="PackageIcon=$(PackageIconFullPath)" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

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

View File

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

View File

@ -13,8 +13,16 @@
<link href="css/site.css" rel="stylesheet" /> <link href="css/site.css" rel="stylesheet" />
</head> </head>
<body> <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> </body>
</html> </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> <a class="navbar-brand" href="">BlazorServerApp</a>
<button class="navbar-toggler" @onclick="ToggleNavMenu"> <button class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>

View File

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

View File

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

View File

@ -101,7 +101,7 @@ export function discoverComponents(document: Document): ComponentDescriptor[] {
discoveredComponents.push(entry); 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 BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { }
protected override void OnParametersSet() { } 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() { } protected InputBase() { }
[Microsoft.AspNetCore.Components.ParameterAttribute(CaptureUnmatchedValues=true)] [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 { } } public Microsoft.AspNetCore.Components.EventCallback<TValue> ValueChanged { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
[Microsoft.AspNetCore.Components.ParameterAttribute] [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 { } } 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; } protected virtual string FormatValueAsString(TValue value) { throw null; }
public override System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) { 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); protected abstract bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage);
} }
public partial class InputCheckbox : Microsoft.AspNetCore.Components.Forms.InputBase<bool> 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 BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { }
protected override void OnParametersSet() { } 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() { } protected InputBase() { }
[Microsoft.AspNetCore.Components.ParameterAttribute(CaptureUnmatchedValues=true)] [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 { } } public Microsoft.AspNetCore.Components.EventCallback<TValue> ValueChanged { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
[Microsoft.AspNetCore.Components.ParameterAttribute] [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 { } } 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; } protected virtual string FormatValueAsString(TValue value) { throw null; }
public override System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) { 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); protected abstract bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage);
} }
public partial class InputCheckbox : Microsoft.AspNetCore.Components.Forms.InputBase<bool> 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 /// integrates with an <see cref="Forms.EditContext"/>, which must be supplied
/// as a cascading parameter. /// as a cascading parameter.
/// </summary> /// </summary>
public abstract class InputBase<TValue> : ComponentBase public abstract class InputBase<TValue> : ComponentBase, IDisposable
{ {
private readonly EventHandler<ValidationStateChangedEventArgs> _validationStateChangedHandler;
private bool _previousParsingAttemptFailed; private bool _previousParsingAttemptFailed;
private ValidationMessageStore _parsingValidationMessages; private ValidationMessageStore _parsingValidationMessages;
private Type _nullableUnderlyingType; private Type _nullableUnderlyingType;
@ -122,7 +123,15 @@ namespace Microsoft.AspNetCore.Components.Forms
} }
/// <summary> /// <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> /// </summary>
/// <param name="value">The value to format.</param> /// <param name="value">The value to format.</param>
/// <returns>A string representation of the value.</returns> /// <returns>A string representation of the value.</returns>
@ -193,6 +202,8 @@ namespace Microsoft.AspNetCore.Components.Forms
EditContext = CascadedEditContext; EditContext = CascadedEditContext;
FieldIdentifier = FieldIdentifier.Create(ValueExpression); FieldIdentifier = FieldIdentifier.Create(ValueExpression);
_nullableUnderlyingType = Nullable.GetUnderlyingType(typeof(TValue)); _nullableUnderlyingType = Nullable.GetUnderlyingType(typeof(TValue));
EditContext.OnValidationStateChanged += _validationStateChangedHandler;
} }
else if (CascadedEditContext != EditContext) else if (CascadedEditContext != EditContext)
{ {
@ -208,5 +219,19 @@ namespace Microsoft.AspNetCore.Components.Forms
// For derived components, retain the usual lifecycle with OnInit/OnParametersSet/etc. // For derived components, retain the usual lifecycle with OnInit/OnParametersSet/etc.
return base.SetParametersAsync(ParameterView.Empty); 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; var prefixLength = prefix.Length;
if (value.Length > prefixLength) 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 // Only match when there's a separator character either at the end of the
// prefix or right after it. // prefix or right after it.

View File

@ -294,7 +294,7 @@ namespace Microsoft.AspNetCore.Components.Forms
rootComponent.EditContext.OnValidationStateChanged += (sender, eventArgs) => { numValidationStateChanges++; }; rootComponent.EditContext.OnValidationStateChanged += (sender, eventArgs) => { numValidationStateChanges++; };
// Act // Act
inputComponent.CurrentValueAsString = "1991/11/20"; await inputComponent.SetCurrentValueAsStringAsync("1991/11/20");
// Assert // Assert
var receivedParsedValue = valueChangedArgs.Single(); var receivedParsedValue = valueChangedArgs.Single();
@ -324,14 +324,14 @@ namespace Microsoft.AspNetCore.Components.Forms
rootComponent.EditContext.OnValidationStateChanged += (sender, eventArgs) => { numValidationStateChanges++; }; rootComponent.EditContext.OnValidationStateChanged += (sender, eventArgs) => { numValidationStateChanges++; };
// Act/Assert 1: Transition to invalid // Act/Assert 1: Transition to invalid
inputComponent.CurrentValueAsString = "1991/11/40"; await inputComponent.SetCurrentValueAsStringAsync("1991/11/40");
Assert.Empty(valueChangedArgs); Assert.Empty(valueChangedArgs);
Assert.True(rootComponent.EditContext.IsModified(fieldIdentifier)); Assert.True(rootComponent.EditContext.IsModified(fieldIdentifier));
Assert.Equal(new[] { "Bad date value" }, rootComponent.EditContext.GetValidationMessages(fieldIdentifier)); Assert.Equal(new[] { "Bad date value" }, rootComponent.EditContext.GetValidationMessages(fieldIdentifier));
Assert.Equal(1, numValidationStateChanges); Assert.Equal(1, numValidationStateChanges);
// Act/Assert 2: Transition to valid // Act/Assert 2: Transition to valid
inputComponent.CurrentValueAsString = "1991/11/20"; await inputComponent.SetCurrentValueAsStringAsync("1991/11/20");
var receivedParsedValue = valueChangedArgs.Single(); var receivedParsedValue = valueChangedArgs.Single();
Assert.Equal(1991, receivedParsedValue.Year); Assert.Equal(1991, receivedParsedValue.Year);
Assert.Equal(11, receivedParsedValue.Month); Assert.Equal(11, receivedParsedValue.Month);
@ -341,6 +341,65 @@ namespace Microsoft.AspNetCore.Components.Forms
Assert.Equal(2, numValidationStateChanges); 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) private static TComponent FindComponent<TComponent>(CapturedBatch batch)
=> batch.ReferenceFrames => batch.ReferenceFrames
.Where(f => f.FrameType == RenderTreeFrameType.Component) .Where(f => f.FrameType == RenderTreeFrameType.Component)
@ -376,7 +435,6 @@ namespace Microsoft.AspNetCore.Components.Forms
public new string CurrentValueAsString public new string CurrentValueAsString
{ {
get => base.CurrentValueAsString; get => base.CurrentValueAsString;
set { base.CurrentValueAsString = value; }
} }
public new IReadOnlyDictionary<string, object> AdditionalAttributes => base.AdditionalAttributes; public new IReadOnlyDictionary<string, object> AdditionalAttributes => base.AdditionalAttributes;
@ -391,6 +449,15 @@ namespace Microsoft.AspNetCore.Components.Forms
{ {
throw new NotImplementedException(); 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> class TestDateInputComponent : TestInputComponent<DateTime>

View File

@ -16,13 +16,13 @@ using Xunit.Abstractions;
namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
{ {
public class MultipleComponentsTest : ServerTestBase<BasicTestAppServerSiteFixture<PrerenderedStartup>> public class MultipleComponentsTest : ServerTestBase<BasicTestAppServerSiteFixture<MultipleComponents>>
{ {
private const string MarkerPattern = ".*?<!--Blazor:(.*?)-->.*?"; private const string MarkerPattern = ".*?<!--Blazor:(.*?)-->.*?";
public MultipleComponentsTest( public MultipleComponentsTest(
BrowserFixture browserFixture, BrowserFixture browserFixture,
BasicTestAppServerSiteFixture<PrerenderedStartup> serverFixture, BasicTestAppServerSiteFixture<MultipleComponents> serverFixture,
ITestOutputHelper output) ITestOutputHelper output)
: base(browserFixture, serverFixture, output) : base(browserFixture, serverFixture, output)
{ {
@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
[Fact] [Fact]
public void DoesNotStartMultipleConnections() public void DoesNotStartMultipleConnections()
{ {
Navigate("/prerendered/multiple-components"); Navigate("/multiple-components");
BeginInteractivity(); BeginInteractivity();
Browser.Exists(By.CssSelector("h3.interactive")); Browser.Exists(By.CssSelector("h3.interactive"));
@ -60,17 +60,18 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
}); });
} }
[Fact] [Fact]
public void CanRenderMultipleRootComponents() public void CanRenderMultipleRootComponents()
{ {
Navigate("/prerendered/multiple-components"); Navigate("/multiple-components");
var greets = Browser.FindElements(By.CssSelector(".greet-wrapper .greet")).Select(e => e.Text).ToArray(); 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 John");
Assert.Single(greets, "Hello Abraham"); 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 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 content = Browser.FindElement(By.Id("test-container")).GetAttribute("innerHTML");
var markers = ReadMarkers(content); var markers = ReadMarkers(content);
@ -86,7 +87,11 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
false, false,
true, true,
false, false,
true true,
false,
true,
false,
true,
}; };
Assert.Equal(expectedComponentSequence, componentSequence); Assert.Equal(expectedComponentSequence, componentSequence);
@ -96,6 +101,8 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
Browser.Exists(By.CssSelector("h3.interactive")); Browser.Exists(By.CssSelector("h3.interactive"));
var updatedGreets = Browser.FindElements(By.CssSelector(".greet-wrapper .greet")).Select(e => e.Text).ToArray(); 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(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 Albert", g)));
Assert.Single(updatedGreets.Where(g => string.Equals("Hello Abraham", 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); 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) private Func<string[]> CreateValidationMessagesAccessor(IWebElement appElement)
{ {
return () => appElement.FindElements(By.ClassName("validation-message")) return () => appElement.FindElements(By.ClassName("validation-message"))

View File

@ -1,7 +1,7 @@
@using System.ComponentModel.DataAnnotations @using System.ComponentModel.DataAnnotations
@using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Forms
<EditForm Model="@person" OnValidSubmit="@HandleValidSubmit"> <EditForm EditContext="@editContext" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator /> <DataAnnotationsValidator />
<p class="name"> <p class="name">
@ -42,6 +42,10 @@
<p class="is-evil"> <p class="is-evil">
Is evil: <InputCheckbox @bind-Value="person.IsEvil" /> Is evil: <InputCheckbox @bind-Value="person.IsEvil" />
</p> </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> <button type="submit">Submit</button>
@ -52,6 +56,14 @@
@code { @code {
Person person = new Person(); 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 // Usually this would be in a different file
class Person class Person
@ -83,6 +95,8 @@
[Required, EnumDataType(typeof(TicketClass))] [Required, EnumDataType(typeof(TicketClass))]
public TicketClass TicketClass { get; set; } public TicketClass TicketClass { get; set; }
public string Username { get; set; }
} }
enum TicketClass { Economy, Premium, First } enum TicketClass { Economy, Premium, First }
@ -93,4 +107,22 @@
{ {
submissionLog.Add("OnValidSubmit"); 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/Default.html">With extension</NavLink></li>
<li><NavLink href="/subdir/Other">Other</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="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/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">With parameters</NavLink></li>
<li><NavLink href="/subdir/WithParameters/Name/Abc/LastName/McDef">With more 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" @page "/multiple-components"
@using BasicTestApp.MultipleComponents; @using BasicTestApp.MultipleComponents;
<!DOCTYPE html>
<html> @{
<head> Layout = "./MultipleComponentsLayout.cshtml";
<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.
*@ @(await Html.RenderComponentAsync<GreeterComponent>(RenderMode.ServerPrerendered))
</head> @(await Html.RenderComponentAsync<GreeterComponent>(RenderMode.Server))
<body> <component type="typeof(GreeterComponent)" render-mode="Static" param-name='"John"' />
<div id="test-container"> <component type="typeof(GreeterComponent)" render-mode="Server" />
@(await Html.RenderComponentAsync<GreeterComponent>(RenderMode.ServerPrerendered)) <div id="container">
@(await Html.RenderComponentAsync<GreeterComponent>(RenderMode.Server)) <p>Some content before</p>
<component type="typeof(GreeterComponent)" render-mode="Static" param-name='"John"' /> <component type="typeof(GreeterComponent)" render-mode="Server" />
<component type="typeof(GreeterComponent)" render-mode="Server"/> <p>Some content between</p>
<div id="container"> <component type="typeof(GreeterComponent)" render-mode="ServerPrerendered" />
<p>Some content before</p> <p>Some content after</p>
<component type="typeof(GreeterComponent)" render-mode="Server"/> <div id="nested-an-extra-level">
<p>Some content between</p> <p>Some content before</p>
<component type="typeof(GreeterComponent)" render-mode="ServerPrerendered"/> <component type="typeof(GreeterComponent)" render-mode="Server" />
<p>Some content after</p> <component type="typeof(GreeterComponent)" render-mode="ServerPrerendered" />
<div id="nested-an-extra-level"> <p>Some content after</p>
<p>Some content before</p>
<component type="typeof(GreeterComponent)" render-mode="Server"/>
<component type="typeof(GreeterComponent)" render-mode="ServerPrerendered"/>
<p>Some content after</p>
</div>
</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> </div>
</div>
@* <div id="container">
So that E2E tests can make assertions about both the prerendered and <component type="typeof(GreeterComponent)" render-mode="Server" param-name='"Albert"' />
interactive states, we only load the .js file when told to. <component type="typeof(GreeterComponent)" render-mode="ServerPrerendered" param-name='"Abraham"' />
*@ </div>
<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

@ -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.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features; using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -28,6 +23,7 @@ namespace TestServer
["Server authentication"] = (BuildWebHost<ServerAuthenticationStartup>(CreateAdditionalArgs(args)), "/subdir"), ["Server authentication"] = (BuildWebHost<ServerAuthenticationStartup>(CreateAdditionalArgs(args)), "/subdir"),
["CORS (WASM)"] = (BuildWebHost<CorsStartup>(CreateAdditionalArgs(args)), "/subdir"), ["CORS (WASM)"] = (BuildWebHost<CorsStartup>(CreateAdditionalArgs(args)), "/subdir"),
["Prerendering (Server-side)"] = (BuildWebHost<PrerenderedStartup>(CreateAdditionalArgs(args)), "/prerendered"), ["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"), ["Globalization + Localization (Server-side)"] = (BuildWebHost<InternationalizationStartup>(CreateAdditionalArgs(args)), "/subdir"),
["Server-side blazor"] = (BuildWebHost<ServerStartup>(CreateAdditionalArgs(args)), "/subdir"), ["Server-side blazor"] = (BuildWebHost<ServerStartup>(CreateAdditionalArgs(args)), "/subdir"),
["Hosted client-side blazor"] = (BuildWebHost<ClientStartup>(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 --> <!-- Reference implementation assemblies in addition to ref assemblies to get xml docs -->
<ReferenceImplementationAssemblies>true</ReferenceImplementationAssemblies> <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 --> <!-- Platform manifest data -->
<FrameworkListFileName>FrameworkList.xml</FrameworkListFileName> <FrameworkListFileName>FrameworkList.xml</FrameworkListFileName>
<FrameworkListOutputPath>$(ArtifactsObjDir)$(FrameworkListFileName)</FrameworkListOutputPath> <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> </PropertyGroup>
<ItemGroup> <ItemGroup>
@ -80,7 +87,7 @@ This package is an internal implementation of the .NET Core SDK and is not meant
</BuildDependsOn> </BuildDependsOn>
<!-- No-op when in source build --> <!-- No-op when in source build -->
<BuildDependsOn Condition="'$(IsTargetingPackBuilding)' != 'false' and '$(DotNetBuildFromSource)' == 'true'"/> <BuildDependsOn Condition="'$(IsTargetingPackBuilding)' == 'false'"/>
</PropertyGroup> </PropertyGroup>
<!-- Override the default MSBuild targets so that nothing is returned from the project since it represents a collection of assemblies. --> <!-- 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. --> <!-- This target finds the reference assemblies. -->
<Target Name="_ResolveTargetingPackContent" <Target Name="_ResolveTargetingPackContent"
Returns="@(AspNetCoreReferenceAssemblyPath)"
BeforeTargets="_GetPackageFiles" BeforeTargets="_GetPackageFiles"
DependsOnTargets="ResolveReferences;FindReferenceAssembliesForReferences"> DependsOnTargets="ResolveReferences;FindReferenceAssembliesForReferences">
<ItemGroup> <ItemGroup>
@ -111,6 +119,7 @@ This package is an internal implementation of the .NET Core SDK and is not meant
Exclude=" Exclude="
@(_SelectedExtensionsRefAssemblies); @(_SelectedExtensionsRefAssemblies);
@(ReferencePathWithRefAssemblies->WithMetadataValue('NuGetPackageId', 'Microsoft.NETCore.App.Ref')); @(ReferencePathWithRefAssemblies->WithMetadataValue('NuGetPackageId', 'Microsoft.NETCore.App.Ref'));
@(ReferencePathWithRefAssemblies->WithMetadataValue('IsReferenceAssembly', 'false'));
@(ReferencePathWithRefAssemblies->WithMetadataValue('ReferenceGrouping', 'Microsoft.NETCore.App'));" /> @(ReferencePathWithRefAssemblies->WithMetadataValue('ReferenceGrouping', 'Microsoft.NETCore.App'));" />
<AspNetCoreReferenceAssemblyPath <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="@(_ResolvedProjectReferencePaths->WithMetadataValue('IsReferenceAssembly', 'false')->'%(RootDir)%(Directory)%(FileName).xml')" />
<AspNetCoreReferenceDocXml Include="@(_SelectedExtensionsRefAssemblies->'$(MicrosoftInternalExtensionsRefsPath)%(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="@(AspNetCoreReferenceAssemblyPath)" PackagePath="$(RefAssemblyPackagePath)" />
<RefPackContent Include="@(AspNetCoreReferenceDocXml)" PackagePath="$(RefAssemblyPackagePath)" /> <RefPackContent Include="@(AspNetCoreReferenceDocXml)" PackagePath="$(RefAssemblyPackagePath)" />
<RefPackContent Include="$(TargetDir)$(PackageConflictManifestFileName)" PackagePath="$(ManifestsPackagePath)" /> <RefPackContent Include="$(TargetDir)$(PackageConflictManifestFileName)" PackagePath="$(ManifestsPackagePath)" />
<RefPackContent Include="$(PlatformManifestOutputPath)" PackagePath="$(ManifestsPackagePath)" /> <RefPackContent Include="$(ReferencePlatformManifestOutputPath)" PackagePath="$(ManifestsPackagePath)" />
</ItemGroup> </ItemGroup>
</Target> </Target>
@ -130,9 +151,10 @@ This package is an internal implementation of the .NET Core SDK and is not meant
DependsOnTargets="ResolveReferences" DependsOnTargets="ResolveReferences"
Inputs="$(MSBuildAllProjects)" Inputs="$(MSBuildAllProjects)"
Outputs="$(TargetDir)$(PackageConflictManifestFileName)"> Outputs="$(TargetDir)$(PackageConflictManifestFileName)">
<ItemGroup> <ItemGroup>
<_AspNetCoreAppPackageOverrides Include="@(ReferencePath->'%(NuGetPackageId)|%(NuGetPackageVersion)')" Condition=" '%(ReferencePath.NuGetPackageId)' != 'Microsoft.NETCore.App' AND '%(ReferencePath.NuGetSourceType)' == 'Package' " /> <_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> </ItemGroup>
<WriteLinesToFile <WriteLinesToFile

View File

@ -53,6 +53,13 @@
</ItemGroup> </ItemGroup>
<Target Name="GenerateTestData" BeforeTargets="GetAssemblyAttributes" DependsOnTargets="InitializeSourceControlInformation"> <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. --> <!-- 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" <MSBuild Projects="$(RepoRoot)src\Framework\src\Microsoft.AspNetCore.App.Runtime.csproj"
Targets="_GetPackageVersionInfo" Targets="_GetPackageVersionInfo"
@ -68,6 +75,11 @@
</MSBuild> </MSBuild>
<ItemGroup> <ItemGroup>
<AssemblyAttribute Include="Microsoft.AspNetCore.TestData">
<_Parameter1>TargetingPackDependencies</_Parameter1>
<_Parameter2>@(_TargetingPackDependencies)</_Parameter2>
</AssemblyAttribute>
<AssemblyAttribute Include="Microsoft.AspNetCore.TestData"> <AssemblyAttribute Include="Microsoft.AspNetCore.TestData">
<_Parameter1>RepositoryCommit</_Parameter1> <_Parameter1>RepositoryCommit</_Parameter1>
<_Parameter2>$(SourceRevisionId)</_Parameter2> <_Parameter2>$(SourceRevisionId)</_Parameter2>

View File

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

View File

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

View File

@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Hosting.StaticWebAssets
} }
else else
{ {
return InnerProvider.GetDirectoryContents(physicalPath); return InnerProvider.GetDirectoryContents(physicalPath.Value);
} }
} }
@ -59,7 +59,7 @@ namespace Microsoft.AspNetCore.Hosting.StaticWebAssets
} }
else 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\TestEventListener.cs" />
<Compile Include="$(SharedSourceRoot)EventSource.Testing\TestCounterListener.cs" /> <Compile Include="$(SharedSourceRoot)EventSource.Testing\TestCounterListener.cs" />
<Content Include="testroot\**\*" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" /> <Content Include="testroot\**\*" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" />
<None Remove="testroot\wwwroot\Static Web Assets.txt" />
<Content Include="Microsoft.AspNetCore.Hosting.StaticWebAssets.xml" CopyToOutputDirectory="PreserveNewest" /> <Content Include="Microsoft.AspNetCore.Hosting.StaticWebAssets.xml" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup> </ItemGroup>

View File

@ -37,6 +37,17 @@ namespace Microsoft.AspNetCore.Hosting.StaticWebAssets
Assert.Equal("/_content", provider.BasePath); 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] [Fact]
public void GetFileInfo_DoesNotMatch_IncompletePrefixSegments() 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> </PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'"> <ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'">
<Compile Include="Microsoft.AspNetCore.Routing.Abstractions.netcoreapp.cs" /> <Compile Include="Microsoft.AspNetCore.Routing.Abstractions.netcoreapp.cs" />
<Compile Include="Microsoft.AspNetCore.Routing.Abstractions.Manual.cs" />
<Reference Include="Microsoft.AspNetCore.Http.Abstractions" /> <Reference Include="Microsoft.AspNetCore.Http.Abstractions" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -23,7 +23,7 @@
<Target Name="Build" DependsOnTargets="DebBuild" /> <Target Name="Build" DependsOnTargets="DebBuild" />
<Target Name="Pack" /> <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 --> <!-- 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> <PropertyGroup>
<DebianConfigProperties> <DebianConfigProperties>

View File

@ -32,7 +32,7 @@
<Target Name="Build" DependsOnTargets="RpmBuild" /> <Target Name="Build" DependsOnTargets="RpmBuild" />
<Target Name="Pack" /> <Target Name="Pack" />
<Target Name="RpmBuild" DependsOnTargets="$(RpmBuildDependsOn)"> <Target Name="RpmBuild" DependsOnTargets="$(RpmBuildDependsOn)" Condition="'$(IsTargetingPackBuilding)' != 'false'">
<!-- Create layout: Create changelog --> <!-- Create layout: Create changelog -->
<PropertyGroup> <PropertyGroup>
<ChangeLogProps>DATE=$([System.DateTime]::UtcNow.ToString(ddd MMM dd yyyy))</ChangeLogProps> <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]$PackageVersion,
[Parameter(Mandatory=$true)][string]$RepoRoot, [Parameter(Mandatory=$true)][string]$RepoRoot,
[Parameter(Mandatory=$true)][string]$MajorVersion, [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" $NuGetDir = Join-Path $RepoRoot "artifacts\Tools\nuget\$Name\$Architecture"
@ -24,8 +25,8 @@ if (-not (Test-Path $NuGetDir)) {
if (-not (Test-Path $NuGetExe)) { if (-not (Test-Path $NuGetExe)) {
# Using 3.5.0 to workaround https://github.com/NuGet/Home/issues/5016 # Using 3.5.0 to workaround https://github.com/NuGet/Home/issues/5016
Write-Output "Downloading nuget.exe to $NuGetExe" 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 Exit $LastExitCode

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -823,6 +823,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
public TooManyModelErrorsException(string message) { } 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 partial class ValueProviderFactoryContext
{ {
public ValueProviderFactoryContext(Microsoft.AspNetCore.Mvc.ActionContext context) { } public ValueProviderFactoryContext(Microsoft.AspNetCore.Mvc.ActionContext context) { }

View File

@ -203,6 +203,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
throw new ArgumentNullException(nameof(exception)); 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) if (ErrorCount >= MaxAllowedErrors - 1)
{ {
EnsureMaxErrorsReachedRecorded(); EnsureMaxErrorsReachedRecorded();
@ -311,9 +318,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
return TryAddModelError(key, errorMessage); 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); 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() public void TryAddModelException_AddsErrorMessage_ForInputFormatterException()
{ {
// Arrange // Arrange
var expectedMessage = "This is an InputFormatterException";
var dictionary = new ModelStateDictionary(); var dictionary = new ModelStateDictionary();
var exception = new InputFormatterException("This is an InputFormatterException."); var exception = new InputFormatterException(expectedMessage);
// Act // Act
dictionary.TryAddModelException("key", exception); dictionary.TryAddModelException("key", exception);
@ -1217,7 +1218,25 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var entry = Assert.Single(dictionary); var entry = Assert.Single(dictionary);
Assert.Equal("key", entry.Key); Assert.Equal("key", entry.Key);
var error = Assert.Single(entry.Value.Errors); 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] [Fact]
@ -1227,9 +1246,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var expectedMessage = "This is an InputFormatterException"; var expectedMessage = "This is an InputFormatterException";
var dictionary = new ModelStateDictionary(); var dictionary = new ModelStateDictionary();
var bindingMetadataProvider = new DefaultBindingMetadataProvider(); var provider = new EmptyModelMetadataProvider();
var compositeProvider = new DefaultCompositeMetadataDetailsProvider(new[] { bindingMetadataProvider });
var provider = new DefaultModelMetadataProvider(compositeProvider, new OptionsAccessor());
var metadata = provider.GetMetadataForType(typeof(int)); var metadata = provider.GetMetadataForType(typeof(int));
// Act // Act
@ -1242,6 +1259,26 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
Assert.Equal(expectedMessage, error.ErrorMessage); 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] [Fact]
public void ModelStateDictionary_ClearEntriesThatMatchWithKey_NonEmptyKey() public void ModelStateDictionary_ClearEntriesThatMatchWithKey_NonEmptyKey()
{ {

View File

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

View File

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

View File

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

View File

@ -2,10 +2,12 @@
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd"> <package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata> <metadata>
$CommonMetadataElements$ $CommonMetadataElements$
<icon>packageIcon.png</icon>
</metadata> </metadata>
<files> <files>
<file src="$OutputBinary$" target="analyzers\dotnet\cs\" /> <file src="$OutputBinary$" target="analyzers\dotnet\cs\" />
<file src="$OutputSymbol$" target="analyzers\dotnet\cs\" /> <file src="$OutputSymbol$" target="analyzers\dotnet\cs\" />
<file src="$PackageIcon$" target="" />
</files> </files>
</package> </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> </PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'"> <ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'">
<Compile Include="Microsoft.AspNetCore.Mvc.ApiExplorer.netcoreapp.cs" /> <Compile Include="Microsoft.AspNetCore.Mvc.ApiExplorer.netcoreapp.cs" />
<Compile Include="Microsoft.AspNetCore.Mvc.ApiExplorer.Manual.cs" />
<Reference Include="Microsoft.AspNetCore.Mvc.Core" /> <Reference Include="Microsoft.AspNetCore.Mvc.Core" />
</ItemGroup> </ItemGroup>
</Project> </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> </PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'"> <ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'">
<Compile Include="Microsoft.AspNetCore.Mvc.Core.netcoreapp.cs" /> <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.Mvc.Abstractions" />
<Reference Include="Microsoft.AspNetCore.Authentication.Core" /> <Reference Include="Microsoft.AspNetCore.Authentication.Core" />
<Reference Include="Microsoft.AspNetCore.Authorization.Policy" /> <Reference Include="Microsoft.AspNetCore.Authorization.Policy" />

View File

@ -137,6 +137,11 @@ namespace Microsoft.AspNetCore.Mvc
public ApiConventionTypeAttribute(System.Type conventionType) { } public ApiConventionTypeAttribute(System.Type conventionType) { }
public System.Type ConventionType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } 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)] [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 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 /// Represents data used to build an <c>ApiDescription</c>, stored as part of the
/// <see cref="Abstractions.ActionDescriptor.Properties"/>. /// <see cref="Abstractions.ActionDescriptor.Properties"/>.
/// </summary> /// </summary>
internal class ApiDescriptionActionData public class ApiDescriptionActionData
{ {
/// <summary> /// <summary>
/// The <c>ApiDescription.GroupName</c> of <c>ApiDescription</c> objects for the associated /// 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)); 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); return await TryUpdateModelAsync(model, prefix, valueProvider);
} }
@ -2550,7 +2555,12 @@ namespace Microsoft.AspNetCore.Mvc
throw new ArgumentNullException(nameof(includeExpressions)); 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( return await ModelBindingHelper.TryUpdateModelAsync(
model, model,
prefix, prefix,
@ -2589,7 +2599,12 @@ namespace Microsoft.AspNetCore.Mvc
throw new ArgumentNullException(nameof(propertyFilter)); 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( return await ModelBindingHelper.TryUpdateModelAsync(
model, model,
prefix, prefix,
@ -2717,7 +2732,12 @@ namespace Microsoft.AspNetCore.Mvc
throw new ArgumentNullException(nameof(modelType)); 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( return await ModelBindingHelper.TryUpdateModelAsync(
model, model,
modelType, modelType,

View File

@ -59,7 +59,12 @@ namespace Microsoft.AspNetCore.Mvc.Controllers
async Task Bind(ControllerContext controllerContext, object controller, Dictionary<string, object> arguments) 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; var parameters = actionDescriptor.Parameters;
for (var i = 0; i < parameters.Count; i++) for (var i = 0; i < parameters.Count; i++)

View File

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

View File

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

View File

@ -80,6 +80,22 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
return new CompositeValueProvider(valueProviderFactoryContext.ValueProviders); 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 /> /// <inheritdoc />
public virtual bool ContainsPrefix(string prefix) 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Core;
namespace Microsoft.AspNetCore.Mvc.ModelBinding namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
@ -32,10 +34,20 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
private static async Task AddValueProviderAsync(ValueProviderFactoryContext context, HttpRequest request) private static async Task AddValueProviderAsync(ValueProviderFactoryContext context, HttpRequest request)
{ {
var formCollection = await request.ReadFormAsync(); IFormCollection form;
if (formCollection.Files.Count > 0)
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); context.ValueProviders.Add(valueProvider);
} }
} }

View File

@ -3,7 +3,10 @@
using System; using System;
using System.Globalization; using System.Globalization;
using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Core;
namespace Microsoft.AspNetCore.Mvc.ModelBinding namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
@ -33,9 +36,20 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
private static async Task AddValueProviderAsync(ValueProviderFactoryContext context) private static async Task AddValueProviderAsync(ValueProviderFactoryContext context)
{ {
var request = context.ActionContext.HttpContext.Request; 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( var valueProvider = new FormValueProvider(
BindingSource.Form, BindingSource.Form,
await request.ReadFormAsync(), form,
CultureInfo.CurrentCulture); CultureInfo.CurrentCulture);
context.ValueProviders.Add(valueProvider); context.ValueProviders.Add(valueProvider);

View File

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

View File

@ -2607,6 +2607,31 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
Assert.NotEqual(0, binder.BindModelCount); 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] [Fact]
public async Task TryUpdateModel_PropertyFilterOverload_UsesPassedArguments() 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 metadataProvider = new EmptyModelMetadataProvider();
var services = new ServiceCollection(); var services = new ServiceCollection();
@ -3056,11 +3081,11 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
stringLocalizerFactory: null), stringLocalizerFactory: null),
}; };
valueProvider = valueProvider ?? new SimpleValueProvider(); valueProvider ??= new SimpleValueProvider();
var controllerContext = new ControllerContext() var controllerContext = new ControllerContext()
{ {
HttpContext = httpContext, HttpContext = httpContext,
ValueProviderFactories = new[] { new SimpleValueProviderFactory(valueProvider), }, ValueProviderFactories = new List<IValueProviderFactory> { new SimpleValueProviderFactory(valueProvider), },
}; };
var binderFactory = new Mock<IModelBinderFactory>(); var binderFactory = new Mock<IModelBinderFactory>();

View File

@ -1202,6 +1202,54 @@ namespace Microsoft.AspNetCore.Mvc.Controllers
Assert.Equal(250.0, transferInfo.Amount); 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) private static ControllerContext GetControllerContext(ControllerActionDescriptor descriptor = null)
{ {
var services = new ServiceCollection(); var services = new ServiceCollection();

View File

@ -8,7 +8,7 @@ using Xunit;
namespace Microsoft.AspNetCore.Mvc.Infrastructure namespace Microsoft.AspNetCore.Mvc.Infrastructure
{ {
public class ProblemDetailsConverterTest public class ProblemDetailsJsonConverterTest
{ {
private static JsonSerializerOptions JsonSerializerOptions => new JsonOptions().JsonSerializerOptions; 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 json = $"{{\"type\":\"{type}\",\"title\":\"{title}\",\"status\":{status},\"detail\":\"{detail}\", \"instance\":\"{instance}\",\"traceId\":\"{traceId}\"}}";
var converter = new ProblemDetailsJsonConverter(); var converter = new ProblemDetailsJsonConverter();
var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json));
reader.Read();
// Act // Act
var problemDetails = converter.Read(ref reader, typeof(ProblemDetails), JsonSerializerOptions); 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] [Fact]
public void Read_WithSomeMissingValues_Works() 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 json = $"{{\"type\":\"{type}\",\"title\":\"{title}\",\"status\":{status},\"traceId\":\"{traceId}\"}}";
var converter = new ProblemDetailsJsonConverter(); var converter = new ProblemDetailsJsonConverter();
var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json));
reader.Read();
// Act // Act
var problemDetails = converter.Read(ref reader, typeof(ProblemDetails), JsonSerializerOptions); var problemDetails = converter.Read(ref reader, typeof(ProblemDetails), JsonSerializerOptions);

View File

@ -9,7 +9,7 @@ using Xunit;
namespace Microsoft.AspNetCore.Mvc.Infrastructure namespace Microsoft.AspNetCore.Mvc.Infrastructure
{ {
public class ValidationProblemDetailsConverterTest public class ValidationProblemDetailsJsonConverterTest
{ {
private static JsonSerializerOptions JsonSerializerOptions => new JsonOptions().JsonSerializerOptions; private static JsonSerializerOptions JsonSerializerOptions => new JsonOptions().JsonSerializerOptions;
@ -27,6 +27,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
"\"errors\":{\"key0\":[\"error0\"],\"key1\":[\"error1\",\"error2\"]}}"; "\"errors\":{\"key0\":[\"error0\"],\"key1\":[\"error1\",\"error2\"]}}";
var converter = new ValidationProblemDetailsJsonConverter(); var converter = new ValidationProblemDetailsJsonConverter();
var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json));
reader.Read();
// Act // Act
var problemDetails = converter.Read(ref reader, typeof(ValidationProblemDetails), JsonSerializerOptions); var problemDetails = converter.Read(ref reader, typeof(ValidationProblemDetails), JsonSerializerOptions);
@ -65,12 +66,14 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
var title = "Not found"; var title = "Not found";
var status = 404; var status = 404;
var traceId = "|37dd3dd5-4a9619f953c40a16."; var traceId = "|37dd3dd5-4a9619f953c40a16.";
var json = $"{{\"type\":\"{type}\",\"title\":\"{title}\",\"status\":{status},\"traceId\":\"{traceId}\"}}"; var json = $"{{\"type\":\"{type}\",\"title\":\"{title}\",\"status\":{status},\"traceId\":\"{traceId}\"," +
var converter = new ProblemDetailsJsonConverter(); "\"errors\":{\"key0\":[\"error0\"],\"key1\":[\"error1\",\"error2\"]}}";
var converter = new ValidationProblemDetailsJsonConverter();
var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json));
reader.Read();
// Act // 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(type, problemDetails.Type);
Assert.Equal(title, problemDetails.Title); Assert.Equal(title, problemDetails.Title);
@ -82,6 +85,56 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
Assert.Equal("traceId", kvp.Key); Assert.Equal("traceId", kvp.Key);
Assert.Equal(traceId, kvp.Value.ToString()); 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] [Fact]

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