Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/aspnetcore.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Newton-King <james@newtonking.com>2022-04-01 02:46:25 +0300
committerGitHub <noreply@github.com>2022-04-01 02:46:25 +0300
commitdddffea59c3c8e16ce2ec43e43ae5ba5fc121943 (patch)
tree4160ad81ba9d3b391e3bffa3f55caf5b9c1be9a0
parentaca14e20a53b65d3defe3d827a1b1fa538a0c066 (diff)
parent7399df28dabaa316a37b043cf944f4433faf08ad (diff)
Merge branch 'main' into jamesnk/trimming-docsjamesnk/trimming-docs
-rw-r--r--.azure/pipelines/ci.yml15
-rw-r--r--.editorconfig4
-rw-r--r--.github/CODEOWNERS6
-rw-r--r--eng/Build.props10
-rw-r--r--eng/Publishing.props7
-rw-r--r--eng/TrimmableProjects.props4
-rw-r--r--eng/Version.Details.xml288
-rw-r--r--eng/Versions.props140
-rw-r--r--eng/helix/content/runtests.sh11
-rw-r--r--global.json8
-rw-r--r--src/Caching/SqlServer/src/MonoDatabaseOperations.cs201
-rw-r--r--src/Caching/SqlServer/src/MonoSqlParameterCollectionExtensions.cs43
-rw-r--r--src/Caching/SqlServer/src/PlatformHelper.cs19
-rw-r--r--src/Caching/SqlServer/src/SqlServerCache.cs24
-rw-r--r--src/Components/WebAssembly/Authentication.Msal/src/Interop/package.json3
-rw-r--r--src/Components/WebAssembly/Authentication.Msal/src/Interop/yarn.lock8
-rw-r--r--src/Components/WebAssembly/WebAssembly.Authentication/src/Interop/package.json3
-rw-r--r--src/Components/WebAssembly/WebAssembly.Authentication/src/Interop/yarn.lock8
-rw-r--r--src/Components/WebView/WebView/src/Services/WebViewJSRuntime.cs5
-rw-r--r--src/Hosting/Abstractions/src/Microsoft.AspNetCore.Hosting.Abstractions.csproj1
-rw-r--r--src/Hosting/Server.Abstractions/src/Microsoft.AspNetCore.Hosting.Server.Abstractions.csproj1
-rw-r--r--src/Hosting/Server.IntegrationTesting/src/Common/DeploymentResult.cs6
-rw-r--r--src/Hosting/Server.IntegrationTesting/src/Deployers/NginxDeployer.cs1
-rw-r--r--src/Hosting/Server.IntegrationTesting/src/Deployers/RemoteWindowsDeployer/RemoteWindowsDeployer.cs6
-rw-r--r--src/Hosting/Server.IntegrationTesting/src/Deployers/SelfHostDeployer.cs8
-rw-r--r--src/Hosting/TestHost/src/TestServer.cs6
-rw-r--r--src/Http/Http.Extensions/src/HeaderDictionaryTypeExtensions.cs88
-rw-r--r--src/Http/Http.Extensions/src/HttpRequestJsonExtensions.cs116
-rw-r--r--src/Http/Http.Extensions/src/HttpResponseJsonExtensions.cs132
-rw-r--r--src/Http/Http.Extensions/src/Microsoft.AspNetCore.Http.Extensions.csproj2
-rw-r--r--src/Http/Http.Extensions/src/PublicAPI.Unshipped.txt4
-rw-r--r--src/Http/Http.Extensions/src/RequestDelegateFactory.cs22
-rw-r--r--src/Http/Http.Extensions/src/RequestHeaders.cs5
-rw-r--r--src/Http/Http.Extensions/src/ResponseHeaders.cs5
-rw-r--r--src/Http/Routing.Abstractions/src/Microsoft.AspNetCore.Routing.Abstractions.csproj1
-rw-r--r--src/Http/Routing/src/Builder/RouteHandlerFilterExtensions.cs23
-rw-r--r--src/Http/Routing/test/UnitTests/Builder/RouteHandlerEndpointRouteBuilderExtensionsTest.cs11
-rw-r--r--src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj1
-rw-r--r--src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/include.wxi6
-rw-r--r--src/Installers/Windows/WindowsHostingBundle/ANCM.wxs18
-rw-r--r--src/Installers/Windows/WindowsHostingBundle/DotNetCore.wxs26
-rw-r--r--src/Installers/Windows/WindowsHostingBundle/Product.targets14
-rw-r--r--src/Installers/Windows/WindowsHostingBundle/SharedFramework.wxs26
-rw-r--r--src/Installers/Windows/WindowsHostingBundle/WindowsHostingBundle.wixproj19
-rw-r--r--src/JSInterop/Microsoft.JSInterop/src/Infrastructure/DotNetDispatcher.cs34
-rw-r--r--src/JSInterop/Microsoft.JSInterop/src/Microsoft.JSInterop.WarningSuppressions.xml10
-rw-r--r--src/JSInterop/Microsoft.JSInterop/test/Infrastructure/DotNetDispatcherTest.cs80
-rw-r--r--src/Middleware/HttpLogging/src/W3CLoggerProcessor.cs2
-rw-r--r--src/Middleware/HttpLogging/test/W3CLoggerTests.cs8
-rw-r--r--src/Middleware/HttpLogging/test/W3CLoggingMiddlewareTests.cs8
-rw-r--r--src/Mvc/Mvc.Testing/src/WebApplicationFactoryClientOptions.cs2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/dotnetcli.host.json4
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/ide.host.json6
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.cs.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.de.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.en.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.es.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.fr.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.it.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.ja.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.ko.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.pl.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.ru.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.tr.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/template.json22
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Program.Main.cs169
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Shared/NavMenu.CallsMicrosoftGraph.razor2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/dotnetcli.host.json4
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/ide.host.json4
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.cs.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.de.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.en.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.es.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.fr.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.it.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.ja.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.ko.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.pl.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.pt-BR.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.ru.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.tr.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.zh-Hans.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.zh-Hant.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/template.json25
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/Program.Main.cs69
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/Shared/NavMenu.CallsMicrosoftGraph.razor2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/wwwroot/sample-data/weather.json10
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Program.Main.cs125
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/dotnetcli.host.json4
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/ide.host.json6
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.cs.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.de.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.en.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.es.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.fr.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.it.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.ja.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.ko.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.pl.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.ru.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.tr.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/template.json22
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/Program.Main.cs14
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/dotnetcli.host.json4
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/ide.host.json8
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.cs.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.de.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.en.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.es.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.fr.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.it.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.ja.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.ko.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.pl.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.pt-BR.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.ru.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.tr.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.zh-Hans.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.zh-Hant.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/template.json22
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/Program.Main.cs25
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/dotnetcli.host.json4
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/ide.host.json5
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.cs.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.de.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.en.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.es.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.fr.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.it.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.ja.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.ko.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.pl.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.ru.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.tr.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/template.json22
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.Main.cs155
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/dotnetcli.host.json4
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/ide.host.json5
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.cs.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.de.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.en.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.es.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.fr.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.it.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.ja.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.ko.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.pl.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.ru.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.tr.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/template.json22
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.Main.cs159
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/dotnetcli.host.json4
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/ide.host.json4
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.cs.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.de.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.en.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.es.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.fr.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.it.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.ja.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.ko.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.pl.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.pt-BR.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.ru.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.tr.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.zh-Hans.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.zh-Hant.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/template.json22
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Program.Main.cs95
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/dotnetcli.host.json4
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/ide.host.json6
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.cs.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.de.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.en.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.es.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.fr.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.it.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.ja.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.ko.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.pl.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.pt-BR.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.ru.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.tr.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.zh-Hans.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.zh-Hant.json2
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/template.json22
-rw-r--r--src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/Program.Main.cs18
-rw-r--r--src/ProjectTemplates/scripts/Run-Angular-Locally.ps12
-rw-r--r--src/ProjectTemplates/scripts/Run-AngularProgramMain-Locally.ps112
-rw-r--r--src/ProjectTemplates/scripts/Run-Blazor-Locally.ps12
-rw-r--r--src/ProjectTemplates/scripts/Run-BlazorProgramMain-Locally.ps113
-rw-r--r--src/ProjectTemplates/scripts/Run-BlazorWasm-Locally.ps12
-rw-r--r--src/ProjectTemplates/scripts/Run-BlazorWasmProgramMain-Locally.ps113
-rw-r--r--src/ProjectTemplates/scripts/Run-EmptyWeb-Locally.ps12
-rw-r--r--src/ProjectTemplates/scripts/Run-EmptyWebProgramMain-Locally.ps112
-rw-r--r--src/ProjectTemplates/scripts/Run-Razor-Locally.ps12
-rw-r--r--src/ProjectTemplates/scripts/Run-RazorProgramMain-Locally.ps19
-rw-r--r--src/ProjectTemplates/scripts/Run-React-Locally.ps12
-rw-r--r--src/ProjectTemplates/scripts/Run-ReactProgramMain-Locally.ps112
-rw-r--r--src/ProjectTemplates/scripts/Run-ReactRedux-Locally.ps12
-rw-r--r--src/ProjectTemplates/scripts/Run-Starterweb-Locally.ps12
-rw-r--r--src/ProjectTemplates/scripts/Run-StarterwebProgramMain-Locally.ps112
-rw-r--r--src/ProjectTemplates/scripts/Run-WebApi-Locally.ps12
-rw-r--r--src/ProjectTemplates/scripts/Run-WebApiMinimal-Locally.ps12
-rw-r--r--src/ProjectTemplates/scripts/Run-WebApiProgamMain-Locally.ps112
-rw-r--r--src/ProjectTemplates/scripts/Run-Worker-Locally.ps12
-rw-r--r--src/ProjectTemplates/scripts/Run-WorkerProgramMain-Locally.ps112
-rw-r--r--src/ProjectTemplates/scripts/Run-gRPC-Locally.ps12
-rw-r--r--src/ProjectTemplates/scripts/Test-Template.ps14
-rw-r--r--src/ProjectTemplates/test/BlazorServerTemplateTest.cs14
-rw-r--r--src/ProjectTemplates/test/BlazorWasmTemplateTest.cs3
-rw-r--r--src/ProjectTemplates/test/EmptyWebTemplateTest.cs11
-rw-r--r--src/ProjectTemplates/test/GrpcTemplateTest.cs9
-rw-r--r--src/ProjectTemplates/test/MvcTemplateTest.cs19
-rw-r--r--src/ProjectTemplates/test/RazorPagesTemplateTest.cs23
-rw-r--r--src/ProjectTemplates/test/WebApiTemplateTest.cs22
-rw-r--r--src/ProjectTemplates/test/WorkerTemplateTest.cs9
-rw-r--r--src/Security/Authentication/Cookies/src/CookieAuthenticationEvents.cs8
-rw-r--r--src/Security/Authentication/Cookies/src/CookieAuthenticationHandler.cs2
-rw-r--r--src/Security/Authentication/Cookies/src/PublicAPI.Unshipped.txt1
-rw-r--r--src/Security/Authentication/test/CertificateTests.cs4
-rw-r--r--src/Servers/IIS/IIS/perf/Microbenchmarks/PlaintextBenchmark.cs3
-rw-r--r--src/Servers/IIS/IIS/test/Common.FunctionalTests/CompressionTests.cs1
-rw-r--r--src/Servers/IIS/IIS/test/Common.FunctionalTests/FrebTests.cs3
-rw-r--r--src/Servers/IIS/IIS/test/Common.FunctionalTests/Http2Tests.cs6
-rw-r--r--src/Servers/IIS/IIS/test/Common.FunctionalTests/Infrastructure/EventLogHelpers.cs2
-rw-r--r--src/Servers/IIS/IIS/test/Common.FunctionalTests/Infrastructure/Helpers.cs27
-rw-r--r--src/Servers/IIS/IIS/test/Common.LongTests/StartupTests.cs5
-rw-r--r--src/Servers/IIS/IIS/test/IIS.FunctionalTests/Http2TrailersResetTests.cs4
-rw-r--r--src/Servers/IIS/IIS/test/IIS.FunctionalTests/Http3Tests.cs2
-rw-r--r--src/Servers/IIS/IIS/test/IIS.Shared.FunctionalTests/StdOutRedirectionTests.cs13
-rw-r--r--src/Servers/IIS/IIS/test/IIS.Tests/Utilities/TestServer.cs3
-rw-r--r--src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs4
-rw-r--r--src/Servers/IIS/IIS/test/testassets/IIS.Common.TestLib/TestConnections.cs2
-rw-r--r--src/Servers/IIS/IIS/test/testassets/IIS.Common.TestLib/TimeoutExtensions.cs2
-rw-r--r--src/Servers/IIS/IISIntegration/test/Tests/IISMiddlewareTests.cs8
-rw-r--r--src/Servers/IIS/IntegrationTesting.IIS/src/IISDeploymentResult.cs3
-rw-r--r--src/Servers/IIS/IntegrationTesting.IIS/src/IISExpressDeployer.cs8
-rw-r--r--src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs102
-rw-r--r--src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs30
-rw-r--r--src/Servers/Kestrel/perf/Microbenchmarks/Http2/Http2FrameWriterBenchmark.cs17
-rw-r--r--src/Servers/Kestrel/shared/test/TestContextFactory.cs13
-rw-r--r--src/Servers/Kestrel/test/Interop.FunctionalTests/Http2/Http2RequestTests.cs93
-rw-r--r--src/Servers/Kestrel/test/Interop.FunctionalTests/HttpHelpers.cs2
-rw-r--r--src/Shared/HttpValidationProblemDetailsJsonConverter.cs19
-rw-r--r--src/Shared/ObjectMethodExecutor/AwaitableInfo.cs64
-rw-r--r--src/Shared/ObjectMethodExecutor/CoercedAwaitableInfo.cs6
-rw-r--r--src/Shared/ObjectMethodExecutor/ObjectMethodExecutor.cs24
-rw-r--r--src/Shared/ObjectMethodExecutor/ObjectMethodExecutorFSharpSupport.cs5
-rw-r--r--src/Shared/ParameterBindingMethodCache.cs13
-rw-r--r--src/Shared/ProblemDetailsJsonConverter.cs4
-rw-r--r--src/Shared/runtime/Http3/QPack/QPackDecoder.cs4
-rw-r--r--src/SignalR/clients/ts/FunctionalTests/package.json3
-rw-r--r--src/SignalR/clients/ts/FunctionalTests/yarn.lock8
-rw-r--r--src/SignalR/clients/ts/common/package.json3
-rw-r--r--src/SignalR/clients/ts/common/yarn.lock8
-rw-r--r--src/Tools/Tools.slnf3
m---------src/submodules/googletest0
m---------src/submodules/spa-templates0
271 files changed, 2725 insertions, 873 deletions
diff --git a/.azure/pipelines/ci.yml b/.azure/pipelines/ci.yml
index d59d36a5cf..ce8da1c3ad 100644
--- a/.azure/pipelines/ci.yml
+++ b/.azure/pipelines/ci.yml
@@ -24,6 +24,11 @@ parameters:
default: false
displayName: Skip tests?
type: boolean
+# Choose whether to enable binlogs when running pipeline manually.
+- name: produceBinlogs
+ default: false
+ displayName: Produce binlogs?
+ type: boolean
# Choose whether to test source indexing. Ignored in public builds.
# Will cause inaccessible links on https://source.dot.net/ unless commits are also available in GitHub.
- name: testSourceIndexing
@@ -86,7 +91,7 @@ variables:
- name: sourceIndexPackageSource
value: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json
- group: source-dot-net stage1 variables
-- ${{ if or(eq(variables['System.TeamProject'], 'public'), in(variables['Build.Reason'], 'PullRequest')) }}:
+- ${{ if or(eq(variables['System.TeamProject'], 'public'), in(variables['Build.Reason'], 'PullRequest'), eq(parameters.produceBinlogs, 'true')) }}:
- name: _BuildArgs
value: '/p:SkipTestBuild=true /p:PostBuildSign=$(PostBuildSign)'
- name: _PublishArgs
@@ -282,7 +287,13 @@ stages:
includeForks: true
- name: Windows_Packages
path: artifacts/packages/
-
+ - name: Windows_HostingBundle
+ path: artifacts/bin/WindowsHostingBundle
+ - name: Windows_ANCM_Msi
+ path: artifacts/bin/ANCMv2
+ - name: Windows_ANCMIISExpress_Msi
+ path: artifacts/bin/AncmIISExpressV2
+
# Build Windows ARM
- template: jobs/default-build.yml
parameters:
diff --git a/.editorconfig b/.editorconfig
index e1181f237f..06b74cd958 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -263,7 +263,7 @@ dotnet_diagnostic.IDE0161.severity = warning
dotnet_style_allow_multiple_blank_lines_experimental = false
dotnet_diagnostic.IDE2000.severity = warning
-[{eng/tools/**.cs,**/{test,testassets,samples,Samples,perf}/**.cs}]
+[{eng/tools/**.cs,**/{test,testassets,samples,Samples,perf,scripts}/**.cs}]
# CA1018: Mark attributes with AttributeUsageAttribute
dotnet_diagnostic.CA1018.severity = suggestion
# CA1507: Use nameof to express symbol names
@@ -302,6 +302,8 @@ dotnet_diagnostic.CA1845.severity = suggestion
dotnet_diagnostic.CA1846.severity = suggestion
# CA1847: Use string.Contains(char) instead of string.Contains(string) with single characters
dotnet_diagnostic.CA1847.severity = suggestion
+# CA2007: Consider calling ConfigureAwait on the awaited task
+dotnet_diagnostic.CA2007.severity = suggestion
# CA2008: Do not create tasks without passing a TaskScheduler
dotnet_diagnostic.CA2008.severity = suggestion
# CA2012: Use ValueTask correctly
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 2b811a2676..fb9da1cada 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -22,6 +22,8 @@
/src/Components/**/PublicAPI.*Shipped.txt @dotnet/aspnet-api-review @dotnet/aspnet-blazor-eng
/src/DefaultBuilder/ @tratcher @halter73
/src/DefaultBuilder/**/PublicAPI.*Shipped.txt @dotnet/aspnet-api-review @tratcher
+/src/Grpc/ @JamesNK @captainsafia
+/src/Grpc/**/PublicAPI.*Shipped.txt @dotnet/aspnet-api-review @JamesNK @captainsafia
/src/Hosting/ @tratcher @halter73
/src/Hosting/**/PublicAPI.*Shipped.txt @dotnet/aspnet-api-review @tratcher
/src/Http/ @tratcher @BrennanConroy @halter73
@@ -39,8 +41,8 @@
/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/ @dotnet/aspnet-blazor-eng
/src/Security/ @tratcher
/src/Security/**/PublicAPI.*Shipped.txt @dotnet/aspnet-api-review @tratcher
-/src/Servers/ @tratcher @halter73 @BrennanConroy
-/src/Servers/**/PublicAPI.*Shipped.txt @dotnet/aspnet-api-review @tratcher @halter73 @BrennanConroy
+/src/Servers/ @tratcher @halter73 @BrennanConroy @JamesNK
+/src/Servers/**/PublicAPI.*Shipped.txt @dotnet/aspnet-api-review @tratcher @halter73 @BrennanConroy @JamesNK
/src/Shared/runtime/ @dotnet/http
/src/Shared/test/Shared.Tests/runtime/ @dotnet/http
/src/SignalR/ @BrennanConroy @halter73
diff --git a/eng/Build.props b/eng/Build.props
index 8ca48331c8..a39342be7d 100644
--- a/eng/Build.props
+++ b/eng/Build.props
@@ -98,23 +98,17 @@
<!-- Build the SharedFramework installers -->
<ProjectToBuild Include="$(RepoRoot)src\Installers\Windows\SharedFrameworkBundle\SharedFrameworkBundle.wixproj" AdditionalProperties="Platform=x64" />
<ProjectToBuild Include="$(RepoRoot)src\Installers\Windows\SharedFrameworkBundle\SharedFrameworkBundle.wixproj" AdditionalProperties="Platform=x86" />
+ <ProjectToBuild Include="$(RepoRoot)src\Installers\Windows\SharedFrameworkBundle\SharedFrameworkBundle.wixproj" AdditionalProperties="Platform=arm64" />
<!-- Build the SharedFramework wixlib -->
<ProjectToBuild Include="$(RepoRoot)src\Installers\Windows\SharedFrameworkLib\SharedFrameworkLib.wixproj" AdditionalProperties="Platform=x64" />
<ProjectToBuild Include="$(RepoRoot)src\Installers\Windows\SharedFrameworkLib\SharedFrameworkLib.wixproj" AdditionalProperties="Platform=x86" />
+ <ProjectToBuild Include="$(RepoRoot)src\Installers\Windows\SharedFrameworkLib\SharedFrameworkLib.wixproj" AdditionalProperties="Platform=arm64" />
<!-- Windows hosting bundled -->
<ProjectToBuild Include="$(RepoRoot)src\Installers\Windows\WindowsHostingBundle\WindowsHostingBundle.wixproj" AdditionalProperties="Platform=x86" />
</ItemGroup>
- <ItemGroup Condition=" '$(BuildInstallers)' == 'true' AND '$(TargetOsName)' == 'win' AND '$(TargetArchitecture)' == 'arm64' ">
- <!-- We don't build the targeting pack installer here because it's built in the x86/x64 leg.
- Instead we only provide the ARM64 SharedFramework MSI-->
-
- <!-- Build the SharedFramework wixlib -->
- <ProjectToBuild Include="$(RepoRoot)src\Installers\Windows\SharedFrameworkLib\SharedFrameworkLib.wixproj" AdditionalProperties="Platform=arm64" />
- </ItemGroup>
-
<ItemGroup Condition="'$(BuildInstallers)' == 'true' AND ('$(TargetRuntimeIdentifier)' == 'linux-x64' OR '$(TargetRuntimeIdentifier)' == 'linux-arm64')">
<ProjectToBuild Condition=" '$(LinuxInstallerType)' == 'deb' "
Include="$(RepoRoot)src\Installers\Debian\**\*.*proj" />
diff --git a/eng/Publishing.props b/eng/Publishing.props
index a812c9e293..ef4fe67705 100644
--- a/eng/Publishing.props
+++ b/eng/Publishing.props
@@ -97,10 +97,11 @@
Condition=" '$(PublishInstallerBaseVersion)' == 'true'">
<!--
This target is defined in eng/targets/Packaging.targets and Npm.Common.targets and included in every C#, F#,
- and npm project. We use Microsoft.AspNetCore.App.Runtime.csproj because it is shipping (we need a stable
- version string to use for productVersion.txt).
+ and npm project. We use Microsoft.JSInterop.JS.npmproj because it is shipping (we need a stable
+ version string to use for productVersion.txt), and because it won't break when the SDK requires a newer
+ desktop MSBuild than exists on the build machine.
-->
- <MSBuild Projects="$(RepoRoot)src\Framework\App.Runtime\src\Microsoft.AspNetCore.App.Runtime.csproj"
+ <MSBuild Projects="$(RepoRoot)src\JSInterop\Microsoft.JSInterop.JS\src\Microsoft.JSInterop.JS.npmproj"
Properties="DisableYarnCheck=true;ExcludeFromBuild=false"
Targets="_GetPackageVersionInfo">
<Output TaskParameter="TargetOutputs" ItemName="_ResolvedProductVersionInfo" />
diff --git a/eng/TrimmableProjects.props b/eng/TrimmableProjects.props
index bbba1c4c17..f6db6bf40d 100644
--- a/eng/TrimmableProjects.props
+++ b/eng/TrimmableProjects.props
@@ -7,10 +7,14 @@
-->
<Project>
<ItemGroup>
+ <TrimmableProject Include="Microsoft.AspNetCore.Hosting.Abstractions" />
+ <TrimmableProject Include="Microsoft.AspNetCore.Hosting.Server.Abstractions" />
<TrimmableProject Include="Microsoft.Net.Http.Headers" />
<TrimmableProject Include="Microsoft.AspNetCore.Http.Abstractions" />
+ <TrimmableProject Include="Microsoft.AspNetCore.Http.Extensions" />
<TrimmableProject Include="Microsoft.AspNetCore.Http.Features" />
<TrimmableProject Include="Microsoft.AspNetCore.Metadata" />
+ <TrimmableProject Include="Microsoft.AspNetCore.Routing.Abstractions" />
<TrimmableProject Include="Microsoft.AspNetCore.WebUtilities" />
<TrimmableProject Include="Microsoft.AspNetCore.Authorization" />
<TrimmableProject Include="Microsoft.AspNetCore.Components.Authorization" />
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 14bccb3101..537cd2a378 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -9,301 +9,301 @@
-->
<Dependencies>
<ProductDependencies>
- <Dependency Name="dotnet-ef" Version="7.0.0-preview.4.22173.5">
+ <Dependency Name="dotnet-ef" Version="7.0.0-preview.4.22178.2">
<Uri>https://github.com/dotnet/efcore</Uri>
- <Sha>12bcdbdffbfbbda9226ddeea54adba7605601c37</Sha>
+ <Sha>b7fefcae719b05c51d149f458a1fbca009a3cbf8</Sha>
</Dependency>
- <Dependency Name="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.0-preview.4.22173.5">
+ <Dependency Name="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.0-preview.4.22178.2">
<Uri>https://github.com/dotnet/efcore</Uri>
- <Sha>12bcdbdffbfbbda9226ddeea54adba7605601c37</Sha>
+ <Sha>b7fefcae719b05c51d149f458a1fbca009a3cbf8</Sha>
</Dependency>
- <Dependency Name="Microsoft.EntityFrameworkCore.Relational" Version="7.0.0-preview.4.22173.5">
+ <Dependency Name="Microsoft.EntityFrameworkCore.Relational" Version="7.0.0-preview.4.22178.2">
<Uri>https://github.com/dotnet/efcore</Uri>
- <Sha>12bcdbdffbfbbda9226ddeea54adba7605601c37</Sha>
+ <Sha>b7fefcae719b05c51d149f458a1fbca009a3cbf8</Sha>
</Dependency>
- <Dependency Name="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.0-preview.4.22173.5">
+ <Dependency Name="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.0-preview.4.22178.2">
<Uri>https://github.com/dotnet/efcore</Uri>
- <Sha>12bcdbdffbfbbda9226ddeea54adba7605601c37</Sha>
+ <Sha>b7fefcae719b05c51d149f458a1fbca009a3cbf8</Sha>
</Dependency>
- <Dependency Name="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.0-preview.4.22173.5">
+ <Dependency Name="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.0-preview.4.22178.2">
<Uri>https://github.com/dotnet/efcore</Uri>
- <Sha>12bcdbdffbfbbda9226ddeea54adba7605601c37</Sha>
+ <Sha>b7fefcae719b05c51d149f458a1fbca009a3cbf8</Sha>
</Dependency>
- <Dependency Name="Microsoft.EntityFrameworkCore.Tools" Version="7.0.0-preview.4.22173.5">
+ <Dependency Name="Microsoft.EntityFrameworkCore.Tools" Version="7.0.0-preview.4.22178.2">
<Uri>https://github.com/dotnet/efcore</Uri>
- <Sha>12bcdbdffbfbbda9226ddeea54adba7605601c37</Sha>
+ <Sha>b7fefcae719b05c51d149f458a1fbca009a3cbf8</Sha>
</Dependency>
- <Dependency Name="Microsoft.EntityFrameworkCore" Version="7.0.0-preview.4.22173.5">
+ <Dependency Name="Microsoft.EntityFrameworkCore" Version="7.0.0-preview.4.22178.2">
<Uri>https://github.com/dotnet/efcore</Uri>
- <Sha>12bcdbdffbfbbda9226ddeea54adba7605601c37</Sha>
+ <Sha>b7fefcae719b05c51d149f458a1fbca009a3cbf8</Sha>
</Dependency>
- <Dependency Name="Microsoft.EntityFrameworkCore.Design" Version="7.0.0-preview.4.22173.5">
+ <Dependency Name="Microsoft.EntityFrameworkCore.Design" Version="7.0.0-preview.4.22178.2">
<Uri>https://github.com/dotnet/efcore</Uri>
- <Sha>12bcdbdffbfbbda9226ddeea54adba7605601c37</Sha>
+ <Sha>b7fefcae719b05c51d149f458a1fbca009a3cbf8</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Caching.Abstractions" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Caching.Abstractions" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Caching.Memory" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Caching.Memory" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Configuration.Binder" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Configuration.Binder" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Configuration.CommandLine" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Configuration.CommandLine" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Configuration.FileExtensions" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Configuration.FileExtensions" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Configuration.Ini" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Configuration.Ini" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Configuration.Json" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Configuration.Json" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Configuration.UserSecrets" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Configuration.UserSecrets" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Configuration.Xml" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Configuration.Xml" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Configuration" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Configuration" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.DependencyInjection" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.DependencyInjection" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.FileProviders.Abstractions" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.FileProviders.Abstractions" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.FileProviders.Composite" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.FileProviders.Composite" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.FileProviders.Physical" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.FileProviders.Physical" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.FileSystemGlobbing" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.FileSystemGlobbing" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.HostFactoryResolver.Sources" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.HostFactoryResolver.Sources" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Hosting.Abstractions" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Hosting.Abstractions" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Hosting" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Hosting" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Http" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Http" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Logging.Abstractions" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Logging.Abstractions" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Logging.Configuration" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Logging.Configuration" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Logging.Console" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Logging.Console" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Logging.Debug" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Logging.Debug" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Logging.EventSource" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Logging.EventSource" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Logging.EventLog" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Logging.EventLog" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Logging.TraceSource" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Logging.TraceSource" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Logging" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Logging" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Options.DataAnnotations" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Options.DataAnnotations" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Options" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Options" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.Primitives" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.Primitives" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Internal.Runtime.AspNetCore.Transport" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Internal.Runtime.AspNetCore.Transport" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="System.Diagnostics.DiagnosticSource" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="System.Diagnostics.DiagnosticSource" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="System.Diagnostics.EventLog" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="System.Diagnostics.EventLog" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="System.DirectoryServices.Protocols" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="System.DirectoryServices.Protocols" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="System.IO.Pipelines" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="System.IO.Pipelines" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="System.Net.Http.Json" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="System.Net.Http.Json" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="System.Net.Http.WinHttpHandler" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="System.Net.Http.WinHttpHandler" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="System.Reflection.Metadata" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="System.Reflection.Metadata" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="System.Resources.Extensions" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="System.Resources.Extensions" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="System.Security.Cryptography.Pkcs" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="System.Security.Cryptography.Pkcs" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="System.Security.Cryptography.Xml" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="System.Security.Cryptography.Xml" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="System.Security.Permissions" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="System.Security.Permissions" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="System.ServiceProcess.ServiceController" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="System.ServiceProcess.ServiceController" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="System.Text.Encodings.Web" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="System.Text.Encodings.Web" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="System.Text.Json" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="System.Text.Json" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="System.Threading.AccessControl" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="System.Threading.AccessControl" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="System.Threading.Channels" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="System.Threading.Channels" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="System.Threading.RateLimiting" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="System.Threading.RateLimiting" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.Extensions.DependencyModel" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.Extensions.DependencyModel" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.NETCore.App.Ref" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.NETCore.App.Ref" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.NET.Runtime.MonoAOTCompiler.Task" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.NET.Runtime.MonoAOTCompiler.Task" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.NET.Runtime.WebAssembly.Sdk" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.NET.Runtime.WebAssembly.Sdk" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
<!--
Win-x64 is used here because we have picked an arbitrary runtime identifier to flow the version of the latest NETCore.App runtime.
All Runtime.$rid packages should have the same version.
-->
- <Dependency Name="Microsoft.NETCore.App.Runtime.win-x64" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.NETCore.App.Runtime.win-x64" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.NETCore.App.Runtime.AOT.win-x64.Cross.browser-wasm" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.NETCore.App.Runtime.AOT.win-x64.Cross.browser-wasm" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.NETCore.BrowserDebugHost.Transport" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.NETCore.BrowserDebugHost.Transport" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
</ProductDependencies>
<ToolsetDependencies>
<!-- Listed explicitly to workaround https://github.com/dotnet/cli/issues/10528 -->
- <Dependency Name="Microsoft.NETCore.Platforms" Version="7.0.0-preview.4.22174.7">
+ <Dependency Name="Microsoft.NETCore.Platforms" Version="7.0.0-preview.4.22180.7">
<Uri>https://github.com/dotnet/runtime</Uri>
- <Sha>cd5beb14b0ce11ae1e4e3f1d30bffba7e37ce606</Sha>
+ <Sha>c0db07b3f3f093b5f4cd27e1f5e8aa54adad049d</Sha>
</Dependency>
- <Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="7.0.0-beta.22168.2">
+ <Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="7.0.0-beta.22171.2">
<Uri>https://github.com/dotnet/arcade</Uri>
- <Sha>bafd55901b50d6fc3507c8ed96a7777fcca1796f</Sha>
+ <Sha>c8a95297e2622251c125aa5c0ef7c822275a792d</Sha>
<SourceBuild RepoName="arcade" ManagedOnly="true" />
</Dependency>
- <Dependency Name="Microsoft.DotNet.Build.Tasks.Installers" Version="7.0.0-beta.22168.2">
+ <Dependency Name="Microsoft.DotNet.Build.Tasks.Installers" Version="7.0.0-beta.22171.2">
<Uri>https://github.com/dotnet/arcade</Uri>
- <Sha>bafd55901b50d6fc3507c8ed96a7777fcca1796f</Sha>
+ <Sha>c8a95297e2622251c125aa5c0ef7c822275a792d</Sha>
</Dependency>
- <Dependency Name="Microsoft.DotNet.Build.Tasks.Templating" Version="7.0.0-beta.22168.2">
+ <Dependency Name="Microsoft.DotNet.Build.Tasks.Templating" Version="7.0.0-beta.22171.2">
<Uri>https://github.com/dotnet/arcade</Uri>
- <Sha>bafd55901b50d6fc3507c8ed96a7777fcca1796f</Sha>
+ <Sha>c8a95297e2622251c125aa5c0ef7c822275a792d</Sha>
</Dependency>
- <Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="7.0.0-beta.22168.2">
+ <Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="7.0.0-beta.22171.2">
<Uri>https://github.com/dotnet/arcade</Uri>
- <Sha>bafd55901b50d6fc3507c8ed96a7777fcca1796f</Sha>
+ <Sha>c8a95297e2622251c125aa5c0ef7c822275a792d</Sha>
</Dependency>
</ToolsetDependencies>
</Dependencies>
diff --git a/eng/Versions.props b/eng/Versions.props
index 6ceb8c6243..8f2faf555e 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -63,79 +63,79 @@
-->
<PropertyGroup Label="Automated">
<!-- Packages from dotnet/runtime -->
- <MicrosoftExtensionsDependencyModelVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsDependencyModelVersion>
- <MicrosoftNETCoreAppRefVersion>7.0.0-preview.4.22174.7</MicrosoftNETCoreAppRefVersion>
- <MicrosoftNETCoreAppRuntimewinx64Version>7.0.0-preview.4.22174.7</MicrosoftNETCoreAppRuntimewinx64Version>
- <MicrosoftNETRuntimeMonoAOTCompilerTaskVersion>7.0.0-preview.4.22174.7</MicrosoftNETRuntimeMonoAOTCompilerTaskVersion>
- <MicrosoftNETRuntimeWebAssemblySdkVersion>7.0.0-preview.4.22174.7</MicrosoftNETRuntimeWebAssemblySdkVersion>
- <MicrosoftNETCoreAppRuntimeAOTwinx64CrossbrowserwasmVersion>7.0.0-preview.4.22174.7</MicrosoftNETCoreAppRuntimeAOTwinx64CrossbrowserwasmVersion>
- <MicrosoftNETCoreBrowserDebugHostTransportVersion>7.0.0-preview.4.22174.7</MicrosoftNETCoreBrowserDebugHostTransportVersion>
- <MicrosoftExtensionsCachingAbstractionsVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsCachingAbstractionsVersion>
- <MicrosoftExtensionsCachingMemoryVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsCachingMemoryVersion>
- <MicrosoftExtensionsConfigurationAbstractionsVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsConfigurationAbstractionsVersion>
- <MicrosoftExtensionsConfigurationBinderVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsConfigurationBinderVersion>
- <MicrosoftExtensionsConfigurationCommandLineVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsConfigurationCommandLineVersion>
- <MicrosoftExtensionsConfigurationEnvironmentVariablesVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsConfigurationEnvironmentVariablesVersion>
- <MicrosoftExtensionsConfigurationFileExtensionsVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsConfigurationFileExtensionsVersion>
- <MicrosoftExtensionsConfigurationIniVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsConfigurationIniVersion>
- <MicrosoftExtensionsConfigurationJsonVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsConfigurationJsonVersion>
- <MicrosoftExtensionsConfigurationVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsConfigurationVersion>
- <MicrosoftExtensionsConfigurationUserSecretsVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsConfigurationUserSecretsVersion>
- <MicrosoftExtensionsConfigurationXmlVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsConfigurationXmlVersion>
- <MicrosoftExtensionsDependencyInjectionAbstractionsVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsDependencyInjectionAbstractionsVersion>
- <MicrosoftExtensionsDependencyInjectionVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsDependencyInjectionVersion>
- <MicrosoftExtensionsFileProvidersAbstractionsVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsFileProvidersAbstractionsVersion>
- <MicrosoftExtensionsFileProvidersCompositeVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsFileProvidersCompositeVersion>
- <MicrosoftExtensionsFileProvidersPhysicalVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsFileProvidersPhysicalVersion>
- <MicrosoftExtensionsFileSystemGlobbingVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsFileSystemGlobbingVersion>
- <MicrosoftExtensionsHostFactoryResolverSourcesVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsHostFactoryResolverSourcesVersion>
- <MicrosoftExtensionsHostingAbstractionsVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsHostingAbstractionsVersion>
- <MicrosoftExtensionsHostingVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsHostingVersion>
- <MicrosoftExtensionsHttpVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsHttpVersion>
- <MicrosoftExtensionsLoggingAbstractionsVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsLoggingAbstractionsVersion>
- <MicrosoftExtensionsLoggingConfigurationVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsLoggingConfigurationVersion>
- <MicrosoftExtensionsLoggingConsoleVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsLoggingConsoleVersion>
- <MicrosoftExtensionsLoggingDebugVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsLoggingDebugVersion>
- <MicrosoftExtensionsLoggingEventSourceVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsLoggingEventSourceVersion>
- <MicrosoftExtensionsLoggingEventLogVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsLoggingEventLogVersion>
- <MicrosoftExtensionsLoggingVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsLoggingVersion>
- <MicrosoftExtensionsLoggingTraceSourceVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsLoggingTraceSourceVersion>
- <MicrosoftExtensionsOptionsConfigurationExtensionsVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsOptionsConfigurationExtensionsVersion>
- <MicrosoftExtensionsOptionsDataAnnotationsVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsOptionsDataAnnotationsVersion>
- <MicrosoftExtensionsOptionsVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsOptionsVersion>
- <MicrosoftExtensionsPrimitivesVersion>7.0.0-preview.4.22174.7</MicrosoftExtensionsPrimitivesVersion>
- <MicrosoftInternalRuntimeAspNetCoreTransportVersion>7.0.0-preview.4.22174.7</MicrosoftInternalRuntimeAspNetCoreTransportVersion>
- <SystemDiagnosticsDiagnosticSourceVersion>7.0.0-preview.4.22174.7</SystemDiagnosticsDiagnosticSourceVersion>
- <SystemDiagnosticsEventLogVersion>7.0.0-preview.4.22174.7</SystemDiagnosticsEventLogVersion>
- <SystemDirectoryServicesProtocolsVersion>7.0.0-preview.4.22174.7</SystemDirectoryServicesProtocolsVersion>
- <SystemIOPipelinesVersion>7.0.0-preview.4.22174.7</SystemIOPipelinesVersion>
- <SystemNetHttpJsonVersion>7.0.0-preview.4.22174.7</SystemNetHttpJsonVersion>
- <SystemNetHttpWinHttpHandlerVersion>7.0.0-preview.4.22174.7</SystemNetHttpWinHttpHandlerVersion>
- <SystemReflectionMetadataVersion>7.0.0-preview.4.22174.7</SystemReflectionMetadataVersion>
- <SystemResourcesExtensionsVersion>7.0.0-preview.4.22174.7</SystemResourcesExtensionsVersion>
- <SystemSecurityCryptographyPkcsVersion>7.0.0-preview.4.22174.7</SystemSecurityCryptographyPkcsVersion>
- <SystemSecurityCryptographyXmlVersion>7.0.0-preview.4.22174.7</SystemSecurityCryptographyXmlVersion>
- <SystemSecurityPermissionsVersion>7.0.0-preview.4.22174.7</SystemSecurityPermissionsVersion>
- <SystemServiceProcessServiceControllerVersion>7.0.0-preview.4.22174.7</SystemServiceProcessServiceControllerVersion>
- <SystemTextEncodingsWebVersion>7.0.0-preview.4.22174.7</SystemTextEncodingsWebVersion>
- <SystemTextJsonVersion>7.0.0-preview.4.22174.7</SystemTextJsonVersion>
- <SystemThreadingAccessControlVersion>7.0.0-preview.4.22174.7</SystemThreadingAccessControlVersion>
- <SystemThreadingChannelsVersion>7.0.0-preview.4.22174.7</SystemThreadingChannelsVersion>
- <SystemThreadingRateLimitingVersion>7.0.0-preview.4.22174.7</SystemThreadingRateLimitingVersion>
+ <MicrosoftExtensionsDependencyModelVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsDependencyModelVersion>
+ <MicrosoftNETCoreAppRefVersion>7.0.0-preview.4.22180.7</MicrosoftNETCoreAppRefVersion>
+ <MicrosoftNETCoreAppRuntimewinx64Version>7.0.0-preview.4.22180.7</MicrosoftNETCoreAppRuntimewinx64Version>
+ <MicrosoftNETRuntimeMonoAOTCompilerTaskVersion>7.0.0-preview.4.22180.7</MicrosoftNETRuntimeMonoAOTCompilerTaskVersion>
+ <MicrosoftNETRuntimeWebAssemblySdkVersion>7.0.0-preview.4.22180.7</MicrosoftNETRuntimeWebAssemblySdkVersion>
+ <MicrosoftNETCoreAppRuntimeAOTwinx64CrossbrowserwasmVersion>7.0.0-preview.4.22180.7</MicrosoftNETCoreAppRuntimeAOTwinx64CrossbrowserwasmVersion>
+ <MicrosoftNETCoreBrowserDebugHostTransportVersion>7.0.0-preview.4.22180.7</MicrosoftNETCoreBrowserDebugHostTransportVersion>
+ <MicrosoftExtensionsCachingAbstractionsVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsCachingAbstractionsVersion>
+ <MicrosoftExtensionsCachingMemoryVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsCachingMemoryVersion>
+ <MicrosoftExtensionsConfigurationAbstractionsVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsConfigurationAbstractionsVersion>
+ <MicrosoftExtensionsConfigurationBinderVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsConfigurationBinderVersion>
+ <MicrosoftExtensionsConfigurationCommandLineVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsConfigurationCommandLineVersion>
+ <MicrosoftExtensionsConfigurationEnvironmentVariablesVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsConfigurationEnvironmentVariablesVersion>
+ <MicrosoftExtensionsConfigurationFileExtensionsVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsConfigurationFileExtensionsVersion>
+ <MicrosoftExtensionsConfigurationIniVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsConfigurationIniVersion>
+ <MicrosoftExtensionsConfigurationJsonVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsConfigurationJsonVersion>
+ <MicrosoftExtensionsConfigurationVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsConfigurationVersion>
+ <MicrosoftExtensionsConfigurationUserSecretsVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsConfigurationUserSecretsVersion>
+ <MicrosoftExtensionsConfigurationXmlVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsConfigurationXmlVersion>
+ <MicrosoftExtensionsDependencyInjectionAbstractionsVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsDependencyInjectionAbstractionsVersion>
+ <MicrosoftExtensionsDependencyInjectionVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsDependencyInjectionVersion>
+ <MicrosoftExtensionsFileProvidersAbstractionsVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsFileProvidersAbstractionsVersion>
+ <MicrosoftExtensionsFileProvidersCompositeVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsFileProvidersCompositeVersion>
+ <MicrosoftExtensionsFileProvidersPhysicalVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsFileProvidersPhysicalVersion>
+ <MicrosoftExtensionsFileSystemGlobbingVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsFileSystemGlobbingVersion>
+ <MicrosoftExtensionsHostFactoryResolverSourcesVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsHostFactoryResolverSourcesVersion>
+ <MicrosoftExtensionsHostingAbstractionsVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsHostingAbstractionsVersion>
+ <MicrosoftExtensionsHostingVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsHostingVersion>
+ <MicrosoftExtensionsHttpVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsHttpVersion>
+ <MicrosoftExtensionsLoggingAbstractionsVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsLoggingAbstractionsVersion>
+ <MicrosoftExtensionsLoggingConfigurationVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsLoggingConfigurationVersion>
+ <MicrosoftExtensionsLoggingConsoleVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsLoggingConsoleVersion>
+ <MicrosoftExtensionsLoggingDebugVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsLoggingDebugVersion>
+ <MicrosoftExtensionsLoggingEventSourceVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsLoggingEventSourceVersion>
+ <MicrosoftExtensionsLoggingEventLogVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsLoggingEventLogVersion>
+ <MicrosoftExtensionsLoggingVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsLoggingVersion>
+ <MicrosoftExtensionsLoggingTraceSourceVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsLoggingTraceSourceVersion>
+ <MicrosoftExtensionsOptionsConfigurationExtensionsVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsOptionsConfigurationExtensionsVersion>
+ <MicrosoftExtensionsOptionsDataAnnotationsVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsOptionsDataAnnotationsVersion>
+ <MicrosoftExtensionsOptionsVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsOptionsVersion>
+ <MicrosoftExtensionsPrimitivesVersion>7.0.0-preview.4.22180.7</MicrosoftExtensionsPrimitivesVersion>
+ <MicrosoftInternalRuntimeAspNetCoreTransportVersion>7.0.0-preview.4.22180.7</MicrosoftInternalRuntimeAspNetCoreTransportVersion>
+ <SystemDiagnosticsDiagnosticSourceVersion>7.0.0-preview.4.22180.7</SystemDiagnosticsDiagnosticSourceVersion>
+ <SystemDiagnosticsEventLogVersion>7.0.0-preview.4.22180.7</SystemDiagnosticsEventLogVersion>
+ <SystemDirectoryServicesProtocolsVersion>7.0.0-preview.4.22180.7</SystemDirectoryServicesProtocolsVersion>
+ <SystemIOPipelinesVersion>7.0.0-preview.4.22180.7</SystemIOPipelinesVersion>
+ <SystemNetHttpJsonVersion>7.0.0-preview.4.22180.7</SystemNetHttpJsonVersion>
+ <SystemNetHttpWinHttpHandlerVersion>7.0.0-preview.4.22180.7</SystemNetHttpWinHttpHandlerVersion>
+ <SystemReflectionMetadataVersion>7.0.0-preview.4.22180.7</SystemReflectionMetadataVersion>
+ <SystemResourcesExtensionsVersion>7.0.0-preview.4.22180.7</SystemResourcesExtensionsVersion>
+ <SystemSecurityCryptographyPkcsVersion>7.0.0-preview.4.22180.7</SystemSecurityCryptographyPkcsVersion>
+ <SystemSecurityCryptographyXmlVersion>7.0.0-preview.4.22180.7</SystemSecurityCryptographyXmlVersion>
+ <SystemSecurityPermissionsVersion>7.0.0-preview.4.22180.7</SystemSecurityPermissionsVersion>
+ <SystemServiceProcessServiceControllerVersion>7.0.0-preview.4.22180.7</SystemServiceProcessServiceControllerVersion>
+ <SystemTextEncodingsWebVersion>7.0.0-preview.4.22180.7</SystemTextEncodingsWebVersion>
+ <SystemTextJsonVersion>7.0.0-preview.4.22180.7</SystemTextJsonVersion>
+ <SystemThreadingAccessControlVersion>7.0.0-preview.4.22180.7</SystemThreadingAccessControlVersion>
+ <SystemThreadingChannelsVersion>7.0.0-preview.4.22180.7</SystemThreadingChannelsVersion>
+ <SystemThreadingRateLimitingVersion>7.0.0-preview.4.22180.7</SystemThreadingRateLimitingVersion>
<!-- Only listed explicitly to workaround https://github.com/dotnet/cli/issues/10528 -->
- <MicrosoftNETCorePlatformsVersion>7.0.0-preview.4.22174.7</MicrosoftNETCorePlatformsVersion>
+ <MicrosoftNETCorePlatformsVersion>7.0.0-preview.4.22180.7</MicrosoftNETCorePlatformsVersion>
<!-- Packages from dotnet/efcore -->
- <dotnetefVersion>7.0.0-preview.4.22173.5</dotnetefVersion>
- <MicrosoftEntityFrameworkCoreInMemoryVersion>7.0.0-preview.4.22173.5</MicrosoftEntityFrameworkCoreInMemoryVersion>
- <MicrosoftEntityFrameworkCoreRelationalVersion>7.0.0-preview.4.22173.5</MicrosoftEntityFrameworkCoreRelationalVersion>
- <MicrosoftEntityFrameworkCoreSqliteVersion>7.0.0-preview.4.22173.5</MicrosoftEntityFrameworkCoreSqliteVersion>
- <MicrosoftEntityFrameworkCoreSqlServerVersion>7.0.0-preview.4.22173.5</MicrosoftEntityFrameworkCoreSqlServerVersion>
- <MicrosoftEntityFrameworkCoreToolsVersion>7.0.0-preview.4.22173.5</MicrosoftEntityFrameworkCoreToolsVersion>
- <MicrosoftEntityFrameworkCoreVersion>7.0.0-preview.4.22173.5</MicrosoftEntityFrameworkCoreVersion>
- <MicrosoftEntityFrameworkCoreDesignVersion>7.0.0-preview.4.22173.5</MicrosoftEntityFrameworkCoreDesignVersion>
+ <dotnetefVersion>7.0.0-preview.4.22178.2</dotnetefVersion>
+ <MicrosoftEntityFrameworkCoreInMemoryVersion>7.0.0-preview.4.22178.2</MicrosoftEntityFrameworkCoreInMemoryVersion>
+ <MicrosoftEntityFrameworkCoreRelationalVersion>7.0.0-preview.4.22178.2</MicrosoftEntityFrameworkCoreRelationalVersion>
+ <MicrosoftEntityFrameworkCoreSqliteVersion>7.0.0-preview.4.22178.2</MicrosoftEntityFrameworkCoreSqliteVersion>
+ <MicrosoftEntityFrameworkCoreSqlServerVersion>7.0.0-preview.4.22178.2</MicrosoftEntityFrameworkCoreSqlServerVersion>
+ <MicrosoftEntityFrameworkCoreToolsVersion>7.0.0-preview.4.22178.2</MicrosoftEntityFrameworkCoreToolsVersion>
+ <MicrosoftEntityFrameworkCoreVersion>7.0.0-preview.4.22178.2</MicrosoftEntityFrameworkCoreVersion>
+ <MicrosoftEntityFrameworkCoreDesignVersion>7.0.0-preview.4.22178.2</MicrosoftEntityFrameworkCoreDesignVersion>
<!-- Packages from dotnet/arcade -->
- <MicrosoftDotNetBuildTasksInstallersVersion>7.0.0-beta.22168.2</MicrosoftDotNetBuildTasksInstallersVersion>
- <MicrosoftDotNetBuildTasksTemplatingVersion>7.0.0-beta.22168.2</MicrosoftDotNetBuildTasksTemplatingVersion>
+ <MicrosoftDotNetBuildTasksInstallersVersion>7.0.0-beta.22171.2</MicrosoftDotNetBuildTasksInstallersVersion>
+ <MicrosoftDotNetBuildTasksTemplatingVersion>7.0.0-beta.22171.2</MicrosoftDotNetBuildTasksTemplatingVersion>
</PropertyGroup>
<!--
diff --git a/eng/helix/content/runtests.sh b/eng/helix/content/runtests.sh
index 1fd36f1997..af91c928ab 100644
--- a/eng/helix/content/runtests.sh
+++ b/eng/helix/content/runtests.sh
@@ -76,7 +76,16 @@ sync
exit_code=0
echo "Restore: dotnet restore RunTests/RunTests.csproj --ignore-failed-sources"
-dotnet restore RunTests/RunTests.csproj --ignore-failed-sources
+
+# --verbosity diagnostic can be removed when random failures are identified
+dotnet restore RunTests/RunTests.csproj --ignore-failed-sources --verbosity diagnostic
+
+exit_code=$?
+
+if [[ $exit_code != 0 ]]; then
+ echo "Restore runtests failed: exit_code=$exit_code"
+ exit $exit_code
+fi
echo "Running tests: dotnet run --no-restore --project RunTests/RunTests.csproj -- --target $1 --runtime $2 --queue $helixQueue --arch $4 --quarantined $5 --ef $6 --helixTimeout $7"
dotnet run --no-restore --project RunTests/RunTests.csproj -- --target $1 --runtime $2 --queue $helixQueue --arch $4 --quarantined $5 --ef $6 --helixTimeout $7
diff --git a/global.json b/global.json
index fdb8f88394..daef57c601 100644
--- a/global.json
+++ b/global.json
@@ -1,9 +1,9 @@
{
"sdk": {
- "version": "7.0.100-preview.4.22174.1"
+ "version": "7.0.100-preview.4.22175.5"
},
"tools": {
- "dotnet": "7.0.100-preview.4.22174.1",
+ "dotnet": "7.0.100-preview.4.22175.5",
"runtimes": {
"dotnet/x86": [
"$(MicrosoftNETCoreBrowserDebugHostTransportVersion)"
@@ -27,7 +27,7 @@
},
"msbuild-sdks": {
"Yarn.MSBuild": "1.22.10",
- "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.22168.2",
- "Microsoft.DotNet.Helix.Sdk": "7.0.0-beta.22168.2"
+ "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.22171.2",
+ "Microsoft.DotNet.Helix.Sdk": "7.0.0-beta.22171.2"
}
}
diff --git a/src/Caching/SqlServer/src/MonoDatabaseOperations.cs b/src/Caching/SqlServer/src/MonoDatabaseOperations.cs
deleted file mode 100644
index 694a59c46a..0000000000
--- a/src/Caching/SqlServer/src/MonoDatabaseOperations.cs
+++ /dev/null
@@ -1,201 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Data;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Data.SqlClient;
-using Microsoft.Extensions.Caching.Distributed;
-using Microsoft.Extensions.Internal;
-
-namespace Microsoft.Extensions.Caching.SqlServer;
-
-internal class MonoDatabaseOperations : DatabaseOperations
-{
- public MonoDatabaseOperations(
- string connectionString, string schemaName, string tableName, ISystemClock systemClock)
- : base(connectionString, schemaName, tableName, systemClock)
- {
- }
-
- protected override byte[]? GetCacheItem(string key, bool includeValue)
- {
- var utcNow = SystemClock.UtcNow;
-
- string query;
- if (includeValue)
- {
- query = SqlQueries.GetCacheItem;
- }
- else
- {
- query = SqlQueries.GetCacheItemWithoutValue;
- }
-
- byte[]? value = null;
- using (var connection = new SqlConnection(ConnectionString))
- {
- var command = new SqlCommand(query, connection);
- command.Parameters
- .AddCacheItemId(key)
- .AddWithValue("UtcNow", SqlDbType.DateTime, utcNow.UtcDateTime);
-
- connection.Open();
-
- var reader = command.ExecuteReader(CommandBehavior.SingleRow | CommandBehavior.SingleResult);
-
- if (reader.Read())
- {
- if (includeValue)
- {
- value = (byte[])reader[Columns.Indexes.CacheItemValueIndex];
- }
- }
- else
- {
- return null;
- }
- }
-
- return value;
- }
-
- protected override async Task<byte[]?> GetCacheItemAsync(string key, bool includeValue, CancellationToken token = default(CancellationToken))
- {
- token.ThrowIfCancellationRequested();
-
- var utcNow = SystemClock.UtcNow;
-
- string query;
- if (includeValue)
- {
- query = SqlQueries.GetCacheItem;
- }
- else
- {
- query = SqlQueries.GetCacheItemWithoutValue;
- }
-
- byte[]? value = null;
- using (var connection = new SqlConnection(ConnectionString))
- {
- var command = new SqlCommand(query, connection);
- command.Parameters
- .AddCacheItemId(key)
- .AddWithValue("UtcNow", SqlDbType.DateTime, utcNow.UtcDateTime);
-
- await connection.OpenAsync(token).ConfigureAwait(false);
-
- var reader = await command.ExecuteReaderAsync(
- CommandBehavior.SingleRow | CommandBehavior.SingleResult,
- token).ConfigureAwait(false);
-
- if (await reader.ReadAsync(token).ConfigureAwait(false))
- {
- if (includeValue)
- {
- value = (byte[])reader[Columns.Indexes.CacheItemValueIndex];
- }
- }
- else
- {
- return null;
- }
- }
-
- return value;
- }
-
- public override void SetCacheItem(string key, byte[] value, DistributedCacheEntryOptions options)
- {
- var utcNow = SystemClock.UtcNow;
-
- var absoluteExpiration = DatabaseOperations.GetAbsoluteExpiration(utcNow, options);
- DatabaseOperations.ValidateOptions(options.SlidingExpiration, absoluteExpiration);
-
- using (var connection = new SqlConnection(ConnectionString))
- {
- var upsertCommand = new SqlCommand(SqlQueries.SetCacheItem, connection);
- upsertCommand.Parameters
- .AddCacheItemId(key)
- .AddCacheItemValue(value)
- .AddSlidingExpirationInSeconds(options.SlidingExpiration)
- .AddAbsoluteExpirationMono(absoluteExpiration)
- .AddWithValue("UtcNow", SqlDbType.DateTime, utcNow.UtcDateTime);
-
- connection.Open();
-
- try
- {
- upsertCommand.ExecuteNonQuery();
- }
- catch (SqlException ex)
- {
- if (DatabaseOperations.IsDuplicateKeyException(ex))
- {
- // There is a possibility that multiple requests can try to add the same item to the cache, in
- // which case we receive a 'duplicate key' exception on the primary key column.
- }
- else
- {
- throw;
- }
- }
- }
- }
-
- public override async Task SetCacheItemAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default(CancellationToken))
- {
- token.ThrowIfCancellationRequested();
-
- var utcNow = SystemClock.UtcNow;
-
- var absoluteExpiration = DatabaseOperations.GetAbsoluteExpiration(utcNow, options);
- DatabaseOperations.ValidateOptions(options.SlidingExpiration, absoluteExpiration);
-
- using (var connection = new SqlConnection(ConnectionString))
- {
- var upsertCommand = new SqlCommand(SqlQueries.SetCacheItem, connection);
- upsertCommand.Parameters
- .AddCacheItemId(key)
- .AddCacheItemValue(value)
- .AddSlidingExpirationInSeconds(options.SlidingExpiration)
- .AddAbsoluteExpirationMono(absoluteExpiration)
- .AddWithValue("UtcNow", SqlDbType.DateTime, utcNow.UtcDateTime);
-
- await connection.OpenAsync(token).ConfigureAwait(false);
-
- try
- {
- await upsertCommand.ExecuteNonQueryAsync(token).ConfigureAwait(false);
- }
- catch (SqlException ex)
- {
- if (DatabaseOperations.IsDuplicateKeyException(ex))
- {
- // There is a possibility that multiple requests can try to add the same item to the cache, in
- // which case we receive a 'duplicate key' exception on the primary key column.
- }
- else
- {
- throw;
- }
- }
- }
- }
-
- public override void DeleteExpiredCacheItems()
- {
- var utcNow = SystemClock.UtcNow;
-
- using (var connection = new SqlConnection(ConnectionString))
- {
- var command = new SqlCommand(SqlQueries.DeleteExpiredCacheItems, connection);
- command.Parameters.AddWithValue("UtcNow", SqlDbType.DateTime, utcNow.UtcDateTime);
-
- connection.Open();
-
- var effectedRowCount = command.ExecuteNonQuery();
- }
- }
-}
diff --git a/src/Caching/SqlServer/src/MonoSqlParameterCollectionExtensions.cs b/src/Caching/SqlServer/src/MonoSqlParameterCollectionExtensions.cs
deleted file mode 100644
index 96e896912a..0000000000
--- a/src/Caching/SqlServer/src/MonoSqlParameterCollectionExtensions.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Data;
-using Microsoft.Data.SqlClient;
-
-namespace Microsoft.Extensions.Caching.SqlServer;
-
-// Since Mono currently does not have support for DateTimeOffset, we convert the time to UtcDateTime.
-// Even though the database column is of type 'datetimeoffset', we can store the UtcDateTime, in which case
-// the zone is set as 00:00. If you look at the below examples, DateTimeOffset.UtcNow
-// and DateTimeOffset.UtcDateTime are almost the same.
-//
-// Examples:
-// DateTimeOffset.Now: 6/29/2015 1:20:40 PM - 07:00
-// DateTimeOffset.UtcNow: 6/29/2015 8:20:40 PM + 00:00
-// DateTimeOffset.UtcDateTime: 6/29/2015 8:20:40 PM
-internal static class MonoSqlParameterCollectionExtensions
-{
- public static SqlParameterCollection AddExpiresAtTimeMono(
- this SqlParameterCollection parameters,
- DateTimeOffset utcTime)
- {
- return parameters.AddWithValue(Columns.Names.ExpiresAtTime, SqlDbType.DateTime, utcTime.UtcDateTime);
- }
-
- public static SqlParameterCollection AddAbsoluteExpirationMono(
- this SqlParameterCollection parameters,
- DateTimeOffset? utcTime)
- {
- if (utcTime.HasValue)
- {
- return parameters.AddWithValue(
- Columns.Names.AbsoluteExpiration, SqlDbType.DateTime, utcTime.Value.UtcDateTime);
- }
- else
- {
- return parameters.AddWithValue(
- Columns.Names.AbsoluteExpiration, SqlDbType.DateTime, DBNull.Value);
- }
- }
-}
diff --git a/src/Caching/SqlServer/src/PlatformHelper.cs b/src/Caching/SqlServer/src/PlatformHelper.cs
deleted file mode 100644
index 613b98d7b5..0000000000
--- a/src/Caching/SqlServer/src/PlatformHelper.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-
-namespace Microsoft.Extensions.Caching.SqlServer;
-
-internal static class PlatformHelper
-{
- private static readonly Lazy<bool> _isMono = new Lazy<bool>(() => Type.GetType("Mono.Runtime") != null);
-
- public static bool IsMono
- {
- get
- {
- return _isMono.Value;
- }
- }
-}
diff --git a/src/Caching/SqlServer/src/SqlServerCache.cs b/src/Caching/SqlServer/src/SqlServerCache.cs
index bc22e2a6fd..968dbb8430 100644
--- a/src/Caching/SqlServer/src/SqlServerCache.cs
+++ b/src/Caching/SqlServer/src/SqlServerCache.cs
@@ -70,25 +70,11 @@ public class SqlServerCache : IDistributedCache
_deleteExpiredCachedItemsDelegate = DeleteExpiredCacheItems;
_defaultSlidingExpiration = cacheOptions.DefaultSlidingExpiration;
- // SqlClient library on Mono doesn't have support for DateTimeOffset and also
- // it doesn't have support for apis like GetFieldValue, GetFieldValueAsync etc.
- // So we detect the platform to perform things differently for Mono vs. non-Mono platforms.
- if (PlatformHelper.IsMono)
- {
- _dbOperations = new MonoDatabaseOperations(
- cacheOptions.ConnectionString,
- cacheOptions.SchemaName,
- cacheOptions.TableName,
- _systemClock);
- }
- else
- {
- _dbOperations = new DatabaseOperations(
- cacheOptions.ConnectionString,
- cacheOptions.SchemaName,
- cacheOptions.TableName,
- _systemClock);
- }
+ _dbOperations = new DatabaseOperations(
+ cacheOptions.ConnectionString,
+ cacheOptions.SchemaName,
+ cacheOptions.TableName,
+ _systemClock);
}
/// <inheritdoc />
diff --git a/src/Components/WebAssembly/Authentication.Msal/src/Interop/package.json b/src/Components/WebAssembly/Authentication.Msal/src/Interop/package.json
index f3195a5a34..43862a4806 100644
--- a/src/Components/WebAssembly/Authentication.Msal/src/Interop/package.json
+++ b/src/Components/WebAssembly/Authentication.Msal/src/Interop/package.json
@@ -29,6 +29,7 @@
"@azure/msal-browser": "^2.16.1"
},
"resolutions": {
- "ansi-regex": "5.0.1"
+ "ansi-regex": "5.0.1",
+ "minimist": ">=1.2.6"
}
}
diff --git a/src/Components/WebAssembly/Authentication.Msal/src/Interop/yarn.lock b/src/Components/WebAssembly/Authentication.Msal/src/Interop/yarn.lock
index 51b9f4e1bf..97ffee2210 100644
--- a/src/Components/WebAssembly/Authentication.Msal/src/Interop/yarn.lock
+++ b/src/Components/WebAssembly/Authentication.Msal/src/Interop/yarn.lock
@@ -2168,10 +2168,10 @@ minimatch@^3.0.4:
dependencies:
brace-expansion "^1.1.7"
-minimist@^1.2.5:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
- integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
+minimist@>=1.2.6, minimist@^1.2.5:
+ version "1.2.6"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
+ integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
ms@2.1.2:
version "2.1.2"
diff --git a/src/Components/WebAssembly/WebAssembly.Authentication/src/Interop/package.json b/src/Components/WebAssembly/WebAssembly.Authentication/src/Interop/package.json
index 09ce7e5b8b..c93a4112fb 100644
--- a/src/Components/WebAssembly/WebAssembly.Authentication/src/Interop/package.json
+++ b/src/Components/WebAssembly/WebAssembly.Authentication/src/Interop/package.json
@@ -29,6 +29,7 @@
"oidc-client": "^1.11.5"
},
"resolutions": {
- "ansi-regex": "5.0.1"
+ "ansi-regex": "5.0.1",
+ "minimist": ">=1.2.6"
}
}
diff --git a/src/Components/WebAssembly/WebAssembly.Authentication/src/Interop/yarn.lock b/src/Components/WebAssembly/WebAssembly.Authentication/src/Interop/yarn.lock
index 6c69bb84ab..5b524eaca4 100644
--- a/src/Components/WebAssembly/WebAssembly.Authentication/src/Interop/yarn.lock
+++ b/src/Components/WebAssembly/WebAssembly.Authentication/src/Interop/yarn.lock
@@ -2169,10 +2169,10 @@ minimatch@^3.0.4:
dependencies:
brace-expansion "^1.1.7"
-minimist@^1.2.5:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
- integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
+minimist@>=1.2.6, minimist@^1.2.5:
+ version "1.2.6"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
+ integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
ms@2.1.2:
version "2.1.2"
diff --git a/src/Components/WebView/WebView/src/Services/WebViewJSRuntime.cs b/src/Components/WebView/WebView/src/Services/WebViewJSRuntime.cs
index 6bdfac2617..b56b590b55 100644
--- a/src/Components/WebView/WebView/src/Services/WebViewJSRuntime.cs
+++ b/src/Components/WebView/WebView/src/Services/WebViewJSRuntime.cs
@@ -30,6 +30,11 @@ internal class WebViewJSRuntime : JSRuntime
protected override void BeginInvokeJS(long taskId, string identifier, string argsJson, JSCallResultType resultType, long targetInstanceId)
{
+ if (_ipcSender is null)
+ {
+ throw new InvalidOperationException("Cannot invoke JavaScript outside of a WebView context.");
+ }
+
_ipcSender.BeginInvokeJS(taskId, identifier, argsJson, resultType, targetInstanceId);
}
diff --git a/src/Hosting/Abstractions/src/Microsoft.AspNetCore.Hosting.Abstractions.csproj b/src/Hosting/Abstractions/src/Microsoft.AspNetCore.Hosting.Abstractions.csproj
index cdcf26e2a5..14efe07f3c 100644
--- a/src/Hosting/Abstractions/src/Microsoft.AspNetCore.Hosting.Abstractions.csproj
+++ b/src/Hosting/Abstractions/src/Microsoft.AspNetCore.Hosting.Abstractions.csproj
@@ -8,6 +8,7 @@
<PackageTags>aspnetcore;hosting</PackageTags>
<IsPackable>false</IsPackable>
<Nullable>enable</Nullable>
+ <Trimmable>true</Trimmable>
</PropertyGroup>
<ItemGroup>
diff --git a/src/Hosting/Server.Abstractions/src/Microsoft.AspNetCore.Hosting.Server.Abstractions.csproj b/src/Hosting/Server.Abstractions/src/Microsoft.AspNetCore.Hosting.Server.Abstractions.csproj
index ef3ae05a89..4de09ff8e4 100644
--- a/src/Hosting/Server.Abstractions/src/Microsoft.AspNetCore.Hosting.Server.Abstractions.csproj
+++ b/src/Hosting/Server.Abstractions/src/Microsoft.AspNetCore.Hosting.Server.Abstractions.csproj
@@ -8,6 +8,7 @@
<PackageTags>aspnetcore;hosting</PackageTags>
<IsPackable>false</IsPackable>
<Nullable>enable</Nullable>
+ <Trimmable>true</Trimmable>
</PropertyGroup>
<ItemGroup>
diff --git a/src/Hosting/Server.IntegrationTesting/src/Common/DeploymentResult.cs b/src/Hosting/Server.IntegrationTesting/src/Common/DeploymentResult.cs
index dc7101c5f5..588c30e58b 100644
--- a/src/Hosting/Server.IntegrationTesting/src/Common/DeploymentResult.cs
+++ b/src/Hosting/Server.IntegrationTesting/src/Common/DeploymentResult.cs
@@ -62,5 +62,9 @@ public class DeploymentResult
/// <param name="baseHandler"></param>
/// <returns></returns>
public HttpClient CreateHttpClient(HttpMessageHandler baseHandler) =>
- new HttpClient(new LoggingHandler(_loggerFactory, baseHandler)) { BaseAddress = new Uri(ApplicationBaseUri) };
+ new HttpClient(new LoggingHandler(_loggerFactory, baseHandler))
+ {
+ BaseAddress = new Uri(ApplicationBaseUri),
+ Timeout = TimeSpan.FromSeconds(200),
+ };
}
diff --git a/src/Hosting/Server.IntegrationTesting/src/Deployers/NginxDeployer.cs b/src/Hosting/Server.IntegrationTesting/src/Deployers/NginxDeployer.cs
index a004b07b12..9c09a94445 100644
--- a/src/Hosting/Server.IntegrationTesting/src/Deployers/NginxDeployer.cs
+++ b/src/Hosting/Server.IntegrationTesting/src/Deployers/NginxDeployer.cs
@@ -77,6 +77,7 @@ public class NginxDeployer : SelfHostDeployer
// Target actual address to avoid going through Nginx proxy
using (var httpClient = new HttpClient())
{
+ httpClient.Timeout = TimeSpan.FromSeconds(200);
var response = await RetryHelper.RetryRequest(() =>
{
return httpClient.GetAsync(redirectUri);
diff --git a/src/Hosting/Server.IntegrationTesting/src/Deployers/RemoteWindowsDeployer/RemoteWindowsDeployer.cs b/src/Hosting/Server.IntegrationTesting/src/Deployers/RemoteWindowsDeployer/RemoteWindowsDeployer.cs
index 40b5cd1bcc..b7b8289375 100644
--- a/src/Hosting/Server.IntegrationTesting/src/Deployers/RemoteWindowsDeployer/RemoteWindowsDeployer.cs
+++ b/src/Hosting/Server.IntegrationTesting/src/Deployers/RemoteWindowsDeployer/RemoteWindowsDeployer.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
@@ -254,8 +254,8 @@ public class RemoteWindowsDeployer : ApplicationDeployer
runScriptsOnRemoteServerProcess.StartAndCaptureOutAndErrToLogger(serverAction, Logger);
- // Wait a second for the script to run or fail. The StartServer script will only terminate when the Deployer is disposed,
- // so we don't want to wait for it to terminate here because it would deadlock.
+ // Wait a minute for the script to run or fail. The StartServer script will only terminate when the
+ // Deployer is disposed, so we don't want to wait for it to terminate here because it would deadlock.
await Task.Delay(TimeSpan.FromMinutes(1));
if (runScriptsOnRemoteServerProcess.HasExited && runScriptsOnRemoteServerProcess.ExitCode != 0)
diff --git a/src/Hosting/Server.IntegrationTesting/src/Deployers/SelfHostDeployer.cs b/src/Hosting/Server.IntegrationTesting/src/Deployers/SelfHostDeployer.cs
index bc299b4363..1abae50c79 100644
--- a/src/Hosting/Server.IntegrationTesting/src/Deployers/SelfHostDeployer.cs
+++ b/src/Hosting/Server.IntegrationTesting/src/Deployers/SelfHostDeployer.cs
@@ -192,10 +192,10 @@ public class SelfHostDeployer : ApplicationDeployer
// Host may not write startup messages, in which case assume it started
if (DeploymentParameters.StatusMessagesEnabled)
{
- // The timeout here is large, because we don't know how long the test could need
- // We cover a lot of error cases above, but I want to make sure we eventually give up and don't hang the build
- // just in case we missed one -anurse
- await started.Task.TimeoutAfter(TimeSpan.FromMinutes(10));
+ // The timeout here is large, because we don't know how long the test could need. We cover a lot
+ // of error cases above, but I want to make sure we eventually give up and don't hang the build
+ // just in case we missed one.
+ await started.Task.TimeoutAfter(TimeSpan.FromMinutes(15));
}
return (url: actualUrl ?? hintUrl, hostExitToken: hostExitTokenSource.Token);
diff --git a/src/Hosting/TestHost/src/TestServer.cs b/src/Hosting/TestHost/src/TestServer.cs
index c012b7a004..ed6ab6eb69 100644
--- a/src/Hosting/TestHost/src/TestServer.cs
+++ b/src/Hosting/TestHost/src/TestServer.cs
@@ -152,7 +152,11 @@ public class TestServer : IServer
/// </summary>
public HttpClient CreateClient()
{
- return new HttpClient(CreateHandler()) { BaseAddress = BaseAddress };
+ return new HttpClient(CreateHandler())
+ {
+ BaseAddress = BaseAddress,
+ Timeout = TimeSpan.FromSeconds(200),
+ };
}
/// <summary>
diff --git a/src/Http/Http.Extensions/src/HeaderDictionaryTypeExtensions.cs b/src/Http/Http.Extensions/src/HeaderDictionaryTypeExtensions.cs
index f7e923a561..fcc8b91c8f 100644
--- a/src/Http/Http.Extensions/src/HeaderDictionaryTypeExtensions.cs
+++ b/src/Http/Http.Extensions/src/HeaderDictionaryTypeExtensions.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Reflection;
@@ -166,29 +167,29 @@ public static class HeaderDictionaryTypeExtensions
}
}
- private static readonly IDictionary<Type, object> KnownParsers = new Dictionary<Type, object>()
- {
- { typeof(CacheControlHeaderValue), new Func<string, CacheControlHeaderValue?>(value => { return CacheControlHeaderValue.TryParse(value, out var result) ? result : null; }) },
- { typeof(ContentDispositionHeaderValue), new Func<string, ContentDispositionHeaderValue?>(value => { return ContentDispositionHeaderValue.TryParse(value, out var result) ? result : null; }) },
- { typeof(ContentRangeHeaderValue), new Func<string, ContentRangeHeaderValue?>(value => { return ContentRangeHeaderValue.TryParse(value, out var result) ? result : null; }) },
- { typeof(MediaTypeHeaderValue), new Func<string, MediaTypeHeaderValue?>(value => { return MediaTypeHeaderValue.TryParse(value, out var result) ? result : null; }) },
- { typeof(RangeConditionHeaderValue), new Func<string, RangeConditionHeaderValue?>(value => { return RangeConditionHeaderValue.TryParse(value, out var result) ? result : null; }) },
- { typeof(RangeHeaderValue), new Func<string, RangeHeaderValue?>(value => { return RangeHeaderValue.TryParse(value, out var result) ? result : null; }) },
- { typeof(EntityTagHeaderValue), new Func<string, EntityTagHeaderValue?>(value => { return EntityTagHeaderValue.TryParse(value, out var result) ? result : null; }) },
- { typeof(DateTimeOffset?), new Func<string, DateTimeOffset?>(value => { return HeaderUtilities.TryParseDate(value, out var result) ? result : null; }) },
- { typeof(long?), new Func<string, long?>(value => { return HeaderUtilities.TryParseNonNegativeInt64(value, out var result) ? result : null; }) },
- };
-
- private static readonly IDictionary<Type, object> KnownListParsers = new Dictionary<Type, object>()
- {
- { typeof(MediaTypeHeaderValue), new Func<IList<string>, IList<MediaTypeHeaderValue>>(value => { return MediaTypeHeaderValue.TryParseList(value, out var result) ? result : Array.Empty<MediaTypeHeaderValue>(); }) },
- { typeof(StringWithQualityHeaderValue), new Func<IList<string>, IList<StringWithQualityHeaderValue>>(value => { return StringWithQualityHeaderValue.TryParseList(value, out var result) ? result : Array.Empty<StringWithQualityHeaderValue>(); }) },
- { typeof(CookieHeaderValue), new Func<IList<string>, IList<CookieHeaderValue>>(value => { return CookieHeaderValue.TryParseList(value, out var result) ? result : Array.Empty<CookieHeaderValue>(); }) },
- { typeof(EntityTagHeaderValue), new Func<IList<string>, IList<EntityTagHeaderValue>>(value => { return EntityTagHeaderValue.TryParseList(value, out var result) ? result : Array.Empty<EntityTagHeaderValue>(); }) },
- { typeof(SetCookieHeaderValue), new Func<IList<string>, IList<SetCookieHeaderValue>>(value => { return SetCookieHeaderValue.TryParseList(value, out var result) ? result : Array.Empty<SetCookieHeaderValue>(); }) },
- };
-
- internal static T? Get<T>(this IHeaderDictionary headers, string name)
+ private static readonly Dictionary<Type, object> KnownParsers = new()
+ {
+ { typeof(CacheControlHeaderValue), new Func<string, CacheControlHeaderValue?>(value => { return CacheControlHeaderValue.TryParse(value, out var result) ? result : null; }) },
+ { typeof(ContentDispositionHeaderValue), new Func<string, ContentDispositionHeaderValue?>(value => { return ContentDispositionHeaderValue.TryParse(value, out var result) ? result : null; }) },
+ { typeof(ContentRangeHeaderValue), new Func<string, ContentRangeHeaderValue?>(value => { return ContentRangeHeaderValue.TryParse(value, out var result) ? result : null; }) },
+ { typeof(MediaTypeHeaderValue), new Func<string, MediaTypeHeaderValue?>(value => { return MediaTypeHeaderValue.TryParse(value, out var result) ? result : null; }) },
+ { typeof(RangeConditionHeaderValue), new Func<string, RangeConditionHeaderValue?>(value => { return RangeConditionHeaderValue.TryParse(value, out var result) ? result : null; }) },
+ { typeof(RangeHeaderValue), new Func<string, RangeHeaderValue?>(value => { return RangeHeaderValue.TryParse(value, out var result) ? result : null; }) },
+ { typeof(EntityTagHeaderValue), new Func<string, EntityTagHeaderValue?>(value => { return EntityTagHeaderValue.TryParse(value, out var result) ? result : null; }) },
+ { typeof(DateTimeOffset?), new Func<string, DateTimeOffset?>(value => { return HeaderUtilities.TryParseDate(value, out var result) ? result : null; }) },
+ { typeof(long?), new Func<string, long?>(value => { return HeaderUtilities.TryParseNonNegativeInt64(value, out var result) ? result : null; }) },
+ };
+
+ private static readonly Dictionary<Type, object> KnownListParsers = new()
+ {
+ { typeof(MediaTypeHeaderValue), new Func<IList<string>, IList<MediaTypeHeaderValue>>(value => { return MediaTypeHeaderValue.TryParseList(value, out var result) ? result : Array.Empty<MediaTypeHeaderValue>(); }) },
+ { typeof(StringWithQualityHeaderValue), new Func<IList<string>, IList<StringWithQualityHeaderValue>>(value => { return StringWithQualityHeaderValue.TryParseList(value, out var result) ? result : Array.Empty<StringWithQualityHeaderValue>(); }) },
+ { typeof(CookieHeaderValue), new Func<IList<string>, IList<CookieHeaderValue>>(value => { return CookieHeaderValue.TryParseList(value, out var result) ? result : Array.Empty<CookieHeaderValue>(); }) },
+ { typeof(EntityTagHeaderValue), new Func<IList<string>, IList<EntityTagHeaderValue>>(value => { return EntityTagHeaderValue.TryParseList(value, out var result) ? result : Array.Empty<EntityTagHeaderValue>(); }) },
+ { typeof(SetCookieHeaderValue), new Func<IList<string>, IList<SetCookieHeaderValue>>(value => { return SetCookieHeaderValue.TryParseList(value, out var result) ? result : Array.Empty<SetCookieHeaderValue>(); }) },
+ };
+
+ internal static T? Get<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>(this IHeaderDictionary headers, string name)
{
if (headers == null)
{
@@ -211,7 +212,7 @@ public static class HeaderDictionaryTypeExtensions
return GetViaReflection<T>(value.ToString());
}
- internal static IList<T> GetList<T>(this IHeaderDictionary headers, string name)
+ internal static IList<T> GetList<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>(this IHeaderDictionary headers, string name)
{
if (headers == null)
{
@@ -223,7 +224,7 @@ public static class HeaderDictionaryTypeExtensions
return GetList<T>(values);
}
- internal static IList<T> GetList<T>(this StringValues values)
+ internal static IList<T> GetList<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>(this StringValues values)
{
if (StringValues.IsNullOrEmpty(values))
{
@@ -239,31 +240,32 @@ public static class HeaderDictionaryTypeExtensions
return GetListViaReflection<T>(values);
}
- private static T? GetViaReflection<T>(string value)
+ private static T? GetViaReflection<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>(string value)
{
// TODO: Cache the reflected type for later? Only if success?
var type = typeof(T);
- var method = type.GetMethods(BindingFlags.Public | BindingFlags.Static)
- .FirstOrDefault(methodInfo =>
+ MethodInfo? method = null;
+ foreach (var methodInfo in type.GetMethods(BindingFlags.Public | BindingFlags.Static))
+ {
+ if (string.Equals("TryParse", methodInfo.Name, StringComparison.Ordinal) &&
+ methodInfo.ReturnParameter.ParameterType.Equals(typeof(bool)))
{
- if (string.Equals("TryParse", methodInfo.Name, StringComparison.Ordinal)
- && methodInfo.ReturnParameter.ParameterType.Equals(typeof(bool)))
+ var methodParams = methodInfo.GetParameters();
+ if (methodParams.Length == 2
+ && methodParams[0].ParameterType.Equals(typeof(string))
+ && methodParams[1].IsOut
+ && methodParams[1].ParameterType.Equals(type.MakeByRefType()))
{
- var methodParams = methodInfo.GetParameters();
- return methodParams.Length == 2
- && methodParams[0].ParameterType.Equals(typeof(string))
- && methodParams[1].IsOut
- && methodParams[1].ParameterType.Equals(type.MakeByRefType());
+ method = methodInfo;
+ break;
}
- return false;
- });
+ }
+ }
- if (method == null)
+ if (method is null)
{
- throw new NotSupportedException(string.Format(
- CultureInfo.CurrentCulture,
- "The given type '{0}' does not have a TryParse method with the required signature 'public static bool TryParse(string, out {0}).",
- nameof(T)));
+ throw new NotSupportedException(
+ $"The given type '{typeof(T)}' does not have a TryParse method with the required signature 'public static bool TryParse(string, out {typeof(T)}).");
}
var parameters = new object?[] { value, null };
@@ -275,7 +277,7 @@ public static class HeaderDictionaryTypeExtensions
return default(T);
}
- private static IList<T> GetListViaReflection<T>(StringValues values)
+ private static IList<T> GetListViaReflection<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>(StringValues values)
{
// TODO: Cache the reflected type for later? Only if success?
var type = typeof(T);
diff --git a/src/Http/Http.Extensions/src/HttpRequestJsonExtensions.cs b/src/Http/Http.Extensions/src/HttpRequestJsonExtensions.cs
index 1dfc5e525a..a204e74c04 100644
--- a/src/Http/Http.Extensions/src/HttpRequestJsonExtensions.cs
+++ b/src/Http/Http.Extensions/src/HttpRequestJsonExtensions.cs
@@ -4,6 +4,8 @@
using System.Diagnostics.CodeAnalysis;
using System.Text;
using System.Text.Json;
+using System.Text.Json.Serialization;
+using System.Text.Json.Serialization.Metadata;
using Microsoft.AspNetCore.Http.Json;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
@@ -17,6 +19,9 @@ namespace Microsoft.AspNetCore.Http;
/// </summary>
public static class HttpRequestJsonExtensions
{
+ private const string RequiresUnreferencedCodeMessage = "JSON serialization and deserialization might require types that cannot be statically analyzed. " +
+ "Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.";
+
/// <summary>
/// Read JSON from the request and deserialize to the specified type.
/// If the request's content-type is not a known JSON type then an error will be thrown.
@@ -25,7 +30,7 @@ public static class HttpRequestJsonExtensions
/// <param name="request">The request to read from.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
/// <returns>The task object representing the asynchronous operation.</returns>
- [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")]
+ [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)]
public static ValueTask<TValue?> ReadFromJsonAsync<TValue>(
this HttpRequest request,
CancellationToken cancellationToken = default)
@@ -42,7 +47,7 @@ public static class HttpRequestJsonExtensions
/// <param name="options">The serializer options to use when deserializing the content.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
/// <returns>The task object representing the asynchronous operation.</returns>
- [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")]
+ [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)]
public static async ValueTask<TValue?> ReadFromJsonAsync<TValue>(
this HttpRequest request,
JsonSerializerOptions? options,
@@ -55,7 +60,7 @@ public static class HttpRequestJsonExtensions
if (!request.HasJsonContentType(out var charset))
{
- throw CreateContentTypeError(request);
+ ThrowContentTypeError(request);
}
options ??= ResolveSerializerOptions(request.HttpContext);
@@ -81,10 +86,51 @@ public static class HttpRequestJsonExtensions
/// If the request's content-type is not a known JSON type then an error will be thrown.
/// </summary>
/// <param name="request">The request to read from.</param>
+ /// <param name="jsonTypeInfo">Metadata about the type to convert.</param>
+ /// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
+ /// <returns>The deserialized value.</returns>
+#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
+ public static async ValueTask<TValue?> ReadFromJsonAsync<TValue>(
+#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
+ this HttpRequest request,
+ JsonTypeInfo<TValue> jsonTypeInfo,
+ CancellationToken cancellationToken = default)
+ {
+ if (request == null)
+ {
+ throw new ArgumentNullException(nameof(request));
+ }
+
+ if (!request.HasJsonContentType(out var charset))
+ {
+ ThrowContentTypeError(request);
+ }
+
+ var encoding = GetEncodingFromCharset(charset);
+ var (inputStream, usesTranscodingStream) = GetInputStream(request.HttpContext, encoding);
+
+ try
+ {
+ return await JsonSerializer.DeserializeAsync(inputStream, jsonTypeInfo, cancellationToken);
+ }
+ finally
+ {
+ if (usesTranscodingStream)
+ {
+ await inputStream.DisposeAsync();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Read JSON from the request and deserialize to the specified type.
+ /// If the request's content-type is not a known JSON type then an error will be thrown.
+ /// </summary>
+ /// <param name="request">The request to read from.</param>
/// <param name="type">The type of object to read.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
/// <returns>The task object representing the asynchronous operation.</returns>
- [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")]
+ [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)]
public static ValueTask<object?> ReadFromJsonAsync(
this HttpRequest request,
Type type,
@@ -102,7 +148,7 @@ public static class HttpRequestJsonExtensions
/// <param name="options">The serializer options use when deserializing the content.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
/// <returns>The task object representing the asynchronous operation.</returns>
- [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")]
+ [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)]
public static async ValueTask<object?> ReadFromJsonAsync(
this HttpRequest request,
Type type,
@@ -120,7 +166,7 @@ public static class HttpRequestJsonExtensions
if (!request.HasJsonContentType(out var charset))
{
- throw CreateContentTypeError(request);
+ ThrowContentTypeError(request);
}
options ??= ResolveSerializerOptions(request.HttpContext);
@@ -142,6 +188,59 @@ public static class HttpRequestJsonExtensions
}
/// <summary>
+ /// Read JSON from the request and deserialize to the specified type.
+ /// If the request's content-type is not a known JSON type then an error will be thrown.
+ /// </summary>
+ /// <param name="request">The request to read from.</param>
+ /// <param name="type">The type of object to read.</param>
+ /// <param name="context">A metadata provider for serializable types.</param>
+ /// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
+ /// <returns>The deserialized value.</returns>
+#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
+ public static async ValueTask<object?> ReadFromJsonAsync(
+#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
+ this HttpRequest request,
+ Type type,
+ JsonSerializerContext context,
+ CancellationToken cancellationToken = default)
+ {
+ if (request is null)
+ {
+ throw new ArgumentNullException(nameof(request));
+ }
+
+ if (type is null)
+ {
+ throw new ArgumentNullException(nameof(type));
+ }
+
+ if (context is null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ if (!request.HasJsonContentType(out var charset))
+ {
+ ThrowContentTypeError(request);
+ }
+
+ var encoding = GetEncodingFromCharset(charset);
+ var (inputStream, usesTranscodingStream) = GetInputStream(request.HttpContext, encoding);
+
+ try
+ {
+ return await JsonSerializer.DeserializeAsync(inputStream, type, context, cancellationToken);
+ }
+ finally
+ {
+ if (usesTranscodingStream)
+ {
+ await inputStream.DisposeAsync();
+ }
+ }
+ }
+
+ /// <summary>
/// Checks the Content-Type header for JSON types.
/// </summary>
/// <returns>true if the Content-Type header represents a JSON content type; otherwise, false.</returns>
@@ -187,9 +286,10 @@ public static class HttpRequestJsonExtensions
return httpContext.RequestServices?.GetService<IOptions<JsonOptions>>()?.Value?.SerializerOptions ?? JsonOptions.DefaultSerializerOptions;
}
- private static InvalidOperationException CreateContentTypeError(HttpRequest request)
+ [DoesNotReturn]
+ private static void ThrowContentTypeError(HttpRequest request)
{
- return new InvalidOperationException($"Unable to read the request as JSON because the request content type '{request.ContentType}' is not a known JSON content type.");
+ throw new InvalidOperationException($"Unable to read the request as JSON because the request content type '{request.ContentType}' is not a known JSON content type.");
}
private static (Stream inputStream, bool usesTranscodingStream) GetInputStream(HttpContext httpContext, Encoding? encoding)
diff --git a/src/Http/Http.Extensions/src/HttpResponseJsonExtensions.cs b/src/Http/Http.Extensions/src/HttpResponseJsonExtensions.cs
index 93fa3c1f50..cba3ae0acf 100644
--- a/src/Http/Http.Extensions/src/HttpResponseJsonExtensions.cs
+++ b/src/Http/Http.Extensions/src/HttpResponseJsonExtensions.cs
@@ -3,6 +3,8 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
+using System.Text.Json.Serialization;
+using System.Text.Json.Serialization.Metadata;
using Microsoft.AspNetCore.Http.Json;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
@@ -14,6 +16,9 @@ namespace Microsoft.AspNetCore.Http;
/// </summary>
public static partial class HttpResponseJsonExtensions
{
+ private const string RequiresUnreferencedCodeMessage = "JSON serialization and deserialization might require types that cannot be statically analyzed. " +
+ "Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.";
+
/// <summary>
/// Write the specified value as JSON to the response body. The response content-type will be set to
/// <c>application/json; charset=utf-8</c>.
@@ -23,13 +28,13 @@ public static partial class HttpResponseJsonExtensions
/// <param name="value">The value to write as JSON.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
/// <returns>The task object representing the asynchronous operation.</returns>
- [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")]
+ [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)]
public static Task WriteAsJsonAsync<TValue>(
this HttpResponse response,
TValue value,
CancellationToken cancellationToken = default)
{
- return response.WriteAsJsonAsync<TValue>(value, options: null, contentType: null, cancellationToken);
+ return response.WriteAsJsonAsync(value, options: null, contentType: null, cancellationToken);
}
/// <summary>
@@ -42,14 +47,14 @@ public static partial class HttpResponseJsonExtensions
/// <param name="options">The serializer options to use when serializing the value.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
/// <returns>The task object representing the asynchronous operation.</returns>
- [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")]
+ [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)]
public static Task WriteAsJsonAsync<TValue>(
this HttpResponse response,
TValue value,
JsonSerializerOptions? options,
CancellationToken cancellationToken = default)
{
- return response.WriteAsJsonAsync<TValue>(value, options, contentType: null, cancellationToken);
+ return response.WriteAsJsonAsync(value, options, contentType: null, cancellationToken);
}
/// <summary>
@@ -63,7 +68,7 @@ public static partial class HttpResponseJsonExtensions
/// <param name="contentType">The content-type to set on the response.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
/// <returns>The task object representing the asynchronous operation.</returns>
- [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")]
+ [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)]
public static Task WriteAsJsonAsync<TValue>(
this HttpResponse response,
TValue value,
@@ -79,15 +84,63 @@ public static partial class HttpResponseJsonExtensions
options ??= ResolveSerializerOptions(response.HttpContext);
response.ContentType = contentType ?? JsonConstants.JsonContentTypeWithCharset;
+
// if no user provided token, pass the RequestAborted token and ignore OperationCanceledException
if (!cancellationToken.CanBeCanceled)
{
- return WriteAsJsonAsyncSlow<TValue>(response.Body, value, options, response.HttpContext.RequestAborted);
+ return WriteAsJsonAsyncSlow(response.Body, value, options, response.HttpContext.RequestAborted);
}
- return JsonSerializer.SerializeAsync<TValue>(response.Body, value, options, cancellationToken);
+ return JsonSerializer.SerializeAsync(response.Body, value, options, cancellationToken);
}
+ /// <summary>
+ /// Write the specified value as JSON to the response body. The response content-type will be set to
+ /// the specified content-type.
+ /// </summary>
+ /// <typeparam name="TValue">The type of object to write.</typeparam>
+ /// <param name="response">The response to write JSON to.</param>
+ /// <param name="value">The value to write as JSON.</param>
+ /// <param name="jsonTypeInfo">Metadata about the type to convert.</param>
+ /// <param name="contentType">The content-type to set on the response.</param>
+ /// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
+ /// <returns>The task object representing the asynchronous operation.</returns>
+ [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)]
+#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
+ public static Task WriteAsJsonAsync<TValue>(
+#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
+ this HttpResponse response,
+ TValue value,
+ JsonTypeInfo<TValue> jsonTypeInfo,
+ string? contentType = default,
+ CancellationToken cancellationToken = default)
+ {
+ if (response == null)
+ {
+ throw new ArgumentNullException(nameof(response));
+ }
+
+ response.ContentType = contentType ?? JsonConstants.JsonContentTypeWithCharset;
+
+ // if no user provided token, pass the RequestAborted token and ignore OperationCanceledException
+ if (!cancellationToken.CanBeCanceled)
+ {
+ return WriteAsJsonAsyncSlow(response, value, jsonTypeInfo);
+ }
+
+ return JsonSerializer.SerializeAsync(response.Body, value, jsonTypeInfo, cancellationToken);
+
+ static async Task WriteAsJsonAsyncSlow(HttpResponse response, TValue value, JsonTypeInfo<TValue> jsonTypeInfo)
+ {
+ try
+ {
+ await JsonSerializer.SerializeAsync(response.Body, value, jsonTypeInfo, response.HttpContext.RequestAborted);
+ }
+ catch (OperationCanceledException) { }
+ }
+ }
+
+ [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)]
private static async Task WriteAsJsonAsyncSlow<TValue>(
Stream body,
TValue value,
@@ -96,7 +149,7 @@ public static partial class HttpResponseJsonExtensions
{
try
{
- await JsonSerializer.SerializeAsync<TValue>(body, value, options, cancellationToken);
+ await JsonSerializer.SerializeAsync(body, value, options, cancellationToken);
}
catch (OperationCanceledException) { }
}
@@ -110,7 +163,7 @@ public static partial class HttpResponseJsonExtensions
/// <param name="type">The type of object to write.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
/// <returns>The task object representing the asynchronous operation.</returns>
- [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")]
+ [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)]
public static Task WriteAsJsonAsync(
this HttpResponse response,
object? value,
@@ -130,7 +183,7 @@ public static partial class HttpResponseJsonExtensions
/// <param name="options">The serializer options to use when serializing the value.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
/// <returns>The task object representing the asynchronous operation.</returns>
- [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")]
+ [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)]
public static Task WriteAsJsonAsync(
this HttpResponse response,
object? value,
@@ -152,7 +205,7 @@ public static partial class HttpResponseJsonExtensions
/// <param name="contentType">The content-type to set on the response.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
/// <returns>The task object representing the asynchronous operation.</returns>
- [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")]
+ [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)]
public static Task WriteAsJsonAsync(
this HttpResponse response,
object? value,
@@ -183,6 +236,7 @@ public static partial class HttpResponseJsonExtensions
return JsonSerializer.SerializeAsync(response.Body, value, type, options, cancellationToken);
}
+ [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)]
private static async Task WriteAsJsonAsyncSlow(
Stream body,
object? value,
@@ -197,6 +251,62 @@ public static partial class HttpResponseJsonExtensions
catch (OperationCanceledException) { }
}
+ /// <summary>
+ /// Write the specified value as JSON to the response body. The response content-type will be set to
+ /// the specified content-type.
+ /// </summary>
+ /// <param name="response">The response to write JSON to.</param>
+ /// <param name="value">The value to write as JSON.</param>
+ /// <param name="type">The type of object to write.</param>
+ /// <param name="context">A metadata provider for serializable types.</param>
+ /// <param name="contentType">The content-type to set on the response.</param>
+ /// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
+ /// <returns>The task object representing the asynchronous operation.</returns>
+#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
+ public static Task WriteAsJsonAsync(
+#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
+ this HttpResponse response,
+ object? value,
+ Type type,
+ JsonSerializerContext context,
+ string? contentType = default,
+ CancellationToken cancellationToken = default)
+ {
+ if (response is null)
+ {
+ throw new ArgumentNullException(nameof(response));
+ }
+
+ if (type is null)
+ {
+ throw new ArgumentNullException(nameof(type));
+ }
+
+ if (context is null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ response.ContentType = contentType ?? JsonConstants.JsonContentTypeWithCharset;
+
+ // if no user provided token, pass the RequestAborted token and ignore OperationCanceledException
+ if (!cancellationToken.CanBeCanceled)
+ {
+ return WriteAsJsonAsyncSlow();
+ }
+
+ return JsonSerializer.SerializeAsync(response.Body, value, type, context, cancellationToken);
+
+ async Task WriteAsJsonAsyncSlow()
+ {
+ try
+ {
+ await JsonSerializer.SerializeAsync(response.Body, value, type, context, cancellationToken);
+ }
+ catch (OperationCanceledException) { }
+ }
+ }
+
private static JsonSerializerOptions ResolveSerializerOptions(HttpContext httpContext)
{
// Attempt to resolve options from DI then fallback to default options
diff --git a/src/Http/Http.Extensions/src/Microsoft.AspNetCore.Http.Extensions.csproj b/src/Http/Http.Extensions/src/Microsoft.AspNetCore.Http.Extensions.csproj
index 06c4e0bb5f..7ef0c2fb5e 100644
--- a/src/Http/Http.Extensions/src/Microsoft.AspNetCore.Http.Extensions.csproj
+++ b/src/Http/Http.Extensions/src/Microsoft.AspNetCore.Http.Extensions.csproj
@@ -7,7 +7,7 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>aspnetcore</PackageTags>
<IsPackable>false</IsPackable>
- <Nullable>enable</Nullable>
+ <Trimmable>true</Trimmable>
</PropertyGroup>
<ItemGroup>
diff --git a/src/Http/Http.Extensions/src/PublicAPI.Unshipped.txt b/src/Http/Http.Extensions/src/PublicAPI.Unshipped.txt
index f5825c4e84..ef7c55f866 100644
--- a/src/Http/Http.Extensions/src/PublicAPI.Unshipped.txt
+++ b/src/Http/Http.Extensions/src/PublicAPI.Unshipped.txt
@@ -2,6 +2,10 @@
Microsoft.AspNetCore.Http.RequestDelegateFactoryOptions.RouteHandlerFilterFactories.get -> System.Collections.Generic.IReadOnlyList<System.Func<Microsoft.AspNetCore.Http.RouteHandlerContext!, Microsoft.AspNetCore.Http.RouteHandlerFilterDelegate!, Microsoft.AspNetCore.Http.RouteHandlerFilterDelegate!>!>?
Microsoft.AspNetCore.Http.RequestDelegateFactoryOptions.RouteHandlerFilterFactories.init -> void
Microsoft.Extensions.DependencyInjection.RouteHandlerJsonServiceExtensions
+static Microsoft.AspNetCore.Http.HttpRequestJsonExtensions.ReadFromJsonAsync(this Microsoft.AspNetCore.Http.HttpRequest! request, System.Type! type, System.Text.Json.Serialization.JsonSerializerContext! context, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask<object?>
+static Microsoft.AspNetCore.Http.HttpRequestJsonExtensions.ReadFromJsonAsync<TValue>(this Microsoft.AspNetCore.Http.HttpRequest! request, System.Text.Json.Serialization.Metadata.JsonTypeInfo<TValue>! jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask<TValue?>
+static Microsoft.AspNetCore.Http.HttpResponseJsonExtensions.WriteAsJsonAsync(this Microsoft.AspNetCore.Http.HttpResponse! response, object? value, System.Type! type, System.Text.Json.Serialization.JsonSerializerContext! context, string? contentType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.Http.HttpResponseJsonExtensions.WriteAsJsonAsync<TValue>(this Microsoft.AspNetCore.Http.HttpResponse! response, TValue value, System.Text.Json.Serialization.Metadata.JsonTypeInfo<TValue>! jsonTypeInfo, string? contentType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
static Microsoft.Extensions.DependencyInjection.RouteHandlerJsonServiceExtensions.ConfigureRouteHandlerJsonOptions(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action<Microsoft.AspNetCore.Http.Json.JsonOptions!>! configureOptions) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
Microsoft.AspNetCore.Http.EndpointDescriptionAttribute
Microsoft.AspNetCore.Http.EndpointDescriptionAttribute.EndpointDescriptionAttribute(string! description) -> void
diff --git a/src/Http/Http.Extensions/src/RequestDelegateFactory.cs b/src/Http/Http.Extensions/src/RequestDelegateFactory.cs
index c32a6a7901..7c2fca4c74 100644
--- a/src/Http/Http.Extensions/src/RequestDelegateFactory.cs
+++ b/src/Http/Http.Extensions/src/RequestDelegateFactory.cs
@@ -2,11 +2,13 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO.Pipelines;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
+using System.Runtime.CompilerServices;
using System.Security.Claims;
using System.Text;
using System.Text.Json;
@@ -22,6 +24,11 @@ namespace Microsoft.AspNetCore.Http;
/// <summary>
/// Creates <see cref="RequestDelegate"/> implementations from <see cref="Delegate"/> request handlers.
/// </summary>
+[UnconditionalSuppressMessage("Trimmer", "IL2026", Justification = "RequestDelegateFactory.Create requires unreferenced code.")]
+[UnconditionalSuppressMessage("Trimmer", "IL2060", Justification = "RequestDelegateFactory.Create requires unreferenced code.")]
+[UnconditionalSuppressMessage("Trimmer", "IL2072", Justification = "RequestDelegateFactory.Create requires unreferenced code.")]
+[UnconditionalSuppressMessage("Trimmer", "IL2075", Justification = "RequestDelegateFactory.Create requires unreferenced code.")]
+[UnconditionalSuppressMessage("Trimmer", "IL2077", Justification = "RequestDelegateFactory.Create requires unreferenced code.")]
public static partial class RequestDelegateFactory
{
private static readonly ParameterBindingMethodCache ParameterBindingMethodCache = new();
@@ -96,9 +103,8 @@ public static partial class RequestDelegateFactory
/// <param name="handler">A request handler with any number of custom parameters that often produces a response with its return value.</param>
/// <param name="options">The <see cref="RequestDelegateFactoryOptions"/> used to configure the behavior of the handler.</param>
/// <returns>The <see cref="RequestDelegateResult"/>.</returns>
-#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
+ [RequiresUnreferencedCode("RequestDelegateFactory performs object creation, serialization and deserialization on the delegates and its parameters. This cannot be statically analyzed.")]
public static RequestDelegateResult Create(Delegate handler, RequestDelegateFactoryOptions? options = null)
-#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
{
if (handler is null)
{
@@ -125,9 +131,9 @@ public static partial class RequestDelegateFactory
/// <param name="targetFactory">Creates the <see langword="this"/> for the non-static method.</param>
/// <param name="options">The <see cref="RequestDelegateFactoryOptions"/> used to configure the behavior of the handler.</param>
/// <returns>The <see cref="RequestDelegate"/>.</returns>
-#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
+
+ [RequiresUnreferencedCode("RequestDelegateFactory performs object creation, serialization and deserialization on the delegates and its parameters. This cannot be statically analyzed.")]
public static RequestDelegateResult Create(MethodInfo methodInfo, Func<HttpContext, object>? targetFactory = null, RequestDelegateFactoryOptions? options = null)
-#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
{
if (methodInfo is null)
{
@@ -786,7 +792,7 @@ public static partial class RequestDelegateFactory
static async Task<(object? FormValue, bool Successful)> TryReadBodyAsync(
HttpContext httpContext,
- Type bodyType,
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type bodyType,
string parameterTypeName,
string parameterName,
bool allowEmptyRequestBody,
@@ -796,7 +802,7 @@ public static partial class RequestDelegateFactory
if (allowEmptyRequestBody && bodyType.IsValueType)
{
- defaultBodyValue = Activator.CreateInstance(bodyType);
+ defaultBodyValue = CreateValueType(bodyType);
}
var bodyValue = defaultBodyValue;
@@ -831,6 +837,10 @@ public static partial class RequestDelegateFactory
}
}
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2067:UnrecognizedReflectionPattern",
+ Justification = "CreateValueType is only called on a ValueType. You can always create an instance of a ValueType.")]
+ private static object? CreateValueType(Type t) => RuntimeHelpers.GetUninitializedObject(t);
+
private static Func<object?, HttpContext, Task> HandleRequestBodyAndCompileRequestDelegateForForm(
Expression responseWritingMethodCall,
FactoryContext factoryContext)
diff --git a/src/Http/Http.Extensions/src/RequestHeaders.cs b/src/Http/Http.Extensions/src/RequestHeaders.cs
index 2b86a3e5f3..d6f6cef97a 100644
--- a/src/Http/Http.Extensions/src/RequestHeaders.cs
+++ b/src/Http/Http.Extensions/src/RequestHeaders.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.Net.Http.Headers;
@@ -357,7 +358,7 @@ public class RequestHeaders
/// The given type must have a static TryParse method.</typeparam>
/// <param name="name">The name of the header to retrieve.</param>
/// <returns>The value of the header.</returns>
- public T? Get<T>(string name)
+ public T? Get<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>(string name)
{
return Headers.Get<T>(name);
}
@@ -370,7 +371,7 @@ public class RequestHeaders
/// The given type must have a static TryParseList method.</typeparam>
/// <param name="name">The name of the header to retrieve.</param>
/// <returns>List of values of the header.</returns>
- public IList<T> GetList<T>(string name)
+ public IList<T> GetList<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>(string name)
{
return Headers.GetList<T>(name);
}
diff --git a/src/Http/Http.Extensions/src/ResponseHeaders.cs b/src/Http/Http.Extensions/src/ResponseHeaders.cs
index 66f44542ae..74f13b8d7a 100644
--- a/src/Http/Http.Extensions/src/ResponseHeaders.cs
+++ b/src/Http/Http.Extensions/src/ResponseHeaders.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.Net.Http.Headers;
@@ -207,7 +208,7 @@ public class ResponseHeaders
/// The given type must have a static TryParse method.</typeparam>
/// <param name="name">The name of the header to retrieve.</param>
/// <returns>The value of the header.</returns>
- public T? Get<T>(string name)
+ public T? Get<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>(string name)
{
return Headers.Get<T>(name);
}
@@ -220,7 +221,7 @@ public class ResponseHeaders
/// The given type must have a static TryParseList method.</typeparam>
/// <param name="name">The name of the header to retrieve.</param>
/// <returns>List of values of the header.</returns>
- public IList<T> GetList<T>(string name)
+ public IList<T> GetList<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>(string name)
{
return Headers.GetList<T>(name);
}
diff --git a/src/Http/Routing.Abstractions/src/Microsoft.AspNetCore.Routing.Abstractions.csproj b/src/Http/Routing.Abstractions/src/Microsoft.AspNetCore.Routing.Abstractions.csproj
index db1aa002e8..2eb5ee4cf2 100644
--- a/src/Http/Routing.Abstractions/src/Microsoft.AspNetCore.Routing.Abstractions.csproj
+++ b/src/Http/Routing.Abstractions/src/Microsoft.AspNetCore.Routing.Abstractions.csproj
@@ -11,6 +11,7 @@ Microsoft.AspNetCore.Routing.RouteData</Description>
<PackageTags>aspnetcore;routing</PackageTags>
<IsPackable>false</IsPackable>
<Nullable>annotations</Nullable>
+ <Trimmable>true</Trimmable>
</PropertyGroup>
<ItemGroup>
diff --git a/src/Http/Routing/src/Builder/RouteHandlerFilterExtensions.cs b/src/Http/Routing/src/Builder/RouteHandlerFilterExtensions.cs
index fae8885ad2..f0032cc2bf 100644
--- a/src/Http/Routing/src/Builder/RouteHandlerFilterExtensions.cs
+++ b/src/Http/Routing/src/Builder/RouteHandlerFilterExtensions.cs
@@ -32,11 +32,26 @@ public static class RouteHandlerFilterExtensions
/// <returns>A <see cref="RouteHandlerBuilder"/> that can be used to further customize the route handler.</returns>
public static RouteHandlerBuilder AddFilter<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TFilterType>(this RouteHandlerBuilder builder) where TFilterType : IRouteHandlerFilter
{
- var filterFactory = ActivatorUtilities.CreateFactory(typeof(TFilterType), Type.EmptyTypes);
- builder.RouteHandlerFilterFactories.Add((routeHandlerContext, next) => (context) =>
+ // We call `CreateFactory` twice here since the `CreateFactory` API does not support optional arguments.
+ // See https://github.com/dotnet/runtime/issues/67309 for more info.
+ ObjectFactory filterFactory;
+ try
{
- var filter = (IRouteHandlerFilter)filterFactory.Invoke(context.HttpContext.RequestServices, Array.Empty<object>());
- return filter.InvokeAsync(context, next);
+ filterFactory = ActivatorUtilities.CreateFactory(typeof(TFilterType), new[] { typeof(RouteHandlerContext) });
+ }
+ catch (InvalidOperationException)
+ {
+ filterFactory = ActivatorUtilities.CreateFactory(typeof(TFilterType), Type.EmptyTypes);
+ }
+
+ builder.RouteHandlerFilterFactories.Add((routeHandlerContext, next) =>
+ {
+ var invokeArguments = new[] { routeHandlerContext };
+ return (context) =>
+ {
+ var filter = (IRouteHandlerFilter)filterFactory.Invoke(context.HttpContext.RequestServices, invokeArguments);
+ return filter.InvokeAsync(context, next);
+ };
});
return builder;
}
diff --git a/src/Http/Routing/test/UnitTests/Builder/RouteHandlerEndpointRouteBuilderExtensionsTest.cs b/src/Http/Routing/test/UnitTests/Builder/RouteHandlerEndpointRouteBuilderExtensionsTest.cs
index b9d4e58607..f5685ecbb1 100644
--- a/src/Http/Routing/test/UnitTests/Builder/RouteHandlerEndpointRouteBuilderExtensionsTest.cs
+++ b/src/Http/Routing/test/UnitTests/Builder/RouteHandlerEndpointRouteBuilderExtensionsTest.cs
@@ -850,7 +850,7 @@ public class RouteHandlerEndpointRouteBuilderExtensionsTest : LoggedTest
}
public static object[][] AddFiltersByClassData =
-{
+ {
new object[] { (Action<RouteHandlerBuilder>)((RouteHandlerBuilder builder) => builder.AddFilter(new IncrementArgFilter())) },
new object[] { (Action<RouteHandlerBuilder>)((RouteHandlerBuilder builder) => builder.AddFilter<IncrementArgFilter>()) }
};
@@ -948,7 +948,7 @@ public class RouteHandlerEndpointRouteBuilderExtensionsTest : LoggedTest
{
var builder = new DefaultEndpointRouteBuilder(new ApplicationBuilder(new ServiceCollection().BuildServiceProvider()));
- string? PrintLogger(HttpContext context) => $"loggerErrorIsEnabled: {context.Items["loggerErrorIsEnabled"]}";
+ string? PrintLogger(HttpContext context) => $"loggerErrorIsEnabled: {context.Items["loggerErrorIsEnabled"]}, parentName: {context.Items["parentName"]}";
var routeHandlerBuilder = builder.Map("/", PrintLogger);
routeHandlerBuilder.AddFilter<ServiceAccessingRouteHandlerFilter>();
@@ -969,21 +969,24 @@ public class RouteHandlerEndpointRouteBuilderExtensionsTest : LoggedTest
httpResponse.Body.Seek(0, SeekOrigin.Begin);
var streamReader = new StreamReader(httpResponse.Body);
var body = streamReader.ReadToEndAsync().Result;
- Assert.Equal("loggerErrorIsEnabled: True", body);
+ Assert.Equal("loggerErrorIsEnabled: True, parentName: RouteHandlerEndpointRouteBuilderExtensionsTest", body);
}
class ServiceAccessingRouteHandlerFilter : IRouteHandlerFilter
{
private ILogger _logger;
+ private RouteHandlerContext _routeHandlerContext;
- public ServiceAccessingRouteHandlerFilter(ILoggerFactory loggerFactory)
+ public ServiceAccessingRouteHandlerFilter(ILoggerFactory loggerFactory, RouteHandlerContext routeHandlerContext)
{
_logger = loggerFactory.CreateLogger<ServiceAccessingRouteHandlerFilter>();
+ _routeHandlerContext = routeHandlerContext;
}
public async ValueTask<object?> InvokeAsync(RouteHandlerInvocationContext context, RouteHandlerFilterDelegate next)
{
context.HttpContext.Items["loggerErrorIsEnabled"] = _logger.IsEnabled(LogLevel.Error);
+ context.HttpContext.Items["parentName"] = _routeHandlerContext.MethodInfo.DeclaringType?.Name;
return await next(context);
}
}
diff --git a/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj b/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj
index 47f13da796..e5c0ef0f56 100644
--- a/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj
+++ b/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj
@@ -22,6 +22,7 @@
</PropertyGroup>
<ItemGroup>
+ <Content Remove="@(Content)" />
<None Include="build\*" Pack="true" PackagePath="build\" />
<None Include="buildMultiTargeting\*" Pack="true" PackagePath="buildMultiTargeting\" />
<None Include="buildTransitive\*" Pack="true" PackagePath="buildTransitive\" />
diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/include.wxi b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/include.wxi
index c4992860a3..98ee8aeb34 100644
--- a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/include.wxi
+++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/include.wxi
@@ -2,6 +2,12 @@
<Include>
<?define DiscoverabilityKeyRoot = "SOFTWARE\Microsoft\IIS Extensions"?>
+
+ <!-- NativeMachine values match the expected values for image file machine constants
+ https://docs.microsoft.com/en-us/windows/win32/sysinfo/image-file-machine-constants -->
+ <?define NativeMachine_x86=332?>
+ <?define NativeMachine_x64=34404?>
+ <?define NativeMachine_arm64=43620?>
<?if $(var.Platform) = "x64"?>
<?define IsWin64 = yes ?>
diff --git a/src/Installers/Windows/WindowsHostingBundle/ANCM.wxs b/src/Installers/Windows/WindowsHostingBundle/ANCM.wxs
index b9ca54eb8f..4deeaed434 100644
--- a/src/Installers/Windows/WindowsHostingBundle/ANCM.wxs
+++ b/src/Installers/Windows/WindowsHostingBundle/ANCM.wxs
@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
+<?include ..\AspNetCoreModule-Setup\IIS-Setup\include.wxi ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
<Fragment>
<PackageGroup Id="PG_ANCM">
@@ -10,7 +11,7 @@
Compressed="yes"
Vital="yes"
Visible="no"
- InstallCondition="NOT VersionNT64 AND (VersionNT &gt;= v6.1) AND (IISCoreWebEngineInstalled_x86=1) AND (IISW3SVCInstalled_x86=1) AND (NOT OPT_NO_ANCM OR OPT_NO_ANCM=&quot;0&quot;)">
+ InstallCondition="(NativeMachine=&quot;$(var.NativeMachine_x86)&quot;) AND (IISCoreWebEngineInstalled_x86=1) AND (IISW3SVCInstalled_x86=1) AND (NOT OPT_NO_ANCM OR OPT_NO_ANCM=&quot;0&quot;)">
<MsiProperty Name="OPT_NO_SHARED_CONFIG_CHECK" Value="[OPT_NO_SHARED_CONFIG_CHECK]" />
</MsiPackage>
@@ -20,11 +21,22 @@
Compressed="yes"
Vital="yes"
Visible="no"
- InstallCondition="VersionNT64 AND (VersionNT64 &gt;= v6.1) AND (IISCoreWebEngineInstalled_x64=1) AND (IISW3SVCInstalled_x64=1) AND (NOT OPT_NO_ANCM OR OPT_NO_ANCM=&quot;0&quot;)">
+ InstallCondition="(NativeMachine=&quot;$(var.NativeMachine_x64)&quot;) AND (IISCoreWebEngineInstalled_x64=1) AND (IISW3SVCInstalled_x64=1) AND (NOT OPT_NO_ANCM OR OPT_NO_ANCM=&quot;0&quot;)">
<MsiProperty Name="OPT_NO_SHARED_CONFIG_CHECK" Value="[OPT_NO_SHARED_CONFIG_CHECK]" />
</MsiPackage>
+
+ <!-- OPT_NO_SHARED_CONFIG_CHECK could be unset at this point, which we explicitly treat as 'false' -->
+ <MsiPackage Id="AspNetCoreModuleV2_arm64" SourceFile="$(var.AspNetCoreModuleV2_arm64.TargetPath)"
+ Name="$(var.AspNetCoreModuleV2_arm64.TargetFileName)"
+ Compressed="yes"
+ Vital="yes"
+ Visible="no"
+ InstallCondition="(NativeMachine=&quot;$(var.NativeMachine_arm64)&quot;) AND (IISCoreWebEngineInstalled_x64=1) AND (IISW3SVCInstalled_x64=1) AND (NOT OPT_NO_ANCM OR OPT_NO_ANCM=&quot;0&quot;)">
+ <MsiProperty Name="OPT_NO_SHARED_CONFIG_CHECK" Value="[OPT_NO_SHARED_CONFIG_CHECK]" />
+ </MsiPackage>
+
</PackageGroup>
-
+
<util:RegistrySearch Id="IISCoreWebEngineInstalledSearch_x86"
Variable="IISCoreWebEngineInstalled_x86"
Root="HKLM"
diff --git a/src/Installers/Windows/WindowsHostingBundle/DotNetCore.wxs b/src/Installers/Windows/WindowsHostingBundle/DotNetCore.wxs
index 25e549b0de..73a80bdbb3 100644
--- a/src/Installers/Windows/WindowsHostingBundle/DotNetCore.wxs
+++ b/src/Installers/Windows/WindowsHostingBundle/DotNetCore.wxs
@@ -1,15 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
+<?include ..\AspNetCoreModule-Setup\IIS-Setup\include.wxi ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Fragment>
<PackageGroup Id="PG_DOTNET_REDIST_LTS_BUNDLE">
<RollbackBoundary Id="RB_DOTNET_REDIST_LTS_BUNDLE" />
<!-- OPT_NO_RUNTIME could be unset at this point, which we explicitly treat as 'false' -->
+ <ExePackage Id="DotNetRedistLts_arm64" SourceFile="$(var.DepsPath)\$(var.DotNetRedistLtsInstallerarm64)"
+ Name="$(var.DotNetRedistLtsInstallerarm64)"
+ Compressed="yes"
+ Vital="yes"
+ InstallCondition="(NativeMachine=&quot;$(var.NativeMachine_arm64)&quot;) AND (NOT OPT_NO_RUNTIME OR OPT_NO_RUNTIME=&quot;0&quot;)"
+ InstallCommand="/quiet /norestart"
+ RepairCommand="/quiet /repair"
+ Permanent="yes"
+ DetectCondition="DotNetRedistLtsProductVersion_arm64 = v$(var.DotNetRedistLtsInstallerProductVersionarm64)">
+ </ExePackage>
+
+ <!-- OPT_NO_RUNTIME could be unset at this point, which we explicitly treat as 'false' -->
<ExePackage Id="DotNetRedistLts_x64" SourceFile="$(var.DepsPath)\$(var.DotNetRedistLtsInstallerx64)"
Name="$(var.DotNetRedistLtsInstallerx64)"
Compressed="yes"
Vital="yes"
- InstallCondition="VersionNT64 AND (NOT OPT_NO_RUNTIME OR OPT_NO_RUNTIME=&quot;0&quot;)"
+ InstallCondition="(NativeMachine=&quot;$(var.NativeMachine_x64)&quot;) AND (NOT OPT_NO_RUNTIME OR OPT_NO_RUNTIME=&quot;0&quot;)"
InstallCommand="/quiet /norestart"
RepairCommand="/quiet /repair"
Permanent="yes"
@@ -32,15 +45,22 @@
<Fragment>
<util:ProductSearch Id="DotNetRedistLtsProductSearch_x86"
- Condition="NOT VersionNT64"
+ Condition="(NativeMachine=&quot;$(var.NativeMachine_x86)&quot;)"
ProductCode="$(var.DotNetRedistLtsInstallerProductCodex86)"
Result="version"
Variable="DotNetRedistLtsProductVersion_x86" />
<util:ProductSearch Id="DotNetRedistLtsProductSearch_x64"
- Condition="VersionNT64"
+ Condition="(NativeMachine=&quot;$(var.NativeMachine_x64)&quot;)"
ProductCode="$(var.DotNetRedistLtsInstallerProductCodex64)"
Result="version"
Variable="DotNetRedistLtsProductVersion_x64" />
+
+ <util:ProductSearch Id="DotNetRedistLtsProductSearch_arm64"
+ Condition="(NativeMachine=&quot;$(var.NativeMachine_arm64)&quot;)"
+ ProductCode="$(var.DotNetRedistLtsInstallerProductCodearm64)"
+ Result="version"
+ Variable="DotNetRedistLtsProductVersion_arm64" />
+
</Fragment>
</Wix>
diff --git a/src/Installers/Windows/WindowsHostingBundle/Product.targets b/src/Installers/Windows/WindowsHostingBundle/Product.targets
index e446b9f5df..dab4141773 100644
--- a/src/Installers/Windows/WindowsHostingBundle/Product.targets
+++ b/src/Installers/Windows/WindowsHostingBundle/Product.targets
@@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
- <Platforms Include="x64;x86" />
+ <Platforms Include="x64;x86;arm64" />
<RuntimeInstallers Include="$(DepsPath)dotnet-runtime-$(MicrosoftNETCoreAppRuntimeVersion)-win-x64.exe">
<TargetPlatform>x64</TargetPlatform>
<BundleNameProperty>DotNetRedistLtsInstallerx64</BundleNameProperty>
@@ -18,6 +18,11 @@
<BundleNameProperty>DotNetRedistLtsInstallerx86</BundleNameProperty>
<Version>$(MicrosoftNETCoreAppRuntimeVersion)</Version>
</RuntimeInstallers>
+ <RuntimeInstallers Include="$(DepsPath)dotnet-runtime-$(MicrosoftNETCoreAppRuntimeVersion)-win-arm64.exe">
+ <TargetPlatform>arm64</TargetPlatform>
+ <BundleNameProperty>DotNetRedistLtsInstallerarm64</BundleNameProperty>
+ <Version>$(MicrosoftNETCoreAppRuntimeVersion)</Version>
+ </RuntimeInstallers>
</ItemGroup>
<Target Name="FetchDependencies" BeforeTargets="Restore;CollectPackageReferences">
@@ -36,6 +41,9 @@
<RemoteAsset Include="Runtime/$(MicrosoftNETCoreBrowserDebugHostTransportVersion)/dotnet-runtime-$(MicrosoftNETCoreAppRuntimeVersion)-win-x86.exe">
<TargetFileName>dotnet-runtime-$(MicrosoftNETCoreAppRuntimeVersion)-win-x86.exe</TargetFileName>
</RemoteAsset>
+ <RemoteAsset Include="Runtime/$(MicrosoftNETCoreBrowserDebugHostTransportVersion)/dotnet-runtime-$(MicrosoftNETCoreAppRuntimeVersion)-win-arm64.exe">
+ <TargetFileName>dotnet-runtime-$(MicrosoftNETCoreAppRuntimeVersion)-win-arm64.exe</TargetFileName>
+ </RemoteAsset>
</ItemGroup>
<MakeDir Directories="$(DepsPath)" />
@@ -86,6 +94,10 @@
<DefineConstants>$(DefineConstants);DotNetRedistLtsInstallerProductVersionx86=$(DotNetRedistLtsInstallerProductVersionx86)</DefineConstants>
<DefineConstants>$(DefineConstants);DotNetRedistLtsInstallerProductCodex86=$(DotNetRedistLtsInstallerProductCodex86)</DefineConstants>
<DefineConstants>$(DefineConstants);DotNetRedistLtsInstallerUpgradeCodex86=$(DotNetRedistLtsInstallerUpgradeCodex86)</DefineConstants>
+ <DefineConstants>$(DefineConstants);DotNetRedistLtsInstallerarm64=$(DotNetRedistLtsInstallerarm64)</DefineConstants>
+ <DefineConstants>$(DefineConstants);DotNetRedistLtsInstallerProductVersionarm64=$(DotNetRedistLtsInstallerProductVersionarm64)</DefineConstants>
+ <DefineConstants>$(DefineConstants);DotNetRedistLtsInstallerProductCodearm64=$(DotNetRedistLtsInstallerProductCodearm64)</DefineConstants>
+ <DefineConstants>$(DefineConstants);DotNetRedistLtsInstallerUpgradeCodearm64=$(DotNetRedistLtsInstallerUpgradeCodearm64)</DefineConstants>
</PropertyGroup>
</Target>
</Project>
diff --git a/src/Installers/Windows/WindowsHostingBundle/SharedFramework.wxs b/src/Installers/Windows/WindowsHostingBundle/SharedFramework.wxs
index c75b5eb362..79671beb84 100644
--- a/src/Installers/Windows/WindowsHostingBundle/SharedFramework.wxs
+++ b/src/Installers/Windows/WindowsHostingBundle/SharedFramework.wxs
@@ -1,15 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
+<?include ..\AspNetCoreModule-Setup\IIS-Setup\include.wxi ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Fragment>
<PackageGroup Id="PG_SHAREDFX_REDIST_BUNDLE">
<RollbackBoundary Id="RB_SHAREDFX_REDIST_BUNDLE" />
<!-- OPT_NO_SHAREDFX could be unset at this point, which we explicitly treat as 'false' -->
+ <ExePackage Id="SharedFxRedist_arm64" SourceFile="$(var.InstallersOutputPath)\$(var.SharedFxRedistInstallerarm64)"
+ Name="$(var.SharedFxRedistInstallerarm64)"
+ Compressed="yes"
+ Vital="yes"
+ InstallCondition="(NativeMachine=&quot;$(var.NativeMachine_arm64)&quot;) AND (NOT OPT_NO_SHAREDFX OR OPT_NO_SHAREDFX=&quot;0&quot;)"
+ InstallCommand="/quiet /norestart"
+ RepairCommand="/quiet /repair"
+ Permanent="yes"
+ DetectCondition="SharedFxRedistProductVersion_arm64 = v$(var.SharedFxInstallerProductVersionarm64)">
+ </ExePackage>
+
+ <!-- OPT_NO_SHAREDFX could be unset at this point, which we explicitly treat as 'false' -->
<ExePackage Id="SharedFxRedist_x64" SourceFile="$(var.InstallersOutputPath)\$(var.SharedFxRedistInstallerx64)"
Name="$(var.SharedFxRedistInstallerx64)"
Compressed="yes"
Vital="yes"
- InstallCondition="VersionNT64 AND (NOT OPT_NO_SHAREDFX OR OPT_NO_SHAREDFX=&quot;0&quot;)"
+ InstallCondition="(NativeMachine=&quot;$(var.NativeMachine_x64)&quot;) AND (NOT OPT_NO_SHAREDFX OR OPT_NO_SHAREDFX=&quot;0&quot;)"
InstallCommand="/quiet /norestart"
RepairCommand="/quiet /repair"
Permanent="yes"
@@ -27,20 +40,27 @@
Permanent="yes"
DetectCondition="SharedFxRedistProductVersion_x86 = v$(var.SharedFxInstallerProductVersionx86)">
</ExePackage>
+
</PackageGroup>
</Fragment>
<Fragment>
<util:ProductSearch Id="SharedFxRedistProductSearch_x86"
- Condition="NOT VersionNT64"
+ Condition="(NativeMachine=&quot;$(var.NativeMachine_x86)&quot;)"
ProductCode="$(var.SharedFxInstallerProductCodex86)"
Result="version"
Variable="SharedFxRedistProductVersion_x86" />
<util:ProductSearch Id="SharedFxRedistProductSearch_x64"
- Condition="VersionNT64"
+ Condition="(NativeMachine=&quot;$(var.NativeMachine_x64)&quot;)"
ProductCode="$(var.SharedFxInstallerProductCodex64)"
Result="version"
Variable="SharedFxRedistProductVersion_x64" />
+
+ <util:ProductSearch Id="SharedFxRedistProductSearch_arm64"
+ Condition="(NativeMachine=&quot;$(var.NativeMachine_arm64)&quot;)"
+ ProductCode="$(var.SharedFxInstallerProductCodearm64)"
+ Result="version"
+ Variable="SharedFxRedistProductVersion_arm64" />
</Fragment>
</Wix>
diff --git a/src/Installers/Windows/WindowsHostingBundle/WindowsHostingBundle.wixproj b/src/Installers/Windows/WindowsHostingBundle/WindowsHostingBundle.wixproj
index 2884081b78..e7c9da7d2b 100644
--- a/src/Installers/Windows/WindowsHostingBundle/WindowsHostingBundle.wixproj
+++ b/src/Installers/Windows/WindowsHostingBundle/WindowsHostingBundle.wixproj
@@ -54,6 +54,13 @@
<Private>True</Private>
<DoNotHarvest>true</DoNotHarvest>
</ProjectReference>
+ <ProjectReference Include="..\AspNetCoreModule-Setup\ANCMV2\ANCMV2.wixproj">
+ <SetPlatform>Platform=arm64</SetPlatform>
+ <Name>AspNetCoreModuleV2_arm64</Name>
+ <Project>f9bacb48-3bd7-4ec2-ae31-664e8703ec12</Project>
+ <Private>True</Private>
+ <DoNotHarvest>true</DoNotHarvest>
+ </ProjectReference>
<ProjectReference Include="..\SharedFrameworkBundle\SharedFrameworkBundle.wixproj"
Private="false"
ReferenceOutputAssembly="false"
@@ -107,6 +114,11 @@
<BundleNameProperty>SharedFxRedistInstallerx86</BundleNameProperty>
<Version>$(SharedFxPackageVersion)</Version>
</SharedFxInstallers>
+ <SharedFxInstallers Include="$(InstallersOutputPath)$(RuntimeInstallerBaseName)-$(SharedFxPackageVersion)-win-arm64.exe">
+ <TargetPlatform>arm64</TargetPlatform>
+ <BundleNameProperty>SharedFxRedistInstallerarm64</BundleNameProperty>
+ <Version>$(SharedFxPackageVersion)</Version>
+ </SharedFxInstallers>
</ItemGroup>
<PropertyGroup>
@@ -137,6 +149,10 @@
<ProductVersionProperty>SharedFxInstallerProductVersionx86</ProductVersionProperty>
<ProductCodeProperty>SharedFxInstallerProductCodex86</ProductCodeProperty>
</SharedFxPayload>
+ <SharedFxPayload Include="$(InstallersOutputPath)$(RuntimeInstallerBaseName)-$(SharedFxMsiVersion)-win-arm64.msi">
+ <ProductVersionProperty>SharedFxInstallerProductVersionarm64</ProductVersionProperty>
+ <ProductCodeProperty>SharedFxInstallerProductCodearm64</ProductCodeProperty>
+ </SharedFxPayload>
</ItemGroup>
<!-- Read MSI properties -->
@@ -154,6 +170,9 @@
<DefineConstants>$(DefineConstants);SharedFxRedistInstallerx86=$(SharedFxRedistInstallerx86)</DefineConstants>
<DefineConstants>$(DefineConstants);SharedFxInstallerProductVersionx86=$(SharedFxInstallerProductVersionx86)</DefineConstants>
<DefineConstants>$(DefineConstants);SharedFxInstallerProductCodex86=$(SharedFxInstallerProductCodex86)</DefineConstants>
+ <DefineConstants>$(DefineConstants);SharedFxRedistInstallerarm64=$(SharedFxRedistInstallerarm64)</DefineConstants>
+ <DefineConstants>$(DefineConstants);SharedFxInstallerProductVersionarm64=$(SharedFxInstallerProductVersionarm64)</DefineConstants>
+ <DefineConstants>$(DefineConstants);SharedFxInstallerProductCodearm64=$(SharedFxInstallerProductCodearm64)</DefineConstants>
</PropertyGroup>
</Target>
</Project>
diff --git a/src/JSInterop/Microsoft.JSInterop/src/Infrastructure/DotNetDispatcher.cs b/src/JSInterop/Microsoft.JSInterop/src/Infrastructure/DotNetDispatcher.cs
index 2f591b67f8..46a77c390e 100644
--- a/src/JSInterop/Microsoft.JSInterop/src/Infrastructure/DotNetDispatcher.cs
+++ b/src/JSInterop/Microsoft.JSInterop/src/Infrastructure/DotNetDispatcher.cs
@@ -10,6 +10,7 @@ using System.Reflection.Metadata;
using System.Runtime.ExceptionServices;
using System.Text;
using System.Text.Json;
+using Microsoft.AspNetCore.Internal;
[assembly: MetadataUpdateHandler(typeof(Microsoft.JSInterop.Infrastructure.DotNetDispatcher))]
@@ -22,12 +23,17 @@ namespace Microsoft.JSInterop.Infrastructure;
public static class DotNetDispatcher
{
private const string DisposeDotNetObjectReferenceMethodName = "__Dispose";
+
internal static readonly JsonEncodedText DotNetObjectRefKey = JsonEncodedText.Encode("__dotNetObject");
private static readonly ConcurrentDictionary<AssemblyKey, IReadOnlyDictionary<string, (MethodInfo, Type[])>> _cachedMethodsByAssembly = new();
private static readonly ConcurrentDictionary<Type, IReadOnlyDictionary<string, (MethodInfo, Type[])>> _cachedMethodsByType = new();
+ private static readonly ConcurrentDictionary<Type, Func<object, Task>> _cachedConvertToTaskByType = new();
+
+ private static readonly MethodInfo _taskConverterMethodInfo = typeof(DotNetDispatcher).GetMethod(nameof(CreateValueTaskConverter), BindingFlags.NonPublic | BindingFlags.Static)!;
+
/// <summary>
/// Receives a call from JS to .NET, locating and invoking the specified method.
/// </summary>
@@ -108,6 +114,19 @@ public static class DotNetDispatcher
// Returned a task - we need to continue that task and then report an exception
// or return the value.
task.ContinueWith(t => EndInvokeDotNetAfterTask(t, jsRuntime, invocationInfo), TaskScheduler.Current);
+
+ }
+ else if(syncResult is ValueTask valueTaskResult)
+ {
+ valueTaskResult.AsTask().ContinueWith(t => EndInvokeDotNetAfterTask(t, jsRuntime, invocationInfo), TaskScheduler.Current);
+ }
+ else if (syncResult?.GetType() is { IsGenericType: true } syncResultType
+ && syncResultType.GetGenericTypeDefinition() == typeof(ValueTask<>))
+ {
+ // It's a ValueTask<T>. We'll coerce it to a Task so that we can attach a continuation.
+ var innerTask = GetTaskByType(syncResultType.GenericTypeArguments[0], syncResult);
+
+ innerTask!.ContinueWith(t => EndInvokeDotNetAfterTask(t, jsRuntime, invocationInfo), TaskScheduler.Current);
}
else
{
@@ -348,6 +367,20 @@ public static class DotNetDispatcher
}
}
+ [UnconditionalSuppressMessage(
+ "ReflectionAnalysis",
+ "IL2060:MakeGenericMethod",
+ Justification = "https://github.com/mono/linker/issues/1727")]
+ private static Task GetTaskByType(Type type, object obj)
+ {
+ var converterDelegate = _cachedConvertToTaskByType.GetOrAdd(type, (Type t, MethodInfo taskConverterMethodInfo) =>
+ taskConverterMethodInfo.MakeGenericMethod(t).CreateDelegate<Func<object, Task>>(), _taskConverterMethodInfo);
+
+ return converterDelegate.Invoke(obj);
+ }
+
+ private static Task CreateValueTaskConverter<[DynamicallyAccessedMembers(LinkerFlags.JsonSerialized)] T>(object result) => ((ValueTask<T>)result).AsTask();
+
private static (MethodInfo methodInfo, Type[] parameterTypes) GetCachedMethodInfo(IDotNetObjectReference objectReference, string methodIdentifier)
{
var type = objectReference.Value.GetType();
@@ -470,6 +503,7 @@ public static class DotNetDispatcher
{
_cachedMethodsByAssembly.Clear();
_cachedMethodsByType.Clear();
+ _cachedConvertToTaskByType.Clear();
}
private readonly struct AssemblyKey : IEquatable<AssemblyKey>
diff --git a/src/JSInterop/Microsoft.JSInterop/src/Microsoft.JSInterop.WarningSuppressions.xml b/src/JSInterop/Microsoft.JSInterop/src/Microsoft.JSInterop.WarningSuppressions.xml
index a1c7043de5..6306606df5 100644
--- a/src/JSInterop/Microsoft.JSInterop/src/Microsoft.JSInterop.WarningSuppressions.xml
+++ b/src/JSInterop/Microsoft.JSInterop/src/Microsoft.JSInterop.WarningSuppressions.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<linker>
<assembly fullname="Microsoft.JSInterop, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60">
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
@@ -39,6 +39,12 @@
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
+ <argument>IL2060</argument>
+ <property name="Scope">member</property>
+ <property name="Target">M:Microsoft.JSInterop.Infrastructure.DotNetDispatcher.&lt;&gt;c.&lt;GetTaskByType&gt;b__14_0(System.Type,System.Reflection.MethodInfo)</property>
+ </attribute>
+ <attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
+ <argument>ILLink</argument>
<argument>IL2065</argument>
<property name="Scope">member</property>
<property name="Target">M:Microsoft.JSInterop.Infrastructure.DotNetDispatcher.ScanAssemblyForCallableMethods(Microsoft.JSInterop.Infrastructure.DotNetDispatcher.AssemblyKey)</property>
@@ -62,4 +68,4 @@
<property name="Target">M:Microsoft.JSInterop.JSRuntimeExtensions.&lt;InvokeAsync&gt;d__4`1.MoveNext</property>
</attribute>
</assembly>
-</linker> \ No newline at end of file
+</linker>
diff --git a/src/JSInterop/Microsoft.JSInterop/test/Infrastructure/DotNetDispatcherTest.cs b/src/JSInterop/Microsoft.JSInterop/test/Infrastructure/DotNetDispatcherTest.cs
index 53ef5fd389..6dfd73d51c 100644
--- a/src/JSInterop/Microsoft.JSInterop/test/Infrastructure/DotNetDispatcherTest.cs
+++ b/src/JSInterop/Microsoft.JSInterop/test/Infrastructure/DotNetDispatcherTest.cs
@@ -609,6 +609,60 @@ public class DotNetDispatcherTest
Assert.Equal(2468, resultDto2.IntVal);
}
+ [Fact]
+ public async Task CanInvokeAsyncMethodReturningValueTask()
+ {
+ // Arrange: Track some instance plus another object we'll pass as a param
+ var jsRuntime = new TestJSRuntime();
+ var targetInstance = new SomePublicType();
+ var arg2 = new TestDTO { IntVal = 1234, StringVal = "My string" };
+ var arg1Ref = DotNetObjectReference.Create(targetInstance);
+ var arg2Ref = DotNetObjectReference.Create(arg2);
+ jsRuntime.Invoke<object>("unimportant", arg1Ref, arg2Ref);
+
+ // Arrange: all args
+ var argsJson = JsonSerializer.Serialize(new object[]
+ {
+ new TestDTO { IntVal = 1000, StringVal = "String via JSON" },
+ arg2Ref,
+ }, jsRuntime.JsonSerializerOptions);
+
+ // Act
+ var callId = "123";
+ var resultTask = jsRuntime.NextInvocationTask;
+ DotNetDispatcher.BeginInvokeDotNet(jsRuntime, new DotNetInvocationInfo(null,
+ nameof(SomePublicType.InvokableAsyncMethodReturningValueTask), 1, callId), argsJson);
+ await resultTask;
+
+ // Assert: Correct completion information
+ Assert.Equal(callId, jsRuntime.LastCompletionCallId);
+ Assert.True(jsRuntime.LastCompletionResult.Success);
+ }
+
+ [Fact]
+ public async Task CanInvokeAsyncMethodReturningNonGenericValueTask()
+ {
+ // Arrange: Track some instance plus another object we'll pass as a param
+ var jsRuntime = new TestJSRuntime();
+ var targetInstance = new SomePublicType();
+ var arg1Ref = DotNetObjectReference.Create(targetInstance);
+ jsRuntime.Invoke<object>("unimportant", arg1Ref);
+
+ // Arrange: all args
+ var argsJson = JsonSerializer.Serialize(new object[] { }, jsRuntime.JsonSerializerOptions);
+
+ // Act
+ var callId = "123";
+ var resultTask = jsRuntime.NextInvocationTask;
+ DotNetDispatcher.BeginInvokeDotNet(jsRuntime, new DotNetInvocationInfo(null,
+ nameof(SomePublicType.InvokableAsyncMethodReturningValueTaskNonGeneric), 1, callId), argsJson);
+ await resultTask;
+
+ // Assert: Correct completion information
+ Assert.Equal(callId, jsRuntime.LastCompletionCallId);
+ Assert.True(jsRuntime.LastCompletionResult.Success);
+ }
+
[Fact]
public async Task CanInvokeSyncThrowingMethod()
{
@@ -878,6 +932,32 @@ public class DotNetDispatcherTest
};
}
+ [JSInvokable]
+ public async ValueTask<InvokableAsyncMethodResult> InvokableAsyncMethodReturningValueTask(TestDTO dtoViaJson, DotNetObjectReference<TestDTO> dtoByRefWrapper)
+ {
+ var dtoByRef = dtoByRefWrapper.Value;
+ return await new ValueTask<InvokableAsyncMethodResult>( new InvokableAsyncMethodResult()
+ {
+ SomeDTO = new TestDTO // Return via JSON
+ {
+ StringVal = dtoViaJson.StringVal.ToUpperInvariant(),
+ IntVal = dtoViaJson.IntVal * 2,
+ },
+ SomeDTORef = DotNetObjectReference.Create(new TestDTO // Return by ref
+ {
+ StringVal = dtoByRef.StringVal.ToUpperInvariant(),
+ IntVal = dtoByRef.IntVal * 2,
+ })
+ });
+ }
+
+ [JSInvokable]
+ public async ValueTask InvokableAsyncMethodReturningValueTaskNonGeneric()
+ {
+ await Task.CompletedTask;
+ return;
+ }
+
public class InvokableAsyncMethodResult
{
public TestDTO SomeDTO { get; set; }
diff --git a/src/Middleware/HttpLogging/src/W3CLoggerProcessor.cs b/src/Middleware/HttpLogging/src/W3CLoggerProcessor.cs
index cbd0f5247b..bee9b496f7 100644
--- a/src/Middleware/HttpLogging/src/W3CLoggerProcessor.cs
+++ b/src/Middleware/HttpLogging/src/W3CLoggerProcessor.cs
@@ -22,7 +22,7 @@ internal class W3CLoggerProcessor : FileLoggerProcessor
{
await WriteMessageAsync("#Version: 1.0", streamWriter, cancellationToken);
- await WriteMessageAsync("#Start-Date: " + DateTimeOffset.UtcNow.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture), streamWriter, cancellationToken);
+ await WriteMessageAsync("#Start-Date: " + DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture), streamWriter, cancellationToken);
await WriteMessageAsync(GetFieldsDirective(), streamWriter, cancellationToken);
}
diff --git a/src/Middleware/HttpLogging/test/W3CLoggerTests.cs b/src/Middleware/HttpLogging/test/W3CLoggerTests.cs
index 5478f4fd9c..d8d976caa3 100644
--- a/src/Middleware/HttpLogging/test/W3CLoggerTests.cs
+++ b/src/Middleware/HttpLogging/test/W3CLoggerTests.cs
@@ -39,7 +39,9 @@ public class W3CLoggerTests
Assert.StartsWith("#Start-Date: ", lines[1]);
var startDate = DateTime.Parse(lines[1].Substring(13), CultureInfo.InvariantCulture);
// Assert that the log was written in the last 10 seconds
- Assert.True(now.Subtract(startDate).TotalSeconds < 10);
+ // W3CLogger writes start-time to second precision, so delta could be as low as -0.999...
+ var delta = startDate.Subtract(now).TotalSeconds;
+ Assert.InRange(delta, -1, 10);
Assert.Equal("#Fields: date time", lines[2]);
@@ -80,7 +82,9 @@ public class W3CLoggerTests
Assert.StartsWith("#Start-Date: ", lines[1]);
var startDate = DateTime.Parse(lines[1].Substring(13), CultureInfo.InvariantCulture);
// Assert that the log was written in the last 10 seconds
- Assert.True(now.Subtract(startDate).TotalSeconds < 10);
+ // W3CLogger writes start-time to second precision, so delta could be as low as -0.999...
+ var delta = startDate.Subtract(now).TotalSeconds;
+ Assert.InRange(delta, -1, 10);
Assert.Equal("#Fields: cs-uri-query sc-status cs-host", lines[2]);
Assert.Equal("- - -", lines[3]);
diff --git a/src/Middleware/HttpLogging/test/W3CLoggingMiddlewareTests.cs b/src/Middleware/HttpLogging/test/W3CLoggingMiddlewareTests.cs
index 5146473998..9876620112 100644
--- a/src/Middleware/HttpLogging/test/W3CLoggingMiddlewareTests.cs
+++ b/src/Middleware/HttpLogging/test/W3CLoggingMiddlewareTests.cs
@@ -95,7 +95,9 @@ public class W3CLoggingMiddlewareTests
Assert.StartsWith("#Start-Date: ", lines[1]);
var startDate = DateTime.Parse(lines[1].Substring(13), CultureInfo.InvariantCulture);
// Assert that the log was written in the last 10 seconds
- Assert.True(now.Subtract(startDate).TotalSeconds < 10);
+ // W3CLogger writes start-time to second precision, so delta could be as low as -0.999...
+ var delta = startDate.Subtract(now).TotalSeconds;
+ Assert.InRange(delta, -1, 10);
Assert.Equal("#Fields: date time c-ip s-computername s-ip s-port cs-method cs-uri-stem cs-uri-query sc-status time-taken cs-version cs-host cs(User-Agent) cs(Referer)", lines[2]);
Assert.DoesNotContain(lines[3], "Snickerdoodle");
@@ -129,7 +131,9 @@ public class W3CLoggingMiddlewareTests
Assert.StartsWith("#Start-Date: ", lines[1]);
var startDate = DateTime.Parse(lines[1].Substring(13), CultureInfo.InvariantCulture);
// Assert that the log was written in the last 10 seconds
- Assert.True(now.Subtract(startDate).TotalSeconds < 10);
+ // W3CLogger writes start-time to second precision, so delta could be as low as -0.999...
+ var delta = startDate.Subtract(now).TotalSeconds;
+ Assert.InRange(delta, -1, 10);
Assert.Equal("#Fields: time-taken", lines[2]);
double num;
diff --git a/src/Mvc/Mvc.Testing/src/WebApplicationFactoryClientOptions.cs b/src/Mvc/Mvc.Testing/src/WebApplicationFactoryClientOptions.cs
index 4809eb44d1..177bb8ef5b 100644
--- a/src/Mvc/Mvc.Testing/src/WebApplicationFactoryClientOptions.cs
+++ b/src/Mvc/Mvc.Testing/src/WebApplicationFactoryClientOptions.cs
@@ -42,7 +42,7 @@ public class WebApplicationFactoryClientOptions
/// <see cref="WebApplicationFactory{TEntryPoint}.CreateClient(WebApplicationFactoryClientOptions)"/>
/// should automatically follow redirect responses.
/// The default is <c>true</c>.
- /// /// </summary>
+ /// </summary>
public bool AllowAutoRedirect { get; set; } = true;
/// <summary>
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/dotnetcli.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/dotnetcli.host.json
index 3c34f96f85..02abad32e7 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/dotnetcli.host.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/dotnetcli.host.json
@@ -85,6 +85,10 @@
"CallsMicrosoftGraph": {
"longName": "calls-graph",
"shortName": ""
+ },
+ "UseProgramMain": {
+ "longName": "use-program-main",
+ "shortName": ""
}
},
"usageExamples": [
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/ide.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/ide.host.json
index e891e5f2df..947fd0caa5 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/ide.host.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/ide.host.json
@@ -43,6 +43,12 @@
"useHttps": true
}
],
+ "symbolInfo": [
+ {
+ "id": "UseProgramMain",
+ "isVisible": true
+ }
+ ],
"disableHttpsSymbol": "NoHttps",
"supportsDocker": true
}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.cs.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.cs.json
index 0d63cde75a..93b827b9d7 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.cs.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.cs.json
@@ -34,6 +34,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.de.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.de.json
index 0d63cde75a..93b827b9d7 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.de.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.de.json
@@ -34,6 +34,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.en.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.en.json
index 0d63cde75a..24cfab2ca6 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.en.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.en.json
@@ -34,6 +34,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Do not use top-level statements",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.es.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.es.json
index 0d63cde75a..93b827b9d7 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.es.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.es.json
@@ -34,6 +34,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.fr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.fr.json
index 0d63cde75a..93b827b9d7 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.fr.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.fr.json
@@ -34,6 +34,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.it.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.it.json
index 0d63cde75a..93b827b9d7 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.it.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.it.json
@@ -34,6 +34,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.ja.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.ja.json
index 0d63cde75a..93b827b9d7 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.ja.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.ja.json
@@ -34,6 +34,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.ko.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.ko.json
index 0d63cde75a..93b827b9d7 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.ko.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.ko.json
@@ -34,6 +34,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.pl.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.pl.json
index 0d63cde75a..93b827b9d7 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.pl.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.pl.json
@@ -34,6 +34,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json
index 0d63cde75a..93b827b9d7 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json
@@ -34,6 +34,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.ru.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.ru.json
index 0d63cde75a..93b827b9d7 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.ru.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.ru.json
@@ -34,6 +34,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.tr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.tr.json
index 0d63cde75a..93b827b9d7 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.tr.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.tr.json
@@ -34,6 +34,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json
index 0d63cde75a..93b827b9d7 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json
@@ -34,6 +34,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json
index 0d63cde75a..93b827b9d7 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json
@@ -34,6 +34,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/template.json
index 864f81dae0..0189a641b7 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/template.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/template.json
@@ -35,6 +35,21 @@
],
"modifiers": [
{
+ "condition": "(!UseProgramMain)",
+ "exclude": [
+ "Program.Main.cs"
+ ]
+ },
+ {
+ "condition": "(UseProgramMain)",
+ "exclude": [
+ "Program.cs"
+ ],
+ "rename": {
+ "Program.Main.cs": "Program.cs"
+ }
+ },
+ {
"condition": "(!IndividualLocalAuth || UseLocalDB)",
"exclude": [
"app.db"
@@ -490,6 +505,13 @@
"datatype": "bool",
"description": "If specified, skips the automatic restore of the project on create.",
"defaultValue": "false"
+ },
+ "UseProgramMain": {
+ "type": "parameter",
+ "datatype": "bool",
+ "defaultValue": "false",
+ "displayName": "Do not use top-level statements",
+ "description": "Whether to generate an explicit Program class and Main method instead of top-level statements."
}
},
"primaryOutputs": [
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Program.Main.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Program.Main.cs
new file mode 100644
index 0000000000..92eb45d80a
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Program.Main.cs
@@ -0,0 +1,169 @@
+#if (OrganizationalAuth || IndividualB2CAuth)
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authentication.OpenIdConnect;
+using Microsoft.Identity.Web;
+using Microsoft.Identity.Web.UI;
+#endif
+#if (WindowsAuth)
+using Microsoft.AspNetCore.Authentication.Negotiate;
+#endif
+#if (OrganizationalAuth)
+#if (MultiOrgAuth)
+using Microsoft.AspNetCore.Authentication.OpenIdConnect;
+#endif
+using Microsoft.AspNetCore.Authorization;
+#endif
+using Microsoft.AspNetCore.Components;
+using Microsoft.AspNetCore.Components.Web;
+#if (IndividualLocalAuth)
+using Microsoft.AspNetCore.Components.Authorization;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Identity.UI;
+#endif
+#if (OrganizationalAuth)
+using Microsoft.AspNetCore.Mvc.Authorization;
+#endif
+#if (IndividualLocalAuth)
+using Microsoft.EntityFrameworkCore;
+#endif
+#if (GenerateGraph)
+using Graph = Microsoft.Graph;
+#endif
+#if(MultiOrgAuth)
+using Microsoft.IdentityModel.Tokens;
+#endif
+#if (IndividualLocalAuth)
+using BlazorServerWeb_CSharp.Areas.Identity;
+#endif
+using BlazorServerWeb_CSharp.Data;
+
+namespace Company.WebApplication1;
+
+public class Program
+{
+ public static void Main(string[] args)
+ {
+ var builder = WebApplication.CreateBuilder(args);
+
+ // Add services to the container.
+ #if (IndividualLocalAuth)
+ var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
+ builder.Services.AddDbContext<ApplicationDbContext>(options =>
+ #if (UseLocalDB)
+ options.UseSqlServer(connectionString));
+ #else
+ options.UseSqlite(connectionString));
+ #endif
+ builder.Services.AddDatabaseDeveloperPageExceptionFilter();
+ builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
+ .AddEntityFrameworkStores<ApplicationDbContext>();
+ #elif (OrganizationalAuth)
+ #if (GenerateApiOrGraph)
+ var initialScopes = builder.Configuration["DownstreamApi:Scopes"]?.Split(' ');
+
+ #endif
+ builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
+ #if (GenerateApiOrGraph)
+ .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
+ .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
+ #if (GenerateApi)
+ .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi"))
+ #endif
+ #if (GenerateGraph)
+ .AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi"))
+ #endif
+ .AddInMemoryTokenCaches();
+ #else
+ .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
+ #endif
+ #elif (IndividualB2CAuth)
+ #if (GenerateApi)
+ var initialScopes = builder.Configuration["DownstreamApi:Scopes"]?.Split(' ');
+
+ #endif
+ builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
+ #if (GenerateApi)
+ .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAdB2C"))
+ .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
+ .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi"))
+ .AddInMemoryTokenCaches();
+ #else
+ .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAdB2C"));
+ #endif
+ #endif
+ #if (OrganizationalAuth || IndividualB2CAuth)
+ builder.Services.AddControllersWithViews()
+ .AddMicrosoftIdentityUI();
+
+ builder.Services.AddAuthorization(options =>
+ {
+ // By default, all incoming requests will be authorized according to the default policy
+ options.FallbackPolicy = options.DefaultPolicy;
+ });
+
+ #elif (WindowsAuth)
+ builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
+ .AddNegotiate();
+
+ builder.Services.AddAuthorization(options =>
+ {
+ // By default, all incoming requests will be authorized according to the default policy.
+ options.FallbackPolicy = options.DefaultPolicy;
+ });
+
+ #endif
+ builder.Services.AddRazorPages();
+ #if (OrganizationalAuth || IndividualB2CAuth)
+ builder.Services.AddServerSideBlazor()
+ .AddMicrosoftIdentityConsentHandler();
+ #else
+ builder.Services.AddServerSideBlazor();
+ #endif
+ #if (IndividualLocalAuth)
+ builder.Services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();
+ #endif
+ builder.Services.AddSingleton<WeatherForecastService>();
+
+ var app = builder.Build();
+
+ // Configure the HTTP request pipeline.
+ #if (IndividualLocalAuth)
+ if (app.Environment.IsDevelopment())
+ {
+ app.UseMigrationsEndPoint();
+ }
+ else
+ #else
+ if (!app.Environment.IsDevelopment())
+ #endif
+ {
+ app.UseExceptionHandler("/Error");
+ #if (RequiresHttps)
+ // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
+ app.UseHsts();
+ }
+
+ app.UseHttpsRedirection();
+ #else
+ }
+
+ #endif
+
+ app.UseStaticFiles();
+
+ app.UseRouting();
+
+ #if (OrganizationalAuth || IndividualAuth || WindowsAuth)
+ app.UseAuthentication();
+ app.UseAuthorization();
+
+ #endif
+ #if (OrganizationalAuth || IndividualAuth)
+ app.MapControllers();
+ #endif
+ app.MapBlazorHub();
+ app.MapFallbackToPage("/_Host");
+
+ app.Run();
+ }
+} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Shared/NavMenu.CallsMicrosoftGraph.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Shared/NavMenu.CallsMicrosoftGraph.razor
index f1ff97d4b1..1841384590 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Shared/NavMenu.CallsMicrosoftGraph.razor
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Shared/NavMenu.CallsMicrosoftGraph.razor
@@ -26,7 +26,7 @@
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="showprofile">
- <span class="oi oi-list-rich" aria-hidden="true"></span> Show profile
+ <span class="oi oi-person" aria-hidden="true"></span> Show profile
</NavLink>
</div>
</nav>
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/dotnetcli.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/dotnetcli.host.json
index 93b2c5a3bc..3d2007dc58 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/dotnetcli.host.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/dotnetcli.host.json
@@ -95,6 +95,10 @@
"CallsMicrosoftGraph": {
"longName": "calls-graph",
"shortName": ""
+ },
+ "UseProgramMain": {
+ "longName": "use-program-main",
+ "shortName": ""
}
}
}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/ide.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/ide.host.json
index c48c26c9f4..e4ec39bc5e 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/ide.host.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/ide.host.json
@@ -41,6 +41,10 @@
{
"id": "PWA",
"isVisible": "true"
+ },
+ {
+ "id": "UseProgramMain",
+ "isVisible": true
}
]
}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.cs.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.cs.json
index 36d0c9f1e4..7e31298e01 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.cs.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.cs.json
@@ -36,6 +36,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'",
"postActions/restoreClient/description": "Restore NuGet packages required by this project.",
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.de.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.de.json
index 36d0c9f1e4..7e31298e01 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.de.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.de.json
@@ -36,6 +36,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'",
"postActions/restoreClient/description": "Restore NuGet packages required by this project.",
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.en.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.en.json
index 4cc52e7cdb..530197158d 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.en.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.en.json
@@ -36,6 +36,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
+ "symbols/UseProgramMain/displayName": "Do not use top-level statements",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'",
"postActions/restoreClient/description": "Restore NuGet packages required by this project.",
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.es.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.es.json
index 36d0c9f1e4..7e31298e01 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.es.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.es.json
@@ -36,6 +36,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'",
"postActions/restoreClient/description": "Restore NuGet packages required by this project.",
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.fr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.fr.json
index 36d0c9f1e4..7e31298e01 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.fr.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.fr.json
@@ -36,6 +36,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'",
"postActions/restoreClient/description": "Restore NuGet packages required by this project.",
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.it.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.it.json
index 36d0c9f1e4..7e31298e01 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.it.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.it.json
@@ -36,6 +36,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'",
"postActions/restoreClient/description": "Restore NuGet packages required by this project.",
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.ja.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.ja.json
index 36d0c9f1e4..7e31298e01 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.ja.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.ja.json
@@ -36,6 +36,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'",
"postActions/restoreClient/description": "Restore NuGet packages required by this project.",
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.ko.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.ko.json
index 36d0c9f1e4..7e31298e01 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.ko.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.ko.json
@@ -36,6 +36,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'",
"postActions/restoreClient/description": "Restore NuGet packages required by this project.",
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.pl.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.pl.json
index 36d0c9f1e4..7e31298e01 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.pl.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.pl.json
@@ -36,6 +36,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'",
"postActions/restoreClient/description": "Restore NuGet packages required by this project.",
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.pt-BR.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.pt-BR.json
index 36d0c9f1e4..7e31298e01 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.pt-BR.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.pt-BR.json
@@ -36,6 +36,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'",
"postActions/restoreClient/description": "Restore NuGet packages required by this project.",
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.ru.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.ru.json
index 36d0c9f1e4..7e31298e01 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.ru.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.ru.json
@@ -36,6 +36,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'",
"postActions/restoreClient/description": "Restore NuGet packages required by this project.",
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.tr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.tr.json
index 36d0c9f1e4..7e31298e01 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.tr.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.tr.json
@@ -36,6 +36,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'",
"postActions/restoreClient/description": "Restore NuGet packages required by this project.",
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.zh-Hans.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.zh-Hans.json
index 36d0c9f1e4..7e31298e01 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.zh-Hans.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.zh-Hans.json
@@ -36,6 +36,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'",
"postActions/restoreClient/description": "Restore NuGet packages required by this project.",
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.zh-Hant.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.zh-Hant.json
index 36d0c9f1e4..7e31298e01 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.zh-Hant.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/localize/templatestrings.zh-Hant.json
@@ -36,6 +36,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'",
"postActions/restoreClient/description": "Restore NuGet packages required by this project.",
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/template.json
index 84db26de74..101f868b87 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/template.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/template.json
@@ -95,6 +95,24 @@
]
},
{
+ "condition": "(!UseProgramMain)",
+ "exclude": [
+ "Server/Program.Main.cs",
+ "Client/Program.Main.cs"
+ ]
+ },
+ {
+ "condition": "(UseProgramMain)",
+ "exclude": [
+ "Server/Program.cs",
+ "Client/Program.cs"
+ ],
+ "rename": {
+ "Server/Program.Main.cs": "Server/Program.cs",
+ "Client/Program.Main.cs": "Client/Program.cs"
+ }
+ },
+ {
"condition": "(!IndividualLocalAuth || UseLocalDB)",
"exclude": [
"Server/app.db"
@@ -593,6 +611,13 @@
"GenerateApiOrGraph": {
"type": "computed",
"value": "(GenerateApi || GenerateGraph)"
+ },
+ "UseProgramMain": {
+ "type": "parameter",
+ "datatype": "bool",
+ "defaultValue": "false",
+ "displayName": "Do not use top-level statements",
+ "description": "Whether to generate an explicit Program class and Main method instead of top-level statements."
}
},
"tags": {
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/Program.Main.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/Program.Main.cs
new file mode 100644
index 0000000000..8b870e5dc9
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/Program.Main.cs
@@ -0,0 +1,69 @@
+using Microsoft.AspNetCore.Components.Web;
+#if (!NoAuth && Hosted)
+using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
+#endif
+using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
+#if (Hosted)
+using ComponentsWebAssembly_CSharp.Client;
+#else
+using ComponentsWebAssembly_CSharp;
+#endif
+
+namespace Company.WebApplication1;
+
+public class Program
+{
+ public static async Task Main(string[] args)
+ {
+ var builder = WebAssemblyHostBuilder.CreateDefault(args);
+ builder.RootComponents.Add<App>("#app");
+ builder.RootComponents.Add<HeadOutlet>("head::after");
+
+ #if (!Hosted || NoAuth)
+ builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
+ #else
+ builder.Services.AddHttpClient("ComponentsWebAssembly_CSharp.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
+ .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
+
+ // Supply HttpClient instances that include access tokens when making requests to the server project
+ builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("ComponentsWebAssembly_CSharp.ServerAPI"));
+ #endif
+ #if(!NoAuth)
+
+ #endif
+ #if (IndividualLocalAuth)
+ #if (Hosted)
+ builder.Services.AddApiAuthorization();
+ #else
+ builder.Services.AddOidcAuthentication(options =>
+ {
+ #if(MissingAuthority)
+ // Configure your authentication provider options here.
+ // For more information, see https://aka.ms/blazor-standalone-auth
+ #endif
+ builder.Configuration.Bind("Local", options.ProviderOptions);
+ });
+ #endif
+ #endif
+ #if (IndividualB2CAuth)
+ builder.Services.AddMsalAuthentication(options =>
+ {
+ builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication);
+ #if (Hosted)
+ options.ProviderOptions.DefaultAccessTokenScopes.Add("https://qualified.domain.name/api.id.uri/api-scope");
+ #endif
+ });
+ #endif
+ #if(OrganizationalAuth)
+ builder.Services.AddMsalAuthentication(options =>
+ {
+ builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
+ #if (Hosted)
+ options.ProviderOptions.DefaultAccessTokenScopes.Add("api://api.id.uri/api-scope");
+ #endif
+ });
+ #endif
+
+ await builder.Build().RunAsync();
+ }
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/Shared/NavMenu.CallsMicrosoftGraph.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/Shared/NavMenu.CallsMicrosoftGraph.razor
index bf3861b243..429950805b 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/Shared/NavMenu.CallsMicrosoftGraph.razor
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/Shared/NavMenu.CallsMicrosoftGraph.razor
@@ -26,7 +26,7 @@
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="showProfile">
- <span class="oi oi-list-rich" aria-hidden="true"></span> Show Profile
+ <span class="oi oi-person" aria-hidden="true"></span> Show Profile
</NavLink>
</div>
</nav>
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/wwwroot/sample-data/weather.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/wwwroot/sample-data/weather.json
index 06463c02f1..b7459733f9 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/wwwroot/sample-data/weather.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/wwwroot/sample-data/weather.json
@@ -1,26 +1,26 @@
[
{
- "date": "2018-05-06",
+ "date": "2022-01-06",
"temperatureC": 1,
"summary": "Freezing"
},
{
- "date": "2018-05-07",
+ "date": "2022-01-07",
"temperatureC": 14,
"summary": "Bracing"
},
{
- "date": "2018-05-08",
+ "date": "2022-01-08",
"temperatureC": -13,
"summary": "Freezing"
},
{
- "date": "2018-05-09",
+ "date": "2022-01-09",
"temperatureC": -16,
"summary": "Balmy"
},
{
- "date": "2018-05-10",
+ "date": "2022-01-10",
"temperatureC": -2,
"summary": "Chilly"
}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Program.Main.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Program.Main.cs
new file mode 100644
index 0000000000..31835439cd
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Program.Main.cs
@@ -0,0 +1,125 @@
+#if (OrganizationalAuth || IndividualB2CAuth || IndividualLocalAuth)
+using Microsoft.AspNetCore.Authentication;
+#endif
+#if (OrganizationalAuth || IndividualB2CAuth)
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+#endif
+using Microsoft.AspNetCore.ResponseCompression;
+#if (IndividualLocalAuth)
+using Microsoft.EntityFrameworkCore;
+#endif
+#if (GenerateGraph)
+using Graph = Microsoft.Graph;
+#endif
+#if (OrganizationalAuth || IndividualB2CAuth)
+using Microsoft.Identity.Web;
+#endif
+#if (IndividualLocalAuth)
+using ComponentsWebAssembly_CSharp.Server.Data;
+using ComponentsWebAssembly_CSharp.Server.Models;
+#endif
+
+namespace Company.WebApplication1;
+
+public class Program
+{
+ public static void Main(string[] args)
+ {
+ var builder = WebApplication.CreateBuilder(args);
+
+ // Add services to the container.
+ #if (IndividualLocalAuth)
+ var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
+ builder.Services.AddDbContext<ApplicationDbContext>(options =>
+ #if (UseLocalDB)
+ options.UseSqlServer(connectionString));
+ #else
+ options.UseSqlite(connectionString));
+ #endif
+ builder.Services.AddDatabaseDeveloperPageExceptionFilter();
+
+ builder.Services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
+ .AddEntityFrameworkStores<ApplicationDbContext>();
+
+ builder.Services.AddIdentityServer()
+ .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
+
+ builder.Services.AddAuthentication()
+ .AddIdentityServerJwt();
+ #endif
+ #if (OrganizationalAuth)
+ builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
+ #if (GenerateApiOrGraph)
+ .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"))
+ .EnableTokenAcquisitionToCallDownstreamApi()
+ #if (GenerateApi)
+ .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi"))
+ #endif
+ #if (GenerateGraph)
+ .AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi"))
+ #endif
+ .AddInMemoryTokenCaches();
+ #else
+ .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
+ #endif
+ #elif (IndividualB2CAuth)
+ builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
+ #if (GenerateApi)
+ .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAdB2C"))
+ .EnableTokenAcquisitionToCallDownstreamApi()
+ .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi"))
+ .AddInMemoryTokenCaches();
+ #else
+ .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAdB2C"));
+ #endif
+ #endif
+
+ builder.Services.AddControllersWithViews();
+ builder.Services.AddRazorPages();
+
+ var app = builder.Build();
+
+ // Configure the HTTP request pipeline.
+ if (app.Environment.IsDevelopment())
+ {
+ #if (IndividualLocalAuth)
+ app.UseMigrationsEndPoint();
+ #endif
+ app.UseWebAssemblyDebugging();
+ }
+ else
+ {
+ app.UseExceptionHandler("/Error");
+ #if (RequiresHttps)
+ // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
+ app.UseHsts();
+ #endif
+ }
+
+ #if (RequiresHttps)
+ app.UseHttpsRedirection();
+
+ #endif
+ app.UseBlazorFrameworkFiles();
+ app.UseStaticFiles();
+
+ app.UseRouting();
+
+ #if (IndividualLocalAuth)
+ app.UseIdentityServer();
+ #endif
+ #if (OrganizationalAuth || IndividualAuth)
+ app.UseAuthentication();
+ #endif
+ #if (!NoAuth)
+ app.UseAuthorization();
+
+ #endif
+
+ app.MapRazorPages();
+ app.MapControllers();
+ app.MapFallbackToFile("index.html");
+
+ app.Run();
+ }
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/dotnetcli.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/dotnetcli.host.json
index d97858472b..6f4f4fb893 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/dotnetcli.host.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/dotnetcli.host.json
@@ -27,6 +27,10 @@
"NoHttps": {
"longName": "no-https",
"shortName": ""
+ },
+ "UseProgramMain": {
+ "longName": "use-program-main",
+ "shortName": ""
}
},
"usageExamples": [
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/ide.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/ide.host.json
index 751a95c5b2..f30c4753e2 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/ide.host.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/ide.host.json
@@ -20,5 +20,11 @@
"useHttps": true
}
],
+ "symbolInfo": [
+ {
+ "id": "UseProgramMain",
+ "isVisible": true
+ }
+ ],
"disableHttpsSymbol": "NoHttps"
}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.cs.json b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.cs.json
index f0366911c0..95327d453e 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.cs.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.cs.json
@@ -11,6 +11,8 @@
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/NoHttps/description": "Whether to turn off HTTPS. This option only applies if Individual, IndividualB2C, SingleOrg, or MultiOrg aren't used for --auth.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.de.json b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.de.json
index f0366911c0..95327d453e 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.de.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.de.json
@@ -11,6 +11,8 @@
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/NoHttps/description": "Whether to turn off HTTPS. This option only applies if Individual, IndividualB2C, SingleOrg, or MultiOrg aren't used for --auth.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.en.json b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.en.json
index f0366911c0..764a457bb1 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.en.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.en.json
@@ -11,6 +11,8 @@
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/NoHttps/description": "Whether to turn off HTTPS. This option only applies if Individual, IndividualB2C, SingleOrg, or MultiOrg aren't used for --auth.",
+ "symbols/UseProgramMain/displayName": "Do not use top-level statements",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.es.json b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.es.json
index f0366911c0..95327d453e 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.es.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.es.json
@@ -11,6 +11,8 @@
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/NoHttps/description": "Whether to turn off HTTPS. This option only applies if Individual, IndividualB2C, SingleOrg, or MultiOrg aren't used for --auth.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.fr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.fr.json
index f0366911c0..95327d453e 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.fr.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.fr.json
@@ -11,6 +11,8 @@
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/NoHttps/description": "Whether to turn off HTTPS. This option only applies if Individual, IndividualB2C, SingleOrg, or MultiOrg aren't used for --auth.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.it.json b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.it.json
index f0366911c0..95327d453e 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.it.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.it.json
@@ -11,6 +11,8 @@
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/NoHttps/description": "Whether to turn off HTTPS. This option only applies if Individual, IndividualB2C, SingleOrg, or MultiOrg aren't used for --auth.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.ja.json b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.ja.json
index f0366911c0..95327d453e 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.ja.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.ja.json
@@ -11,6 +11,8 @@
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/NoHttps/description": "Whether to turn off HTTPS. This option only applies if Individual, IndividualB2C, SingleOrg, or MultiOrg aren't used for --auth.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.ko.json b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.ko.json
index f0366911c0..95327d453e 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.ko.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.ko.json
@@ -11,6 +11,8 @@
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/NoHttps/description": "Whether to turn off HTTPS. This option only applies if Individual, IndividualB2C, SingleOrg, or MultiOrg aren't used for --auth.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.pl.json b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.pl.json
index f0366911c0..95327d453e 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.pl.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.pl.json
@@ -11,6 +11,8 @@
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/NoHttps/description": "Whether to turn off HTTPS. This option only applies if Individual, IndividualB2C, SingleOrg, or MultiOrg aren't used for --auth.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json
index f0366911c0..95327d453e 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json
@@ -11,6 +11,8 @@
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/NoHttps/description": "Whether to turn off HTTPS. This option only applies if Individual, IndividualB2C, SingleOrg, or MultiOrg aren't used for --auth.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.ru.json b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.ru.json
index f0366911c0..95327d453e 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.ru.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.ru.json
@@ -11,6 +11,8 @@
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/NoHttps/description": "Whether to turn off HTTPS. This option only applies if Individual, IndividualB2C, SingleOrg, or MultiOrg aren't used for --auth.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.tr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.tr.json
index f0366911c0..95327d453e 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.tr.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.tr.json
@@ -11,6 +11,8 @@
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/NoHttps/description": "Whether to turn off HTTPS. This option only applies if Individual, IndividualB2C, SingleOrg, or MultiOrg aren't used for --auth.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json
index f0366911c0..95327d453e 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json
@@ -11,6 +11,8 @@
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/NoHttps/description": "Whether to turn off HTTPS. This option only applies if Individual, IndividualB2C, SingleOrg, or MultiOrg aren't used for --auth.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json
index f0366911c0..95327d453e 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json
@@ -11,6 +11,8 @@
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/NoHttps/description": "Whether to turn off HTTPS. This option only applies if Individual, IndividualB2C, SingleOrg, or MultiOrg aren't used for --auth.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/template.json
index ae82a87026..9accfeb934 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/template.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/template.json
@@ -29,6 +29,21 @@
"exclude": [
"Properties/launchSettings.json"
]
+ },
+ {
+ "condition": "(!UseProgramMain)",
+ "exclude": [
+ "Program.Main.cs"
+ ]
+ },
+ {
+ "condition": "(UseProgramMain)",
+ "exclude": [
+ "Program.cs"
+ ],
+ "rename": {
+ "Program.Main.cs": "Program.cs"
+ }
}
]
}
@@ -156,6 +171,13 @@
"datatype": "bool",
"defaultValue": "false",
"description": "Whether to turn off HTTPS. This option only applies if Individual, IndividualB2C, SingleOrg, or MultiOrg aren't used for --auth."
+ },
+ "UseProgramMain": {
+ "type": "parameter",
+ "datatype": "bool",
+ "defaultValue": "false",
+ "displayName": "Do not use top-level statements",
+ "description": "Whether to generate an explicit Program class and Main method instead of top-level statements."
}
},
"primaryOutputs": [
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/Program.Main.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/Program.Main.cs
new file mode 100644
index 0000000000..6a10649982
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/Program.Main.cs
@@ -0,0 +1,14 @@
+namespace Company.WebApplication1;
+
+public class Program
+{
+ public static void Main(string[] args)
+ {
+ var builder = WebApplication.CreateBuilder(args);
+ var app = builder.Build();
+
+ app.MapGet("/", () => "Hello World!");
+
+ app.Run();
+ }
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/dotnetcli.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/dotnetcli.host.json
index 684bc1e734..ded3cbf35f 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/dotnetcli.host.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/dotnetcli.host.json
@@ -14,6 +14,10 @@
"ExcludeLaunchSettings": {
"longName": "exclude-launch-settings",
"shortName": ""
+ },
+ "UseProgramMain": {
+ "longName": "use-program-main",
+ "shortName": ""
}
},
"usageExamples": [
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/ide.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/ide.host.json
index 2cb4190951..5c3a869512 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/ide.host.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/ide.host.json
@@ -2,5 +2,11 @@
"$schema": "http://json.schemastore.org/vs-2017.3.host",
"order": 500,
"icon": "ide/gRPC.png",
- "supportsDocker": true
+ "supportsDocker": true,
+ "symbolInfo": [
+ {
+ "id": "UseProgramMain",
+ "isVisible": true
+ }
+ ]
}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.cs.json b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.cs.json
index 64465ca34a..eec915b973 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.cs.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.cs.json
@@ -8,6 +8,8 @@
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.",
"symbols/kestrelHttpsPort/description": "Port number to use for the HTTPS endpoint in launchSettings.json. This option is only applicable when the parameter no-https is not used (no-https will be ignored if either IndividualAuth or OrganizationalAuth is used).",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.de.json b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.de.json
index 64465ca34a..eec915b973 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.de.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.de.json
@@ -8,6 +8,8 @@
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.",
"symbols/kestrelHttpsPort/description": "Port number to use for the HTTPS endpoint in launchSettings.json. This option is only applicable when the parameter no-https is not used (no-https will be ignored if either IndividualAuth or OrganizationalAuth is used).",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.en.json b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.en.json
index 64465ca34a..a1f2262d3d 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.en.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.en.json
@@ -8,6 +8,8 @@
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.",
"symbols/kestrelHttpsPort/description": "Port number to use for the HTTPS endpoint in launchSettings.json. This option is only applicable when the parameter no-https is not used (no-https will be ignored if either IndividualAuth or OrganizationalAuth is used).",
+ "symbols/UseProgramMain/displayName": "Do not use top-level statements",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.es.json b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.es.json
index 64465ca34a..eec915b973 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.es.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.es.json
@@ -8,6 +8,8 @@
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.",
"symbols/kestrelHttpsPort/description": "Port number to use for the HTTPS endpoint in launchSettings.json. This option is only applicable when the parameter no-https is not used (no-https will be ignored if either IndividualAuth or OrganizationalAuth is used).",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.fr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.fr.json
index 64465ca34a..eec915b973 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.fr.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.fr.json
@@ -8,6 +8,8 @@
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.",
"symbols/kestrelHttpsPort/description": "Port number to use for the HTTPS endpoint in launchSettings.json. This option is only applicable when the parameter no-https is not used (no-https will be ignored if either IndividualAuth or OrganizationalAuth is used).",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.it.json b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.it.json
index 64465ca34a..eec915b973 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.it.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.it.json
@@ -8,6 +8,8 @@
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.",
"symbols/kestrelHttpsPort/description": "Port number to use for the HTTPS endpoint in launchSettings.json. This option is only applicable when the parameter no-https is not used (no-https will be ignored if either IndividualAuth or OrganizationalAuth is used).",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.ja.json b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.ja.json
index 64465ca34a..eec915b973 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.ja.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.ja.json
@@ -8,6 +8,8 @@
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.",
"symbols/kestrelHttpsPort/description": "Port number to use for the HTTPS endpoint in launchSettings.json. This option is only applicable when the parameter no-https is not used (no-https will be ignored if either IndividualAuth or OrganizationalAuth is used).",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.ko.json b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.ko.json
index 64465ca34a..eec915b973 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.ko.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.ko.json
@@ -8,6 +8,8 @@
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.",
"symbols/kestrelHttpsPort/description": "Port number to use for the HTTPS endpoint in launchSettings.json. This option is only applicable when the parameter no-https is not used (no-https will be ignored if either IndividualAuth or OrganizationalAuth is used).",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.pl.json b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.pl.json
index 64465ca34a..eec915b973 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.pl.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.pl.json
@@ -8,6 +8,8 @@
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.",
"symbols/kestrelHttpsPort/description": "Port number to use for the HTTPS endpoint in launchSettings.json. This option is only applicable when the parameter no-https is not used (no-https will be ignored if either IndividualAuth or OrganizationalAuth is used).",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.pt-BR.json b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.pt-BR.json
index 64465ca34a..eec915b973 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.pt-BR.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.pt-BR.json
@@ -8,6 +8,8 @@
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.",
"symbols/kestrelHttpsPort/description": "Port number to use for the HTTPS endpoint in launchSettings.json. This option is only applicable when the parameter no-https is not used (no-https will be ignored if either IndividualAuth or OrganizationalAuth is used).",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.ru.json b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.ru.json
index 64465ca34a..eec915b973 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.ru.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.ru.json
@@ -8,6 +8,8 @@
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.",
"symbols/kestrelHttpsPort/description": "Port number to use for the HTTPS endpoint in launchSettings.json. This option is only applicable when the parameter no-https is not used (no-https will be ignored if either IndividualAuth or OrganizationalAuth is used).",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.tr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.tr.json
index 64465ca34a..eec915b973 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.tr.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.tr.json
@@ -8,6 +8,8 @@
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.",
"symbols/kestrelHttpsPort/description": "Port number to use for the HTTPS endpoint in launchSettings.json. This option is only applicable when the parameter no-https is not used (no-https will be ignored if either IndividualAuth or OrganizationalAuth is used).",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.zh-Hans.json b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.zh-Hans.json
index 64465ca34a..eec915b973 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.zh-Hans.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.zh-Hans.json
@@ -8,6 +8,8 @@
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.",
"symbols/kestrelHttpsPort/description": "Port number to use for the HTTPS endpoint in launchSettings.json. This option is only applicable when the parameter no-https is not used (no-https will be ignored if either IndividualAuth or OrganizationalAuth is used).",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.zh-Hant.json b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.zh-Hant.json
index 64465ca34a..eec915b973 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.zh-Hant.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/localize/templatestrings.zh-Hant.json
@@ -8,6 +8,8 @@
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
"symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.",
"symbols/kestrelHttpsPort/description": "Port number to use for the HTTPS endpoint in launchSettings.json. This option is only applicable when the parameter no-https is not used (no-https will be ignored if either IndividualAuth or OrganizationalAuth is used).",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/template.json
index 8e17381b92..9b1f90bc5b 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/template.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/template.json
@@ -26,6 +26,21 @@
"exclude": [
"Properties/launchSettings.json"
]
+ },
+ {
+ "condition": "(!UseProgramMain)",
+ "exclude": [
+ "Program.Main.cs"
+ ]
+ },
+ {
+ "condition": "(UseProgramMain)",
+ "exclude": [
+ "Program.cs"
+ ],
+ "rename": {
+ "Program.Main.cs": "Program.cs"
+ }
}
]
}
@@ -102,6 +117,13 @@
"fallbackVariableName": "kestrelHttpsPortGenerated"
},
"replaces": "5001"
+ },
+ "UseProgramMain": {
+ "type": "parameter",
+ "datatype": "bool",
+ "defaultValue": "false",
+ "displayName": "Do not use top-level statements",
+ "description": "Whether to generate an explicit Program class and Main method instead of top-level statements."
}
},
"primaryOutputs": [
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/Program.Main.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/Program.Main.cs
new file mode 100644
index 0000000000..ec1af1a7e9
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/Program.Main.cs
@@ -0,0 +1,25 @@
+using GrpcService_CSharp.Services;
+
+namespace Company.WebApplication1;
+
+public class Program
+{
+ public static void Main(string[] args)
+ {
+ var builder = WebApplication.CreateBuilder(args);
+
+ // Additional configuration is required to successfully run gRPC on macOS.
+ // For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682
+
+ // Add services to the container.
+ builder.Services.AddGrpc();
+
+ var app = builder.Build();
+
+ // Configure the HTTP request pipeline.
+ app.MapGrpcService<GreeterService>();
+ app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
+
+ app.Run();
+ }
+} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/dotnetcli.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/dotnetcli.host.json
index 6ce1fbe6eb..a00ae64f28 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/dotnetcli.host.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/dotnetcli.host.json
@@ -85,6 +85,10 @@
"CallsMicrosoftGraph": {
"longName": "calls-graph",
"shortName": ""
+ },
+ "UseProgramMain": {
+ "longName": "use-program-main",
+ "shortName": ""
}
},
"usageExamples": [
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/ide.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/ide.host.json
index f176b8df2a..0dc542e09b 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/ide.host.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/ide.host.json
@@ -45,7 +45,10 @@
}
],
"symbolInfo": [
-
+ {
+ "id": "UseProgramMain",
+ "isVisible": true
+ }
],
"disableHttpsSymbol": "NoHttps"
}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.cs.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.cs.json
index 390d976d32..815f7d8cab 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.cs.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.cs.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.de.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.de.json
index 390d976d32..815f7d8cab 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.de.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.de.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.en.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.en.json
index 390d976d32..d9e25f82e1 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.en.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.en.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Do not use top-level statements",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.es.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.es.json
index 390d976d32..815f7d8cab 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.es.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.es.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.fr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.fr.json
index 390d976d32..815f7d8cab 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.fr.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.fr.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.it.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.it.json
index 390d976d32..815f7d8cab 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.it.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.it.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.ja.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.ja.json
index 390d976d32..815f7d8cab 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.ja.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.ja.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.ko.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.ko.json
index 390d976d32..815f7d8cab 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.ko.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.ko.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.pl.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.pl.json
index 390d976d32..815f7d8cab 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.pl.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.pl.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json
index 390d976d32..815f7d8cab 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.ru.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.ru.json
index 390d976d32..815f7d8cab 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.ru.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.ru.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.tr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.tr.json
index 390d976d32..815f7d8cab 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.tr.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.tr.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json
index 390d976d32..815f7d8cab 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json
index 390d976d32..815f7d8cab 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/template.json
index e8d986bdd0..3f42794ce9 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/template.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/template.json
@@ -94,6 +94,21 @@
"exclude": [
"Data/SqlServer/**"
]
+ },
+ {
+ "condition": "(!UseProgramMain)",
+ "exclude": [
+ "Program.Main.cs"
+ ]
+ },
+ {
+ "condition": "(UseProgramMain)",
+ "exclude": [
+ "Program.cs"
+ ],
+ "rename": {
+ "Program.Main.cs": "Program.cs"
+ }
}
]
}
@@ -406,6 +421,13 @@
"GenerateApiOrGraph": {
"type": "computed",
"value": "(GenerateApi || GenerateGraph)"
+ },
+ "UseProgramMain": {
+ "type": "parameter",
+ "datatype": "bool",
+ "defaultValue": "false",
+ "displayName": "Do not use top-level statements",
+ "description": "Whether to generate an explicit Program class and Main method instead of top-level statements."
}
},
"primaryOutputs": [
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.Main.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.Main.cs
new file mode 100644
index 0000000000..3a1a1d68cc
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.Main.cs
@@ -0,0 +1,155 @@
+#if (OrganizationalAuth || IndividualB2CAuth)
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authentication.OpenIdConnect;
+using Microsoft.AspNetCore.Authorization;
+#endif
+#if (WindowsAuth)
+using Microsoft.AspNetCore.Authentication.Negotiate;
+#endif
+#if (IndividualLocalAuth)
+using Microsoft.AspNetCore.Identity;
+#endif
+#if (OrganizationalAuth)
+using Microsoft.AspNetCore.Mvc.Authorization;
+#endif
+#if (IndividualLocalAuth)
+using Microsoft.EntityFrameworkCore;
+#endif
+#if (OrganizationalAuth || IndividualB2CAuth)
+using Microsoft.Identity.Web;
+using Microsoft.Identity.Web.UI;
+#endif
+#if (MultiOrgAuth)
+using Microsoft.IdentityModel.Tokens;
+#endif
+#if (GenerateGraph)
+using Graph = Microsoft.Graph;
+#endif
+#if (IndividualLocalAuth)
+using Company.WebApplication1.Data;
+#endif
+#if (OrganizationalAuth || IndividualB2CAuth || IndividualLocalAuth || MultiOrgAuth || GenerateGraph || WindowsAuth)
+
+#endif
+namespace Company.WebApplication1;
+
+public class Program
+{
+ public static void Main(string[] args)
+ {
+ var builder = WebApplication.CreateBuilder(args);
+
+ // Add services to the container.
+ #if (IndividualLocalAuth)
+ var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
+ builder.Services.AddDbContext<ApplicationDbContext>(options =>
+ #if (UseLocalDB)
+ options.UseSqlServer(connectionString));
+ #else
+ options.UseSqlite(connectionString));
+ #endif
+ builder.Services.AddDatabaseDeveloperPageExceptionFilter();
+
+ builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
+ .AddEntityFrameworkStores<ApplicationDbContext>();
+ #elif (OrganizationalAuth)
+ #if (GenerateApiOrGraph)
+ var initialScopes = builder.Configuration["DownstreamApi:Scopes"]?.Split(' ');
+
+ #endif
+ builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
+ #if (GenerateApiOrGraph)
+ .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
+ .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
+ #if (GenerateApi)
+ .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi"))
+ #endif
+ #if (GenerateGraph)
+ .AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi"))
+ #endif
+ .AddInMemoryTokenCaches();
+ #else
+ .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
+ #endif
+ #elif (IndividualB2CAuth)
+ #if (GenerateApi)
+ var initialScopes = builder.Configuration["DownstreamApi:Scopes"]?.Split(' ');
+
+ #endif
+ builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
+ #if (GenerateApi)
+ .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAdB2C"))
+ .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
+ .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi"))
+ .AddInMemoryTokenCaches();
+ #else
+ .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAdB2C"));
+ #endif
+ #endif
+ #if (OrganizationalAuth)
+
+ builder.Services.AddAuthorization(options =>
+ {
+ // By default, all incoming requests will be authorized according to the default policy.
+ options.FallbackPolicy = options.DefaultPolicy;
+ });
+ builder.Services.AddRazorPages()
+ .AddMicrosoftIdentityUI();
+ #elif (IndividualB2CAuth)
+ builder.Services.AddRazorPages()
+ .AddMicrosoftIdentityUI();
+ #elif (WindowsAuth)
+
+ builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
+ .AddNegotiate();
+
+ builder.Services.AddAuthorization(options =>
+ {
+ // By default, all incoming requests will be authorized according to the default policy.
+ options.FallbackPolicy = options.DefaultPolicy;
+ });
+ builder.Services.AddRazorPages();
+ #else
+ builder.Services.AddRazorPages();
+ #endif
+
+ var app = builder.Build();
+
+ // Configure the HTTP request pipeline.
+ #if (IndividualLocalAuth)
+ if (app.Environment.IsDevelopment())
+ {
+ app.UseMigrationsEndPoint();
+ }
+ else
+ #else
+ if (!app.Environment.IsDevelopment())
+ #endif
+ {
+ app.UseExceptionHandler("/Error");
+ #if (RequiresHttps)
+ // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
+ app.UseHsts();
+ }
+
+ app.UseHttpsRedirection();
+ #else
+ }
+ #endif
+ app.UseStaticFiles();
+
+ app.UseRouting();
+
+ #if (OrganizationalAuth || IndividualAuth || WindowsAuth)
+ app.UseAuthentication();
+ #endif
+ app.UseAuthorization();
+
+ app.MapRazorPages();
+ #if (IndividualB2CAuth || OrganizationalAuth)
+ app.MapControllers();
+ #endif
+
+ app.Run();
+ }
+} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/dotnetcli.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/dotnetcli.host.json
index 3c34f96f85..02abad32e7 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/dotnetcli.host.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/dotnetcli.host.json
@@ -85,6 +85,10 @@
"CallsMicrosoftGraph": {
"longName": "calls-graph",
"shortName": ""
+ },
+ "UseProgramMain": {
+ "longName": "use-program-main",
+ "shortName": ""
}
},
"usageExamples": [
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/ide.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/ide.host.json
index 12bb6ec5db..995a75bea9 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/ide.host.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/ide.host.json
@@ -45,7 +45,10 @@
}
],
"symbolInfo": [
-
+ {
+ "id": "UseProgramMain",
+ "isVisible": true
+ }
],
"disableHttpsSymbol": "NoHttps"
}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.cs.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.cs.json
index 42fc6e65af..9a7972bc95 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.cs.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.cs.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use an Program class and Main method.",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.de.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.de.json
index 42fc6e65af..9a7972bc95 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.de.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.de.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use an Program class and Main method.",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.en.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.en.json
index 42fc6e65af..4f01b0e182 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.en.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.en.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Do not use top-level statements",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.es.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.es.json
index 42fc6e65af..9a7972bc95 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.es.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.es.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use an Program class and Main method.",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.fr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.fr.json
index 42fc6e65af..9a7972bc95 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.fr.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.fr.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use an Program class and Main method.",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.it.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.it.json
index 42fc6e65af..9a7972bc95 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.it.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.it.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use an Program class and Main method.",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.ja.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.ja.json
index 42fc6e65af..9a7972bc95 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.ja.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.ja.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use an Program class and Main method.",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.ko.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.ko.json
index 42fc6e65af..9a7972bc95 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.ko.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.ko.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use an Program class and Main method.",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.pl.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.pl.json
index 42fc6e65af..9a7972bc95 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.pl.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.pl.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use an Program class and Main method.",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json
index 42fc6e65af..9a7972bc95 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.pt-BR.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use an Program class and Main method.",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.ru.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.ru.json
index 42fc6e65af..9a7972bc95 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.ru.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.ru.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use an Program class and Main method.",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.tr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.tr.json
index 42fc6e65af..9a7972bc95 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.tr.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.tr.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use an Program class and Main method.",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json
index 42fc6e65af..9a7972bc95 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.zh-Hans.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use an Program class and Main method.",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json
index 42fc6e65af..9a7972bc95 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/localize/templatestrings.zh-Hant.json
@@ -34,6 +34,8 @@
"symbols/CalledApiUrl/description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified.",
+ "symbols/UseProgramMain/displayName": "Use an Program class and Main method.",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/template.json
index ebc005e25f..a2af2cbbf6 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/template.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/template.json
@@ -90,6 +90,21 @@
"exclude": [
"Data/SqlServer/**"
]
+ },
+ {
+ "condition": "(!UseProgramMain)",
+ "exclude": [
+ "Program.Main.cs"
+ ]
+ },
+ {
+ "condition": "(UseProgramMain)",
+ "exclude": [
+ "Program.cs"
+ ],
+ "rename": {
+ "Program.Main.cs": "Program.cs"
+ }
}
]
}
@@ -402,6 +417,13 @@
"GenerateApiOrGraph": {
"type": "computed",
"value": "(GenerateApi || GenerateGraph)"
+ },
+ "UseProgramMain": {
+ "type": "parameter",
+ "datatype": "bool",
+ "defaultValue": "false",
+ "displayName": "Do not use top-level statements",
+ "description": "Whether to generate an explicit Program class and Main method instead of top-level statements."
}
},
"primaryOutputs": [
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.Main.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.Main.cs
new file mode 100644
index 0000000000..5fda9092d0
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.Main.cs
@@ -0,0 +1,159 @@
+#if (OrganizationalAuth || IndividualB2CAuth)
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Authentication.OpenIdConnect;
+#endif
+#if (WindowsAuth)
+using Microsoft.AspNetCore.Authentication.Negotiate;
+#endif
+#if (IndividualLocalAuth)
+using Microsoft.AspNetCore.Identity;
+#endif
+#if (OrganizationalAuth)
+using Microsoft.AspNetCore.Mvc.Authorization;
+#endif
+#if (IndividualLocalAuth)
+using Microsoft.EntityFrameworkCore;
+#endif
+#if (OrganizationalAuth || IndividualB2CAuth)
+using Microsoft.Identity.Web;
+using Microsoft.Identity.Web.UI;
+#endif
+#if (MultiOrgAuth)
+using Microsoft.IdentityModel.Tokens;
+#endif
+#if (GenerateGraph)
+using Graph = Microsoft.Graph;
+#endif
+#if (IndividualLocalAuth)
+using Company.WebApplication1.Data;
+#endif
+#if (OrganizationalAuth || IndividualB2CAuth || IndividualLocalAuth || MultiOrgAuth || GenerateGraph || WindowsAuth)
+
+#endif
+namespace Company.WebApplication1;
+
+public class Program
+{
+ public static void Main(string[] args)
+ {
+ var builder = WebApplication.CreateBuilder(args);
+
+ // Add services to the container.
+ #if (IndividualLocalAuth)
+ var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
+ builder.Services.AddDbContext<ApplicationDbContext>(options =>
+ #if (UseLocalDB)
+ options.UseSqlServer(connectionString));
+ #else
+ options.UseSqlite(connectionString));
+ #endif
+ builder.Services.AddDatabaseDeveloperPageExceptionFilter();
+
+ builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
+ .AddEntityFrameworkStores<ApplicationDbContext>();
+ #elif (OrganizationalAuth)
+ #if (GenerateApiOrGraph)
+ var initialScopes = builder.Configuration["DownstreamApi:Scopes"]?.Split(' ');
+
+ #endif
+ builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
+ #if (GenerateApiOrGraph)
+ .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
+ .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
+ #if (GenerateApi)
+ .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi"))
+ #endif
+ #if (GenerateGraph)
+ .AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi"))
+ #endif
+ .AddInMemoryTokenCaches();
+ #else
+ .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
+ #endif
+ #elif (IndividualB2CAuth)
+ #if (GenerateApi)
+ var initialScopes = builder.Configuration["DownstreamApi:Scopes"]?.Split(' ');
+
+ #endif
+ builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
+ #if (GenerateApi)
+ .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAdB2C"))
+ .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
+ .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi"))
+ .AddInMemoryTokenCaches();
+ #else
+ .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAdB2C"));
+ #endif
+ #endif
+ #if (OrganizationalAuth)
+
+ builder.Services.AddControllersWithViews(options =>
+ {
+ var policy = new AuthorizationPolicyBuilder()
+ .RequireAuthenticatedUser()
+ .Build();
+ options.Filters.Add(new AuthorizeFilter(policy));
+ });
+ #else
+ builder.Services.AddControllersWithViews();
+ #endif
+ #if (OrganizationalAuth || IndividualB2CAuth)
+ builder.Services.AddRazorPages()
+ .AddMicrosoftIdentityUI();
+ #endif
+ #if (WindowsAuth)
+
+ builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
+ .AddNegotiate();
+
+ builder.Services.AddAuthorization(options =>
+ {
+ // By default, all incoming requests will be authorized according to the default policy.
+ options.FallbackPolicy = options.DefaultPolicy;
+ });
+ builder.Services.AddRazorPages();
+ #endif
+
+ var app = builder.Build();
+
+ // Configure the HTTP request pipeline.
+ #if (IndividualLocalAuth)
+ if (app.Environment.IsDevelopment())
+ {
+ app.UseMigrationsEndPoint();
+ }
+ else
+ #else
+ if (!app.Environment.IsDevelopment())
+ #endif
+ {
+ app.UseExceptionHandler("/Home/Error");
+ #if (RequiresHttps)
+ // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
+ app.UseHsts();
+ }
+
+ app.UseHttpsRedirection();
+ #else
+ }
+ #endif
+ app.UseStaticFiles();
+
+ app.UseRouting();
+
+ #if (OrganizationalAuth || IndividualAuth || WindowsAuth)
+ app.UseAuthentication();
+ #endif
+ app.UseAuthorization();
+
+ app.MapControllerRoute(
+ name: "default",
+ pattern: "{controller=Home}/{action=Index}/{id?}");
+ #if (OrganizationalAuth || IndividualAuth)
+ app.MapRazorPages();
+ #endif
+
+ app.Run();
+ }
+} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/dotnetcli.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/dotnetcli.host.json
index 9b97a61820..79217f1680 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/dotnetcli.host.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/dotnetcli.host.json
@@ -85,6 +85,10 @@
"DisableOpenAPI": {
"longName": "no-openapi",
"shortName": ""
+ },
+ "UseProgramMain": {
+ "longName": "use-program-main",
+ "shortName": ""
}
},
"usageExamples": [
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/ide.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/ide.host.json
index a6042e22b9..6b45461ce4 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/ide.host.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/ide.host.json
@@ -58,6 +58,10 @@
"invertBoolean": true,
"isVisible": true,
"defaultValue": true
+ },
+ {
+ "id": "UseProgramMain",
+ "isVisible": true
}
],
"disableHttpsSymbol": "NoHttps"
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.cs.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.cs.json
index ec9b27882c..f82adc667d 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.cs.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.cs.json
@@ -31,6 +31,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg or --auth IndividualB2C is specified.",
"symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.de.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.de.json
index ec9b27882c..f82adc667d 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.de.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.de.json
@@ -31,6 +31,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg or --auth IndividualB2C is specified.",
"symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.en.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.en.json
index ec9b27882c..34a1dd0167 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.en.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.en.json
@@ -31,6 +31,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg or --auth IndividualB2C is specified.",
"symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support",
+ "symbols/UseProgramMain/displayName": "Do not use top-level statements",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.es.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.es.json
index ec9b27882c..f82adc667d 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.es.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.es.json
@@ -31,6 +31,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg or --auth IndividualB2C is specified.",
"symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.fr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.fr.json
index ec9b27882c..f82adc667d 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.fr.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.fr.json
@@ -31,6 +31,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg or --auth IndividualB2C is specified.",
"symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.it.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.it.json
index ec9b27882c..f82adc667d 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.it.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.it.json
@@ -31,6 +31,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg or --auth IndividualB2C is specified.",
"symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.ja.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.ja.json
index ec9b27882c..f82adc667d 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.ja.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.ja.json
@@ -31,6 +31,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg or --auth IndividualB2C is specified.",
"symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.ko.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.ko.json
index ec9b27882c..f82adc667d 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.ko.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.ko.json
@@ -31,6 +31,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg or --auth IndividualB2C is specified.",
"symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.pl.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.pl.json
index ec9b27882c..f82adc667d 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.pl.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.pl.json
@@ -31,6 +31,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg or --auth IndividualB2C is specified.",
"symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.pt-BR.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.pt-BR.json
index ec9b27882c..f82adc667d 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.pt-BR.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.pt-BR.json
@@ -31,6 +31,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg or --auth IndividualB2C is specified.",
"symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.ru.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.ru.json
index ec9b27882c..f82adc667d 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.ru.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.ru.json
@@ -31,6 +31,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg or --auth IndividualB2C is specified.",
"symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.tr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.tr.json
index ec9b27882c..f82adc667d 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.tr.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.tr.json
@@ -31,6 +31,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg or --auth IndividualB2C is specified.",
"symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.zh-Hans.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.zh-Hans.json
index ec9b27882c..f82adc667d 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.zh-Hans.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.zh-Hans.json
@@ -31,6 +31,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg or --auth IndividualB2C is specified.",
"symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.zh-Hant.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.zh-Hant.json
index ec9b27882c..f82adc667d 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.zh-Hant.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/localize/templatestrings.zh-Hant.json
@@ -31,6 +31,8 @@
"symbols/CallsMicrosoftGraph/description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg is specified.",
"symbols/CalledApiScopes/description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg or --auth IndividualB2C is specified.",
"symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/template.json
index d3683b75eb..e153789e02 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/template.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/template.json
@@ -38,6 +38,21 @@
]
},
{
+ "condition": "(!UseProgramMain)",
+ "exclude": [
+ "Program.Main.cs"
+ ]
+ },
+ {
+ "condition": "(UseProgramMain && !UseMinimalAPIs)",
+ "exclude": [
+ "Program.cs"
+ ],
+ "rename": {
+ "Program.Main.cs": "Program.cs"
+ }
+ },
+ {
"condition": "(UseMinimalAPIs)",
"exclude": [
"Controllers/WeatherForecastController.cs",
@@ -364,6 +379,13 @@
"UseControllers": {
"type": "computed",
"value": "(!UseMinimalAPIs)"
+ },
+ "UseProgramMain": {
+ "type": "parameter",
+ "datatype": "bool",
+ "defaultValue": "false",
+ "displayName": "Do not use top-level statements",
+ "description": "Whether to generate an explicit Program class and Main method instead of top-level statements."
}
},
"primaryOutputs": [
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Program.Main.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Program.Main.cs
new file mode 100644
index 0000000000..a0c9ad67e8
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Program.Main.cs
@@ -0,0 +1,95 @@
+#if (OrganizationalAuth || IndividualB2CAuth)
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+#endif
+#if (WindowsAuth)
+using Microsoft.AspNetCore.Authentication.Negotiate;
+#endif
+#if (GenerateGraph)
+using Graph = Microsoft.Graph;
+#endif
+#if (OrganizationalAuth || IndividualB2CAuth)
+using Microsoft.Identity.Web;
+#endif
+#if (OrganizationalAuth || IndividualB2CAuth || GenerateGraph || WindowsAuth)
+
+#endif
+namespace Company.WebApplication1;
+
+public class Program
+{
+ public static void Main(string[] args)
+ {
+ var builder = WebApplication.CreateBuilder(args);
+
+ // Add services to the container.
+ #if (OrganizationalAuth)
+ builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
+ #if (GenerateApiOrGraph)
+ .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"))
+ .EnableTokenAcquisitionToCallDownstreamApi()
+ #if (GenerateApi)
+ .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi"))
+ #endif
+ #if (GenerateGraph)
+ .AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi"))
+ #endif
+ .AddInMemoryTokenCaches();
+ #else
+ .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
+ #endif
+ #elif (IndividualB2CAuth)
+ builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
+ #if (GenerateApi)
+ .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAdB2C"))
+ .EnableTokenAcquisitionToCallDownstreamApi()
+ .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi"))
+ .AddInMemoryTokenCaches();
+ #else
+ .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAdB2C"));
+ #endif
+ #endif
+
+ builder.Services.AddControllers();
+ #if (EnableOpenAPI)
+ // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
+ builder.Services.AddEndpointsApiExplorer();
+ builder.Services.AddSwaggerGen();
+ #endif
+ #if (WindowsAuth)
+
+ builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
+ .AddNegotiate();
+
+ builder.Services.AddAuthorization(options =>
+ {
+ // By default, all incoming requests will be authorized according to the default policy.
+ options.FallbackPolicy = options.DefaultPolicy;
+ });
+ #endif
+
+ var app = builder.Build();
+
+ // Configure the HTTP request pipeline.
+ #if (EnableOpenAPI)
+ if (app.Environment.IsDevelopment())
+ {
+ app.UseSwagger();
+ app.UseSwaggerUI();
+ }
+ #endif
+ #if (RequiresHttps)
+
+ app.UseHttpsRedirection();
+ #endif
+
+ #if (OrganizationalAuth || IndividualAuth || WindowsAuth)
+ app.UseAuthentication();
+ #endif
+ app.UseAuthorization();
+
+ app.MapControllers();
+
+ app.Run();
+ }
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/dotnetcli.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/dotnetcli.host.json
index b1cf98e39b..36493a3a4a 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/dotnetcli.host.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/dotnetcli.host.json
@@ -11,6 +11,10 @@
"ExcludeLaunchSettings": {
"longName": "exclude-launch-settings",
"shortName": ""
+ },
+ "UseProgramMain": {
+ "longName": "use-program-main",
+ "shortName": ""
}
},
"usageExamples": [
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/ide.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/ide.host.json
index 13a025d034..59f260a583 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/ide.host.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/ide.host.json
@@ -3,4 +3,10 @@
"order": 300,
"icon": "ide/Worker.png",
"supportsDocker": true,
+ "symbolInfo": [
+ {
+ "id": "UseProgramMain",
+ "isVisible": true
+ }
+ ]
}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.cs.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.cs.json
index 018f87d2e8..23507879a5 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.cs.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.cs.json
@@ -6,6 +6,8 @@
"symbols/Framework/description": "The target framework for the project.",
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.de.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.de.json
index 018f87d2e8..23507879a5 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.de.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.de.json
@@ -6,6 +6,8 @@
"symbols/Framework/description": "The target framework for the project.",
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.en.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.en.json
index 018f87d2e8..859e306470 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.en.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.en.json
@@ -6,6 +6,8 @@
"symbols/Framework/description": "The target framework for the project.",
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Do not use top-level statements",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.es.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.es.json
index 018f87d2e8..23507879a5 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.es.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.es.json
@@ -6,6 +6,8 @@
"symbols/Framework/description": "The target framework for the project.",
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.fr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.fr.json
index 018f87d2e8..23507879a5 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.fr.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.fr.json
@@ -6,6 +6,8 @@
"symbols/Framework/description": "The target framework for the project.",
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.it.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.it.json
index 018f87d2e8..23507879a5 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.it.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.it.json
@@ -6,6 +6,8 @@
"symbols/Framework/description": "The target framework for the project.",
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.ja.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.ja.json
index 018f87d2e8..23507879a5 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.ja.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.ja.json
@@ -6,6 +6,8 @@
"symbols/Framework/description": "The target framework for the project.",
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.ko.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.ko.json
index 018f87d2e8..23507879a5 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.ko.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.ko.json
@@ -6,6 +6,8 @@
"symbols/Framework/description": "The target framework for the project.",
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.pl.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.pl.json
index 018f87d2e8..23507879a5 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.pl.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.pl.json
@@ -6,6 +6,8 @@
"symbols/Framework/description": "The target framework for the project.",
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.pt-BR.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.pt-BR.json
index 018f87d2e8..23507879a5 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.pt-BR.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.pt-BR.json
@@ -6,6 +6,8 @@
"symbols/Framework/description": "The target framework for the project.",
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.ru.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.ru.json
index 018f87d2e8..23507879a5 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.ru.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.ru.json
@@ -6,6 +6,8 @@
"symbols/Framework/description": "The target framework for the project.",
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.tr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.tr.json
index 018f87d2e8..23507879a5 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.tr.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.tr.json
@@ -6,6 +6,8 @@
"symbols/Framework/description": "The target framework for the project.",
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.zh-Hans.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.zh-Hans.json
index 018f87d2e8..23507879a5 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.zh-Hans.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.zh-Hans.json
@@ -6,6 +6,8 @@
"symbols/Framework/description": "The target framework for the project.",
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.zh-Hant.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.zh-Hant.json
index 018f87d2e8..23507879a5 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.zh-Hant.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/localize/templatestrings.zh-Hant.json
@@ -6,6 +6,8 @@
"symbols/Framework/description": "The target framework for the project.",
"symbols/Framework/choices/net7.0/description": "Target net7.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "symbols/UseProgramMain/displayName": "Use a Program class with a Main method",
+ "symbols/UseProgramMain/description": "Whether to generate an explicit Program class and Main method instead of top-level statements.",
"postActions/restore/description": "Restore NuGet packages required by this project.",
"postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
} \ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/template.json
index 6fbdd3e798..5246a00539 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/template.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/template.json
@@ -30,6 +30,21 @@
"exclude": [
"Properties/launchSettings.json"
]
+ },
+ {
+ "condition": "(!UseProgramMain)",
+ "exclude": [
+ "Program.Main.cs"
+ ]
+ },
+ {
+ "condition": "(UseProgramMain)",
+ "exclude": [
+ "Program.cs"
+ ],
+ "rename": {
+ "Program.Main.cs": "Program.cs"
+ }
}
]
}
@@ -67,6 +82,13 @@
"datatype": "bool",
"description": "If specified, skips the automatic restore of the project on create.",
"defaultValue": "false"
+ },
+ "UseProgramMain": {
+ "type": "parameter",
+ "datatype": "bool",
+ "defaultValue": "false",
+ "displayName": "Do not use top-level statements",
+ "description": "Whether to generate an explicit Program class and Main method instead of top-level statements."
}
},
"primaryOutputs": [
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/Program.Main.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/Program.Main.cs
new file mode 100644
index 0000000000..d69747f38d
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/Program.Main.cs
@@ -0,0 +1,18 @@
+using Company.Application1;
+
+namespace Company.WebApplication1;
+
+public class Program
+{
+ public static void Main(string[] args)
+ {
+ IHost host = Host.CreateDefaultBuilder(args)
+ .ConfigureServices(services =>
+ {
+ services.AddHostedService<Worker>();
+ })
+ .Build();
+
+ host.Run();
+ }
+} \ No newline at end of file
diff --git a/src/ProjectTemplates/scripts/Run-Angular-Locally.ps1 b/src/ProjectTemplates/scripts/Run-Angular-Locally.ps1
index 95de6568ea..606071f061 100644
--- a/src/ProjectTemplates/scripts/Run-Angular-Locally.ps1
+++ b/src/ProjectTemplates/scripts/Run-Angular-Locally.ps1
@@ -9,4 +9,4 @@ $ErrorActionPreference = 'Stop'
. $PSScriptRoot\Test-Template.ps1
-Test-Template "angular" "angular" "Microsoft.DotNet.Web.Spa.ProjectTemplates.6.0.6.0.0-dev.nupkg" $false
+Test-Template "angular" "angular" "Microsoft.DotNet.Web.Spa.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false
diff --git a/src/ProjectTemplates/scripts/Run-AngularProgramMain-Locally.ps1 b/src/ProjectTemplates/scripts/Run-AngularProgramMain-Locally.ps1
new file mode 100644
index 0000000000..955b9450ba
--- /dev/null
+++ b/src/ProjectTemplates/scripts/Run-AngularProgramMain-Locally.ps1
@@ -0,0 +1,12 @@
+#!/usr/bin/env pwsh
+#requires -version 4
+
+[CmdletBinding(PositionalBinding = $false)]
+param()
+
+Set-StrictMode -Version 2
+$ErrorActionPreference = 'Stop'
+
+. $PSScriptRoot\Test-Template.ps1
+
+Test-Template "angular" "angular --use-program-main" "Microsoft.DotNet.Web.Spa.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false
diff --git a/src/ProjectTemplates/scripts/Run-Blazor-Locally.ps1 b/src/ProjectTemplates/scripts/Run-Blazor-Locally.ps1
index 7a510a7a9a..22b9f6db96 100644
--- a/src/ProjectTemplates/scripts/Run-Blazor-Locally.ps1
+++ b/src/ProjectTemplates/scripts/Run-Blazor-Locally.ps1
@@ -10,4 +10,4 @@ $ErrorActionPreference = 'Stop'
. $PSScriptRoot\Test-Template.ps1
-Test-Template "blazorserver" "blazorserver" "Microsoft.DotNet.Web.ProjectTemplates.6.0.6.0.0-dev.nupkg" $false
+Test-Template "blazorserver" "blazorserver" "Microsoft.DotNet.Web.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false
diff --git a/src/ProjectTemplates/scripts/Run-BlazorProgramMain-Locally.ps1 b/src/ProjectTemplates/scripts/Run-BlazorProgramMain-Locally.ps1
new file mode 100644
index 0000000000..a5f89a1201
--- /dev/null
+++ b/src/ProjectTemplates/scripts/Run-BlazorProgramMain-Locally.ps1
@@ -0,0 +1,13 @@
+#!/usr/bin/env pwsh
+#requires -version 4
+
+# This script packages, installs and creates a template to help with rapid iteration in the templating area.
+[CmdletBinding(PositionalBinding = $false)]
+param()
+
+Set-StrictMode -Version 2
+$ErrorActionPreference = 'Stop'
+
+. $PSScriptRoot\Test-Template.ps1
+
+Test-Template "blazorserver" "blazorserver --use-program-main" "Microsoft.DotNet.Web.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false
diff --git a/src/ProjectTemplates/scripts/Run-BlazorWasm-Locally.ps1 b/src/ProjectTemplates/scripts/Run-BlazorWasm-Locally.ps1
index 50f70bb1b0..184f3c28f8 100644
--- a/src/ProjectTemplates/scripts/Run-BlazorWasm-Locally.ps1
+++ b/src/ProjectTemplates/scripts/Run-BlazorWasm-Locally.ps1
@@ -10,4 +10,4 @@ $ErrorActionPreference = 'Stop'
. $PSScriptRoot\Test-Template.ps1
-Test-Template "blazorwasm" "blazorwasm --hosted --auth Individual" "Microsoft.DotNet.Web.ProjectTemplates.6.0.6.0.0-dev.nupkg" $true
+Test-Template "blazorwasm" "blazorwasm --hosted --auth Individual" "Microsoft.DotNet.Web.ProjectTemplates.7.0.7.0.0-dev.nupkg" $true
diff --git a/src/ProjectTemplates/scripts/Run-BlazorWasmProgramMain-Locally.ps1 b/src/ProjectTemplates/scripts/Run-BlazorWasmProgramMain-Locally.ps1
new file mode 100644
index 0000000000..4c28a98793
--- /dev/null
+++ b/src/ProjectTemplates/scripts/Run-BlazorWasmProgramMain-Locally.ps1
@@ -0,0 +1,13 @@
+#!/usr/bin/env pwsh
+#requires -version 4
+
+# This script packages, installs and creates a template to help with rapid iteration in the templating area.
+[CmdletBinding(PositionalBinding = $false)]
+param()
+
+Set-StrictMode -Version 2
+$ErrorActionPreference = 'Stop'
+
+. $PSScriptRoot\Test-Template.ps1
+
+Test-Template "blazorwasm" "blazorwasm --use-program-main --hosted --auth Individual" "Microsoft.DotNet.Web.ProjectTemplates.7.0.7.0.0-dev.nupkg" $true
diff --git a/src/ProjectTemplates/scripts/Run-EmptyWeb-Locally.ps1 b/src/ProjectTemplates/scripts/Run-EmptyWeb-Locally.ps1
index 10e743504b..9d55079bf9 100644
--- a/src/ProjectTemplates/scripts/Run-EmptyWeb-Locally.ps1
+++ b/src/ProjectTemplates/scripts/Run-EmptyWeb-Locally.ps1
@@ -9,4 +9,4 @@ $ErrorActionPreference = 'Stop'
. $PSScriptRoot\Test-Template.ps1
-Test-Template "web" "web" "Microsoft.DotNet.Web.ProjectTemplates.6.0.6.0.0-dev.nupkg" $false
+Test-Template "web" "web" "Microsoft.DotNet.Web.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false
diff --git a/src/ProjectTemplates/scripts/Run-EmptyWebProgramMain-Locally.ps1 b/src/ProjectTemplates/scripts/Run-EmptyWebProgramMain-Locally.ps1
new file mode 100644
index 0000000000..4fd0f95af0
--- /dev/null
+++ b/src/ProjectTemplates/scripts/Run-EmptyWebProgramMain-Locally.ps1
@@ -0,0 +1,12 @@
+#!/usr/bin/env pwsh
+#requires -version 4
+
+[CmdletBinding(PositionalBinding = $false)]
+param()
+
+Set-StrictMode -Version 2
+$ErrorActionPreference = 'Stop'
+
+. $PSScriptRoot\Test-Template.ps1
+
+Test-Template "web" "web --use-program-main" "Microsoft.DotNet.Web.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false
diff --git a/src/ProjectTemplates/scripts/Run-Razor-Locally.ps1 b/src/ProjectTemplates/scripts/Run-Razor-Locally.ps1
index 6f16590be8..9dfe0c2178 100644
--- a/src/ProjectTemplates/scripts/Run-Razor-Locally.ps1
+++ b/src/ProjectTemplates/scripts/Run-Razor-Locally.ps1
@@ -6,4 +6,4 @@ param()
. $PSScriptRoot\Test-Template.ps1
-Test-Template "webapp" "webapp -au Individual" "Microsoft.DotNet.Web.ProjectTemplates.6.0.6.0.0-dev.nupkg" $false
+Test-Template "webapp" "webapp -au Individual" "Microsoft.DotNet.Web.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false
diff --git a/src/ProjectTemplates/scripts/Run-RazorProgramMain-Locally.ps1 b/src/ProjectTemplates/scripts/Run-RazorProgramMain-Locally.ps1
new file mode 100644
index 0000000000..ada9e210b6
--- /dev/null
+++ b/src/ProjectTemplates/scripts/Run-RazorProgramMain-Locally.ps1
@@ -0,0 +1,9 @@
+#!/usr/bin/env powershell
+#requires -version 4
+
+[CmdletBinding(PositionalBinding = $false)]
+param()
+
+. $PSScriptRoot\Test-Template.ps1
+
+Test-Template "webapp" "webapp -au Individual --use-program-main" "Microsoft.DotNet.Web.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false
diff --git a/src/ProjectTemplates/scripts/Run-React-Locally.ps1 b/src/ProjectTemplates/scripts/Run-React-Locally.ps1
index a4baf0c405..5be4be7ff5 100644
--- a/src/ProjectTemplates/scripts/Run-React-Locally.ps1
+++ b/src/ProjectTemplates/scripts/Run-React-Locally.ps1
@@ -9,4 +9,4 @@ $ErrorActionPreference = 'Stop'
. $PSScriptRoot\Test-Template.ps1
-Test-Template "react" "react" "Microsoft.DotNet.Web.Spa.ProjectTemplates.6.0.6.0.0-dev.nupkg" $false
+Test-Template "react" "react" "Microsoft.DotNet.Web.Spa.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false
diff --git a/src/ProjectTemplates/scripts/Run-ReactProgramMain-Locally.ps1 b/src/ProjectTemplates/scripts/Run-ReactProgramMain-Locally.ps1
new file mode 100644
index 0000000000..ef8cc77d32
--- /dev/null
+++ b/src/ProjectTemplates/scripts/Run-ReactProgramMain-Locally.ps1
@@ -0,0 +1,12 @@
+#!/usr/bin/env pwsh
+#requires -version 4
+
+[CmdletBinding(PositionalBinding = $false)]
+param()
+
+Set-StrictMode -Version 2
+$ErrorActionPreference = 'Stop'
+
+. $PSScriptRoot\Test-Template.ps1
+
+Test-Template "react" "react --use-program-main" "Microsoft.DotNet.Web.Spa.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false
diff --git a/src/ProjectTemplates/scripts/Run-ReactRedux-Locally.ps1 b/src/ProjectTemplates/scripts/Run-ReactRedux-Locally.ps1
index aedd8ec88a..06303a076a 100644
--- a/src/ProjectTemplates/scripts/Run-ReactRedux-Locally.ps1
+++ b/src/ProjectTemplates/scripts/Run-ReactRedux-Locally.ps1
@@ -9,4 +9,4 @@ $ErrorActionPreference = 'Stop'
. $PSScriptRoot\Test-Template.ps1
-Test-Template "reactredux" "reactredux" "Microsoft.DotNet.Web.Spa.ProjectTemplates.6.0.6.0.0-dev.nupkg" $false
+Test-Template "reactredux" "reactredux" "Microsoft.DotNet.Web.Spa.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false
diff --git a/src/ProjectTemplates/scripts/Run-Starterweb-Locally.ps1 b/src/ProjectTemplates/scripts/Run-Starterweb-Locally.ps1
index ab195cd016..c411befc5a 100644
--- a/src/ProjectTemplates/scripts/Run-Starterweb-Locally.ps1
+++ b/src/ProjectTemplates/scripts/Run-Starterweb-Locally.ps1
@@ -9,4 +9,4 @@ $ErrorActionPreference = 'Stop'
. $PSScriptRoot\Test-Template.ps1
-Test-Template "mvc" "mvc -au Individual" "Microsoft.DotNet.Web.ProjectTemplates.6.0.6.0.0-dev.nupkg" $false
+Test-Template "mvc" "mvc -au Individual" "Microsoft.DotNet.Web.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false
diff --git a/src/ProjectTemplates/scripts/Run-StarterwebProgramMain-Locally.ps1 b/src/ProjectTemplates/scripts/Run-StarterwebProgramMain-Locally.ps1
new file mode 100644
index 0000000000..d262c5eb50
--- /dev/null
+++ b/src/ProjectTemplates/scripts/Run-StarterwebProgramMain-Locally.ps1
@@ -0,0 +1,12 @@
+#!/usr/bin/env pwsh
+#requires -version 4
+
+[CmdletBinding(PositionalBinding = $false)]
+param()
+
+Set-StrictMode -Version 2
+$ErrorActionPreference = 'Stop'
+
+. $PSScriptRoot\Test-Template.ps1
+
+Test-Template "mvc" "mvc -au Individual --use-program-main" "Microsoft.DotNet.Web.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false
diff --git a/src/ProjectTemplates/scripts/Run-WebApi-Locally.ps1 b/src/ProjectTemplates/scripts/Run-WebApi-Locally.ps1
index 467d6e57e7..14f003acfd 100644
--- a/src/ProjectTemplates/scripts/Run-WebApi-Locally.ps1
+++ b/src/ProjectTemplates/scripts/Run-WebApi-Locally.ps1
@@ -9,4 +9,4 @@ $ErrorActionPreference = 'Stop'
. $PSScriptRoot\Test-Template.ps1
-Test-Template "webapi" "webapi" "Microsoft.DotNet.Web.ProjectTemplates.6.0.6.0.0-dev.nupkg" $false
+Test-Template "webapi" "webapi" "Microsoft.DotNet.Web.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false
diff --git a/src/ProjectTemplates/scripts/Run-WebApiMinimal-Locally.ps1 b/src/ProjectTemplates/scripts/Run-WebApiMinimal-Locally.ps1
index 19325a7c7e..4e32b826f8 100644
--- a/src/ProjectTemplates/scripts/Run-WebApiMinimal-Locally.ps1
+++ b/src/ProjectTemplates/scripts/Run-WebApiMinimal-Locally.ps1
@@ -9,4 +9,4 @@ $ErrorActionPreference = 'Stop'
. $PSScriptRoot\Test-Template.ps1
-Test-Template "webapimin" "webapi -minimal" "Microsoft.DotNet.Web.ProjectTemplates.6.0.6.0.0-dev.nupkg" $false
+Test-Template "webapimin" "webapi -minimal" "Microsoft.DotNet.Web.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false
diff --git a/src/ProjectTemplates/scripts/Run-WebApiProgamMain-Locally.ps1 b/src/ProjectTemplates/scripts/Run-WebApiProgamMain-Locally.ps1
new file mode 100644
index 0000000000..dafce77763
--- /dev/null
+++ b/src/ProjectTemplates/scripts/Run-WebApiProgamMain-Locally.ps1
@@ -0,0 +1,12 @@
+#!/usr/bin/env pwsh
+#requires -version 4
+
+[CmdletBinding(PositionalBinding = $false)]
+param()
+
+Set-StrictMode -Version 2
+$ErrorActionPreference = 'Stop'
+
+. $PSScriptRoot\Test-Template.ps1
+
+Test-Template "webapi" "webapi --use-program-main" "Microsoft.DotNet.Web.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false
diff --git a/src/ProjectTemplates/scripts/Run-Worker-Locally.ps1 b/src/ProjectTemplates/scripts/Run-Worker-Locally.ps1
index 9f3c027209..7ccf87d528 100644
--- a/src/ProjectTemplates/scripts/Run-Worker-Locally.ps1
+++ b/src/ProjectTemplates/scripts/Run-Worker-Locally.ps1
@@ -9,4 +9,4 @@ $ErrorActionPreference = 'Stop'
. $PSScriptRoot\Test-Template.ps1
-Test-Template "worker" "worker" "Microsoft.DotNet.Web.ProjectTemplates.6.0.6.0.0-dev.nupkg" $false
+Test-Template "worker" "worker" "Microsoft.DotNet.Web.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false
diff --git a/src/ProjectTemplates/scripts/Run-WorkerProgramMain-Locally.ps1 b/src/ProjectTemplates/scripts/Run-WorkerProgramMain-Locally.ps1
new file mode 100644
index 0000000000..42b013ef27
--- /dev/null
+++ b/src/ProjectTemplates/scripts/Run-WorkerProgramMain-Locally.ps1
@@ -0,0 +1,12 @@
+#!/usr/bin/env pwsh
+#requires -version 4
+
+[CmdletBinding(PositionalBinding = $false)]
+param()
+
+Set-StrictMode -Version 2
+$ErrorActionPreference = 'Stop'
+
+. $PSScriptRoot\Test-Template.ps1
+
+Test-Template "worker" "worker --use-program-main" "Microsoft.DotNet.Web.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false
diff --git a/src/ProjectTemplates/scripts/Run-gRPC-Locally.ps1 b/src/ProjectTemplates/scripts/Run-gRPC-Locally.ps1
index 2803a34d9c..d201cda047 100644
--- a/src/ProjectTemplates/scripts/Run-gRPC-Locally.ps1
+++ b/src/ProjectTemplates/scripts/Run-gRPC-Locally.ps1
@@ -9,4 +9,4 @@ $ErrorActionPreference = 'Stop'
. $PSScriptRoot\Test-Template.ps1
-Test-Template "grpc" "grpc" "Microsoft.DotNet.Web.ProjectTemplates.6.0.6.0.0-dev.nupkg" $false
+Test-Template "grpc" "grpc" "Microsoft.DotNet.Web.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false
diff --git a/src/ProjectTemplates/scripts/Test-Template.ps1 b/src/ProjectTemplates/scripts/Test-Template.ps1
index 242558493d..1774b47735 100644
--- a/src/ProjectTemplates/scripts/Test-Template.ps1
+++ b/src/ProjectTemplates/scripts/Test-Template.ps1
@@ -64,7 +64,9 @@ function Test-Template($templateName, $templateArgs, $templateNupkg, $isBlazorWa
if ($isBlazorWasmHosted) {
Push-Location Server
}
- dotnet.exe ef migrations add mvc
+ if ($templateArgs -match '-au') {
+ dotnet.exe ef migrations add mvc
+ }
dotnet.exe publish --configuration Release
Set-Location .\bin\Release\net7.0\publish
if ($isBlazorWasm -eq $false) {
diff --git a/src/ProjectTemplates/test/BlazorServerTemplateTest.cs b/src/ProjectTemplates/test/BlazorServerTemplateTest.cs
index b10647182a..92120b20fb 100644
--- a/src/ProjectTemplates/test/BlazorServerTemplateTest.cs
+++ b/src/ProjectTemplates/test/BlazorServerTemplateTest.cs
@@ -26,18 +26,26 @@ public class BlazorServerTemplateTest : BlazorTemplateTest
[Fact]
public Task BlazorServerTemplateWorks_NoAuth() => CreateBuildPublishAsync("blazorservernoauth");
+ [Fact]
+ public Task BlazorServerTemplateWorks_ProgamMainNoAuth() => CreateBuildPublishAsync("blazorservernoauth", args: new [] { "--use-program-main" });
+
[Theory]
- [InlineData(true)]
- [InlineData(false)]
+ [InlineData(true, null)]
+ [InlineData(true, new string[] { "--use-program-main" })]
+ [InlineData(false, null)]
+ [InlineData(false, new string[] { "--use-program-main" })]
[SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/30825", Queues = "All.OSX")]
- public Task BlazorServerTemplateWorks_IndividualAuth(bool useLocalDB) => CreateBuildPublishAsync("blazorserverindividual" + (useLocalDB ? "uld" : ""));
+ public Task BlazorServerTemplateWorks_IndividualAuth(bool useLocalDB, string[] args) => CreateBuildPublishAsync("blazorserverindividual" + (useLocalDB ? "uld" : "", args: args));
[Theory]
[InlineData("IndividualB2C", null)]
[InlineData("IndividualB2C", new string[] { "--called-api-url \"https://graph.microsoft.com\"", "--called-api-scopes user.readwrite" })]
+ [InlineData("IndividualB2C", new string[] { "--use-program-main", "--called-api-url \"https://graph.microsoft.com\"", "--called-api-scopes user.readwrite" })]
[InlineData("SingleOrg", null)]
[InlineData("SingleOrg", new string[] { "--called-api-url \"https://graph.microsoft.com\"", "--called-api-scopes user.readwrite" })]
+ [InlineData("SingleOrg", new string[] { "--use-program-main --called-api-url \"https://graph.microsoft.com\"", "--called-api-scopes user.readwrite" })]
[InlineData("SingleOrg", new string[] { "--calls-graph" })]
+ [InlineData("SingleOrg", new string[] { "--use-program-main --calls-graph" })]
public Task BlazorServerTemplate_IdentityWeb_BuildAndPublish(string auth, string[] args)
=> CreateBuildPublishAsync("blazorserveridweb" + Guid.NewGuid().ToString().Substring(0, 10).ToLowerInvariant(), auth, args);
diff --git a/src/ProjectTemplates/test/BlazorWasmTemplateTest.cs b/src/ProjectTemplates/test/BlazorWasmTemplateTest.cs
index 223c0259eb..aad7638674 100644
--- a/src/ProjectTemplates/test/BlazorWasmTemplateTest.cs
+++ b/src/ProjectTemplates/test/BlazorWasmTemplateTest.cs
@@ -38,6 +38,9 @@ public class BlazorWasmTemplateTest : BlazorTemplateTest
public Task BlazorWasmHostedTemplateCanCreateBuildPublish() => CreateBuildPublishAsync("blazorhosted", args: new[] { "--hosted" }, serverProject: true);
[Fact]
+ public Task BlazorWasmHostedTemplateWithProgamMainCanCreateBuildPublish() => CreateBuildPublishAsync("blazorhosted", args: new[] { "--use-program-main", "--hosted" }, serverProject: true);
+
+ [Fact]
public Task BlazorWasmStandalonePwaTemplateCanCreateBuildPublish() => CreateBuildPublishAsync("blazorstandalonepwa", args: new[] { "--pwa" });
[Fact]
diff --git a/src/ProjectTemplates/test/EmptyWebTemplateTest.cs b/src/ProjectTemplates/test/EmptyWebTemplateTest.cs
index b37648b65a..addfd26c81 100644
--- a/src/ProjectTemplates/test/EmptyWebTemplateTest.cs
+++ b/src/ProjectTemplates/test/EmptyWebTemplateTest.cs
@@ -38,17 +38,24 @@ public class EmptyWebTemplateTest : LoggedTest
await EmtpyTemplateCore(languageOverride: null);
}
+ [ConditionalFact]
+ [SkipOnHelix("Cert failure, https://github.com/dotnet/aspnetcore/issues/28090", Queues = "All.OSX;" + HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
+ public async Task EmptyWebTemplateProgramMainCSharp()
+ {
+ await EmtpyTemplateCore(languageOverride: null, args: new [] { "--use-program-main" });
+ }
+
[Fact]
public async Task EmptyWebTemplateFSharp()
{
await EmtpyTemplateCore("F#");
}
- private async Task EmtpyTemplateCore(string languageOverride)
+ private async Task EmtpyTemplateCore(string languageOverride, string[] args = null)
{
var project = await ProjectFactory.GetOrCreateProject("empty" + (languageOverride == "F#" ? "fsharp" : "csharp"), Output);
- var createResult = await project.RunDotNetNewAsync("web", language: languageOverride);
+ var createResult = await project.RunDotNetNewAsync("web", args: args, language: languageOverride);
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", project, createResult));
// Avoid the F# compiler. See https://github.com/dotnet/aspnetcore/issues/14022
diff --git a/src/ProjectTemplates/test/GrpcTemplateTest.cs b/src/ProjectTemplates/test/GrpcTemplateTest.cs
index 5a94bfc9f0..e7cbf12621 100644
--- a/src/ProjectTemplates/test/GrpcTemplateTest.cs
+++ b/src/ProjectTemplates/test/GrpcTemplateTest.cs
@@ -34,14 +34,17 @@ public class GrpcTemplateTest : LoggedTest
}
}
- [ConditionalFact]
+ [ConditionalTheory]
[SkipOnHelix("Not supported queues", Queues = "All.OSX;" + HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
[SkipOnAlpine("https://github.com/grpc/grpc/issues/18338")]
- public async Task GrpcTemplate()
+ [InlineData(true)]
+ [InlineData(false)]
+ public async Task GrpcTemplate(bool useProgramMain)
{
var project = await ProjectFactory.GetOrCreateProject("grpc", Output);
- var createResult = await project.RunDotNetNewAsync("grpc");
+ var args = useProgramMain ? new [] { "--use-program-main" } : null;
+ var createResult = await project.RunDotNetNewAsync("grpc", args: args);
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", project, createResult));
var publishResult = await project.RunDotNetPublishAsync();
diff --git a/src/ProjectTemplates/test/MvcTemplateTest.cs b/src/ProjectTemplates/test/MvcTemplateTest.cs
index 5ccdf8e675..340e13b58c 100644
--- a/src/ProjectTemplates/test/MvcTemplateTest.cs
+++ b/src/ProjectTemplates/test/MvcTemplateTest.cs
@@ -36,11 +36,15 @@ public class MvcTemplateTest : LoggedTest
[SkipOnHelix("Cert failure, https://github.com/dotnet/aspnetcore/issues/28090", Queues = "All.OSX;" + HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
public async Task MvcTemplate_NoAuthCSharp() => await MvcTemplateCore(languageOverride: null);
- private async Task MvcTemplateCore(string languageOverride)
+ [ConditionalFact]
+ [SkipOnHelix("Cert failure, https://github.com/dotnet/aspnetcore/issues/28090", Queues = "All.OSX;" + HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
+ public async Task MvcTemplate_ProgramMainNoAuthCSharp() => await MvcTemplateCore(languageOverride: null, new [] { "--use-program-main" });
+
+ private async Task MvcTemplateCore(string languageOverride, string[] args = null)
{
var project = await ProjectFactory.GetOrCreateProject("mvcnoauth" + (languageOverride == "F#" ? "fsharp" : "csharp"), Output);
- var createResult = await project.RunDotNetNewAsync("mvc", language: languageOverride);
+ var createResult = await project.RunDotNetNewAsync("mvc", language: languageOverride, args: args);
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", project, createResult));
var projectExtension = languageOverride == "F#" ? "fsproj" : "csproj";
@@ -109,14 +113,17 @@ public class MvcTemplateTest : LoggedTest
}
[ConditionalTheory]
- [InlineData(true)]
- [InlineData(false)]
+ [InlineData(true, false)]
+ [InlineData(true, true)]
+ [InlineData(false, false)]
+ [InlineData(false, true)]
[SkipOnHelix("Cert failure, https://github.com/dotnet/aspnetcore/issues/28090", Queues = "All.OSX;" + HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
- public async Task MvcTemplate_IndividualAuth(bool useLocalDB)
+ public async Task MvcTemplate_IndividualAuth(bool useLocalDB, bool useProgramMain)
{
var project = await ProjectFactory.GetOrCreateProject("mvcindividual" + (useLocalDB ? "uld" : ""), Output);
- var createResult = await project.RunDotNetNewAsync("mvc", auth: "Individual", useLocalDB: useLocalDB);
+ var args = useProgramMain ? new [] { "--use-program-main" } : null;
+ var createResult = await project.RunDotNetNewAsync("mvc", auth: "Individual", useLocalDB: useLocalDB, args: args);
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", project, createResult));
var projectFileContents = project.ReadFile($"{project.ProjectName}.csproj");
diff --git a/src/ProjectTemplates/test/RazorPagesTemplateTest.cs b/src/ProjectTemplates/test/RazorPagesTemplateTest.cs
index 4534c66426..c56cc9762a 100644
--- a/src/ProjectTemplates/test/RazorPagesTemplateTest.cs
+++ b/src/ProjectTemplates/test/RazorPagesTemplateTest.cs
@@ -34,13 +34,16 @@ public class RazorPagesTemplateTest : LoggedTest
}
}
- [ConditionalFact]
+ [ConditionalTheory]
[SkipOnHelix("Cert failure, https://github.com/dotnet/aspnetcore/issues/28090", Queues = "All.OSX;" + HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
- public async Task RazorPagesTemplate_NoAuth()
+ [InlineData(true)]
+ [InlineData(false)]
+ public async Task RazorPagesTemplate_NoAuth(bool useProgramMain)
{
var project = await ProjectFactory.GetOrCreateProject("razorpagesnoauth", Output);
- var createResult = await project.RunDotNetNewAsync("razor");
+ var args = useProgramMain ? new [] { "--use-program-main" } : null;
+ var createResult = await project.RunDotNetNewAsync("razor", args: args);
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("razor", project, createResult));
var projectFileContents = ReadFile(project.TemplateOutputDir, $"{project.ProjectName}.csproj");
@@ -104,14 +107,17 @@ public class RazorPagesTemplateTest : LoggedTest
}
[ConditionalTheory]
- [InlineData(false)]
- [InlineData(true)]
+ [InlineData(false, false)]
+ [InlineData(false, true)]
+ [InlineData(true, false)]
+ [InlineData(true, true)]
[SkipOnHelix("Cert failure, https://github.com/dotnet/aspnetcore/issues/28090", Queues = "All.OSX;" + HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
- public async Task RazorPagesTemplate_IndividualAuth(bool useLocalDB)
+ public async Task RazorPagesTemplate_IndividualAuth(bool useLocalDB, bool useProgramMain)
{
var project = await ProjectFactory.GetOrCreateProject("razorpagesindividual" + (useLocalDB ? "uld" : ""), Output);
- var createResult = await project.RunDotNetNewAsync("razor", auth: "Individual", useLocalDB: useLocalDB);
+ var args = useProgramMain ? new [] { "--use-program-main" } : null;
+ var createResult = await project.RunDotNetNewAsync("razor", auth: "Individual", useLocalDB: useLocalDB, args: args);
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", project, createResult));
var projectFileContents = ReadFile(project.TemplateOutputDir, $"{project.ProjectName}.csproj");
@@ -226,12 +232,15 @@ public class RazorPagesTemplateTest : LoggedTest
[SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/28090", Queues = HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
[InlineData("IndividualB2C", null)]
[InlineData("IndividualB2C", new string[] { "--called-api-url \"https://graph.microsoft.com\"", "--called-api-scopes user.readwrite" })]
+ [InlineData("IndividualB2C", new string[] { "--use-program-main --called-api-url \"https://graph.microsoft.com\"", "--called-api-scopes user.readwrite" })]
[InlineData("SingleOrg", null)]
[InlineData("SingleOrg", new string[] { "--called-api-url \"https://graph.microsoft.com\"", "--called-api-scopes user.readwrite" })]
+ [InlineData("SingleOrg", new string[] { "--use-program-main --called-api-url \"https://graph.microsoft.com\"", "--called-api-scopes user.readwrite" })]
public Task RazorPagesTemplate_IdentityWeb_BuildsAndPublishes(string auth, string[] args) => BuildAndPublishRazorPagesTemplate(auth: auth, args: args);
[ConditionalTheory]
[InlineData("SingleOrg", new string[] { "--calls-graph" })]
+ [InlineData("SingleOrg", new string[] { "--use-program-main --calls-graph" })]
public Task RazorPagesTemplate_IdentityWeb_BuildsAndPublishes_WithSingleOrg(string auth, string[] args) => BuildAndPublishRazorPagesTemplate(auth: auth, args: args);
private async Task<Project> BuildAndPublishRazorPagesTemplate(string auth, string[] args)
diff --git a/src/ProjectTemplates/test/WebApiTemplateTest.cs b/src/ProjectTemplates/test/WebApiTemplateTest.cs
index 6d3889bce6..76425a7257 100644
--- a/src/ProjectTemplates/test/WebApiTemplateTest.cs
+++ b/src/ProjectTemplates/test/WebApiTemplateTest.cs
@@ -35,10 +35,15 @@ public class WebApiTemplateTest : LoggedTest
[ConditionalTheory]
[SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/28090", Queues = HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
[InlineData("IndividualB2C", null)]
+ [InlineData("IndividualB2C", new string[] { "--use-program-main" })]
[InlineData("IndividualB2C", new string[] { "--called-api-url \"https://graph.microsoft.com\"", "--called-api-scopes user.readwrite" })]
+ [InlineData("IndividualB2C", new string[] { "--use-program-main --called-api-url \"https://graph.microsoft.com\"", "--called-api-scopes user.readwrite" })]
[InlineData("SingleOrg", null)]
+ [InlineData("SingleOrg", new string[] { "--use-program-main" })]
[InlineData("SingleOrg", new string[] { "--called-api-url \"https://graph.microsoft.com\"", "--called-api-scopes user.readwrite" })]
+ [InlineData("SingleOrg", new string[] { "--use-program-main --called-api-url \"https://graph.microsoft.com\"", "--called-api-scopes user.readwrite" })]
[InlineData("SingleOrg", new string[] { "--calls-graph" })]
+ [InlineData("SingleOrg", new string[] { "--use-program-main --calls-graph" })]
public Task WebApiTemplateCSharp_IdentityWeb_BuildsAndPublishes(string auth, string[] args) => PublishAndBuildWebApiTemplate(languageOverride: null, auth: auth, args: args);
[Fact]
@@ -50,11 +55,18 @@ public class WebApiTemplateTest : LoggedTest
[ConditionalFact]
[SkipOnHelix("Cert failure, https://github.com/dotnet/aspnetcore/issues/28090", Queues = "All.OSX;" + HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
- public async Task WebApiTemplateCSharp_WithoutOpenAPI()
+ public Task WebApiTemplateProgramMainCSharp() => WebApiTemplateCore(languageOverride: null, args: new [] { "--use-program-main" });
+
+ [ConditionalTheory]
+ [InlineData(false)]
+ [InlineData(true)]
+ [SkipOnHelix("Cert failure, https://github.com/dotnet/aspnetcore/issues/28090", Queues = "All.OSX;" + HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
+ public async Task WebApiTemplateCSharp_WithoutOpenAPI(bool useProgramMain)
{
var project = await FactoryFixture.GetOrCreateProject("webapinoopenapi", Output);
- var createResult = await project.RunDotNetNewAsync("webapi", args: new[] { "--no-openapi" });
+ var args = useProgramMain ? new[] { "--use-program-main --no-openapi" } : new[] { "--no-openapi" };
+ var createResult = await project.RunDotNetNewAsync("webapi", args: args);
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", project, createResult));
var buildResult = await project.RunDotNetBuildAsync();
@@ -68,7 +80,7 @@ public class WebApiTemplateTest : LoggedTest
await aspNetProcess.AssertNotFound("swagger");
}
- private async Task<Project> PublishAndBuildWebApiTemplate(string languageOverride, string auth, string[] args)
+ private async Task<Project> PublishAndBuildWebApiTemplate(string languageOverride, string auth, string[] args = null)
{
var project = await FactoryFixture.GetOrCreateProject("webapi" + (languageOverride == "F#" ? "fsharp" : "csharp") + Guid.NewGuid().ToString().Substring(0, 10).ToLowerInvariant(), Output);
@@ -94,9 +106,9 @@ public class WebApiTemplateTest : LoggedTest
return project;
}
- private async Task WebApiTemplateCore(string languageOverride)
+ private async Task WebApiTemplateCore(string languageOverride, string[] args = null)
{
- var project = await PublishAndBuildWebApiTemplate(languageOverride, null, null);
+ var project = await PublishAndBuildWebApiTemplate(languageOverride, null, args);
// Avoid the F# compiler. See https://github.com/dotnet/aspnetcore/issues/14022
if (languageOverride != null)
diff --git a/src/ProjectTemplates/test/WorkerTemplateTest.cs b/src/ProjectTemplates/test/WorkerTemplateTest.cs
index c1d2e961a8..8af59b84fe 100644
--- a/src/ProjectTemplates/test/WorkerTemplateTest.cs
+++ b/src/ProjectTemplates/test/WorkerTemplateTest.cs
@@ -32,16 +32,17 @@ public class WorkerTemplateTest : LoggedTest
[ConditionalTheory]
[OSSkipCondition(OperatingSystems.Linux, SkipReason = "https://github.com/dotnet/sdk/issues/12831")]
- [InlineData("C#")]
- [InlineData("F#")]
+ [InlineData("C#", null)]
+ [InlineData("C#", new string[] { "--use-program-main" })]
+ [InlineData("F#", null)]
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/25404")]
- public async Task WorkerTemplateAsync(string language)
+ public async Task WorkerTemplateAsync(string language, string[] args)
{
var project = await ProjectFactory.GetOrCreateProject(
$"worker-{ language.ToLowerInvariant()[0] }sharp",
Output);
- var createResult = await project.RunDotNetNewAsync("worker", language: language);
+ var createResult = await project.RunDotNetNewAsync("worker", language: language, args: args);
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", project, createResult));
var publishResult = await project.RunDotNetPublishAsync();
diff --git a/src/Security/Authentication/Cookies/src/CookieAuthenticationEvents.cs b/src/Security/Authentication/Cookies/src/CookieAuthenticationEvents.cs
index 613d9fab67..1b13746bb2 100644
--- a/src/Security/Authentication/Cookies/src/CookieAuthenticationEvents.cs
+++ b/src/Security/Authentication/Cookies/src/CookieAuthenticationEvents.cs
@@ -109,10 +109,16 @@ public class CookieAuthenticationEvents
}
/// <summary>
- /// Invoked to validate the prinicipal.
+ /// Invoked to validate the principal.
/// </summary>
/// <param name="context">The <see cref="CookieValidatePrincipalContext"/>.</param>
public virtual Task ValidatePrincipal(CookieValidatePrincipalContext context) => OnValidatePrincipal(context);
+
+ /// <summary>
+ /// Invoked to check if the cookie should be renewed.
+ /// </summary>
+ /// <param name="context">The <see cref="CookieSlidingExpirationContext"/>.</param>
+ public virtual Task CheckSlidingExpiration(CookieSlidingExpirationContext context) => OnCheckSlidingExpiration(context);
/// <summary>
/// Invoked during sign in.
diff --git a/src/Security/Authentication/Cookies/src/CookieAuthenticationHandler.cs b/src/Security/Authentication/Cookies/src/CookieAuthenticationHandler.cs
index 8300d7fcaf..7cfa4f94bb 100644
--- a/src/Security/Authentication/Cookies/src/CookieAuthenticationHandler.cs
+++ b/src/Security/Authentication/Cookies/src/CookieAuthenticationHandler.cs
@@ -93,7 +93,7 @@ public class CookieAuthenticationHandler : SignInAuthenticationHandler<CookieAut
{
ShouldRenew = timeRemaining < timeElapsed,
};
- await Options.Events.OnCheckSlidingExpiration(eventContext);
+ await Options.Events.CheckSlidingExpiration(eventContext);
if (eventContext.ShouldRenew)
{
diff --git a/src/Security/Authentication/Cookies/src/PublicAPI.Unshipped.txt b/src/Security/Authentication/Cookies/src/PublicAPI.Unshipped.txt
index 9ed3fc11d3..899d7d2843 100644
--- a/src/Security/Authentication/Cookies/src/PublicAPI.Unshipped.txt
+++ b/src/Security/Authentication/Cookies/src/PublicAPI.Unshipped.txt
@@ -1,3 +1,4 @@
#nullable enable
*REMOVED*Microsoft.AspNetCore.Authentication.Cookies.PostConfigureCookieAuthenticationOptions.PostConfigure(string! name, Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions! options) -> void
Microsoft.AspNetCore.Authentication.Cookies.PostConfigureCookieAuthenticationOptions.PostConfigure(string? name, Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions! options) -> void
+virtual Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationEvents.CheckSlidingExpiration(Microsoft.AspNetCore.Authentication.Cookies.CookieSlidingExpirationContext! context) -> System.Threading.Tasks.Task!
diff --git a/src/Security/Authentication/test/CertificateTests.cs b/src/Security/Authentication/test/CertificateTests.cs
index f69360da79..03fd439a36 100644
--- a/src/Security/Authentication/test/CertificateTests.cs
+++ b/src/Security/Authentication/test/CertificateTests.cs
@@ -153,7 +153,7 @@ public class ClientCertificateAuthenticationTests
}
[ConditionalFact]
- [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/32813", Queues = "All.Ubuntu")]
+ [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/32813", Queues = $"All.Ubuntu;{HelixConstants.RedhatAmd64}")]
public async Task VerifyExpiredSelfSignedFails()
{
using var host = await CreateHost(
@@ -188,7 +188,7 @@ public class ClientCertificateAuthenticationTests
}
[ConditionalFact]
- [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/32813", Queues = "All.Ubuntu")]
+ [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/32813", Queues = $"All.Ubuntu;{HelixConstants.RedhatAmd64}")]
public async Task VerifyNotYetValidSelfSignedFails()
{
using var host = await CreateHost(
diff --git a/src/Servers/IIS/IIS/perf/Microbenchmarks/PlaintextBenchmark.cs b/src/Servers/IIS/IIS/perf/Microbenchmarks/PlaintextBenchmark.cs
index ee38cb1588..a98b53326b 100644
--- a/src/Servers/IIS/IIS/perf/Microbenchmarks/PlaintextBenchmark.cs
+++ b/src/Servers/IIS/IIS/perf/Microbenchmarks/PlaintextBenchmark.cs
@@ -27,7 +27,8 @@ public class PlaintextBenchmark
// Recreate client, TestServer.Client has additional logging that can hurt performance
_client = new HttpClient()
{
- BaseAddress = _server.HttpClient.BaseAddress
+ BaseAddress = _server.HttpClient.BaseAddress,
+ Timeout = TimeSpan.FromSeconds(200),
};
}
diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/CompressionTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/CompressionTests.cs
index cc8f46bbb9..20278b0aa1 100644
--- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/CompressionTests.cs
+++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/CompressionTests.cs
@@ -130,6 +130,7 @@ public class CompressionTests : FixtureLoggedTest
var client = new HttpClient(handler)
{
BaseAddress = _fixture.Client.BaseAddress,
+ Timeout = TimeSpan.FromSeconds(200),
};
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("identity", 0));
diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/FrebTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/FrebTests.cs
index 24cceea63a..ea01504eca 100644
--- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/FrebTests.cs
+++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/FrebTests.cs
@@ -90,10 +90,7 @@ public class FrebTests : IISFunctionalTestBase
AssertFrebLogs(result, new FrebLogItem("ANCM_INPROC_ASYNC_COMPLETION_COMPLETION", "2"));
}
- // I think this test is flaky due to freb file not being created quickly enough.
- // Adding extra logging, marking as flaky, and repeating should help
[ConditionalFact]
- [Repeat(10)]
[RequiresIIS(IISCapability.FailedRequestTracingModule)]
public async Task CheckFrebDisconnect()
{
diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Http2Tests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Http2Tests.cs
index e069cc2976..34906e32e4 100644
--- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Http2Tests.cs
+++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Http2Tests.cs
@@ -356,7 +356,7 @@ public class Http2Tests
{
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
- using HttpClient client = new HttpClient(handler);
+ using var client = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(200) };
client.DefaultRequestVersion = HttpVersion.Version11;
var response = await client.GetStringAsync(Fixture.Client.BaseAddress + "Reset_Http1_NotSupported");
Assert.Equal("Hello World", response);
@@ -370,7 +370,7 @@ public class Http2Tests
{
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
- using HttpClient client = new HttpClient(handler);
+ using var client = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(200) };
client.DefaultRequestVersion = HttpVersion.Version20;
var response = await client.GetStringAsync(Fixture.Client.BaseAddress + "Reset_PriorOSVersions_NotSupported");
Assert.Equal("Hello World", response);
@@ -390,7 +390,7 @@ public class Http2Tests
var handler = new HttpClientHandler();
handler.MaxResponseHeadersLength = 128;
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
- using var client = new HttpClient(handler);
+ using var client = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(200) };
client.DefaultRequestVersion = http2 ? HttpVersion.Version20 : HttpVersion.Version11;
return await client.GetAsync(uri);
}
diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Infrastructure/EventLogHelpers.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Infrastructure/EventLogHelpers.cs
index a6b41e9e07..2830ffaed2 100644
--- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Infrastructure/EventLogHelpers.cs
+++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Infrastructure/EventLogHelpers.cs
@@ -88,7 +88,7 @@ public class EventLogHelpers
var processIdString = $"Process Id: {deploymentResult.HostProcess.Id}.";
// Event log messages round down to the nearest second, so subtract 5 seconds to make sure we get event logs
- var processStartTime = deploymentResult.HostProcess.StartTime.AddSeconds(-5);
+ var processStartTime = deploymentResult.HostProcess.StartTime.AddSeconds(-10);
for (var i = eventLog.Entries.Count - 1; i >= 0; i--)
{
var eventLogEntry = eventLog.Entries[i];
diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Infrastructure/Helpers.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Infrastructure/Helpers.cs
index af3e945d1f..0b8c5bbeff 100644
--- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Infrastructure/Helpers.cs
+++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Infrastructure/Helpers.cs
@@ -1,19 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using System;
-using System.Collections.Generic;
using System.Diagnostics;
-using System.IO;
-using System.Linq;
+using System.Net;
using System.Net.Http;
-using System.Threading.Tasks;
using System.Xml.Linq;
using Microsoft.AspNetCore.Server.IntegrationTesting;
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
-using Xunit;
namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests;
@@ -29,18 +24,28 @@ public static class Helpers
public static async Task AssertStarts(this IISDeploymentResult deploymentResult, string path = "/HelloWorld")
{
- var response = await deploymentResult.HttpClient.GetAsync(path);
-
+ // Sometimes the site is not ready, so retry until its actually started and ready
+ var response = await deploymentResult.HttpClient.RetryRequestAsync(path, r => r.IsSuccessStatusCode);
var responseText = await response.Content.ReadAsStringAsync();
-
- Assert.Equal("Hello World", responseText);
+ if (response.IsSuccessStatusCode)
+ {
+ Assert.Equal("Hello World", responseText);
+ }
+ else
+ {
+ throw new Exception($"Server not started successfully, recieved non success status code, responseText: {responseText}");
+ }
}
public static async Task StressLoad(HttpClient httpClient, string path, Action<HttpResponseMessage> action)
{
async Task RunRequests()
{
- var connection = new HttpClient() { BaseAddress = httpClient.BaseAddress };
+ var connection = new HttpClient()
+ {
+ BaseAddress = httpClient.BaseAddress,
+ Timeout = TimeSpan.FromSeconds(200),
+ };
for (int j = 0; j < 10; j++)
{
diff --git a/src/Servers/IIS/IIS/test/Common.LongTests/StartupTests.cs b/src/Servers/IIS/IIS/test/Common.LongTests/StartupTests.cs
index b2599611d7..3ea9955b98 100644
--- a/src/Servers/IIS/IIS/test/Common.LongTests/StartupTests.cs
+++ b/src/Servers/IIS/IIS/test/Common.LongTests/StartupTests.cs
@@ -410,7 +410,7 @@ public class StartupTests : IISFunctionalTestBase
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
var responseContent = await response.Content.ReadAsStringAsync();
Assert.Contains("500.31", responseContent);
- Assert.Contains("The framework 'Microsoft.NETCore.App', version '2.9.9'", responseContent);
+ Assert.Contains("Framework: 'Microsoft.NETCore.App', version '2.9.9'", responseContent);
}
else
{
@@ -1354,7 +1354,8 @@ public class StartupTests : IISFunctionalTestBase
};
var client = new HttpClient(handler)
{
- BaseAddress = new Uri(deploymentParameters.ApplicationBaseUriHint)
+ BaseAddress = new Uri(deploymentParameters.ApplicationBaseUriHint),
+ Timeout = TimeSpan.FromSeconds(200),
};
if (DeployerSelector.HasNewHandler)
diff --git a/src/Servers/IIS/IIS/test/IIS.FunctionalTests/Http2TrailersResetTests.cs b/src/Servers/IIS/IIS/test/IIS.FunctionalTests/Http2TrailersResetTests.cs
index 93d959b14a..d05619647b 100644
--- a/src/Servers/IIS/IIS/test/IIS.FunctionalTests/Http2TrailersResetTests.cs
+++ b/src/Servers/IIS/IIS/test/IIS.FunctionalTests/Http2TrailersResetTests.cs
@@ -503,7 +503,7 @@ public class Http2TrailerResetTests : FunctionalTestsBase
var handler = new HttpClientHandler();
handler.MaxResponseHeadersLength = 128;
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
- var client = new HttpClient(handler);
+ var client = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(200) };
return client;
}
@@ -512,7 +512,7 @@ public class Http2TrailerResetTests : FunctionalTestsBase
var handler = new HttpClientHandler();
handler.MaxResponseHeadersLength = 128;
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
- using var client = new HttpClient(handler);
+ using var client = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(200) };
client.DefaultRequestVersion = http2 ? HttpVersion.Version20 : HttpVersion.Version11;
return await client.GetAsync(uri);
}
diff --git a/src/Servers/IIS/IIS/test/IIS.FunctionalTests/Http3Tests.cs b/src/Servers/IIS/IIS/test/IIS.FunctionalTests/Http3Tests.cs
index 41f4fec311..be5022389b 100644
--- a/src/Servers/IIS/IIS/test/IIS.FunctionalTests/Http3Tests.cs
+++ b/src/Servers/IIS/IIS/test/IIS.FunctionalTests/Http3Tests.cs
@@ -173,6 +173,6 @@ public class Http3Tests : FunctionalTestsBase
var handler = new HttpClientHandler();
// Needed on CI, the IIS Express cert we use isn't trusted there.
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
- return new HttpClient(handler);
+ return new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(200) };
}
}
diff --git a/src/Servers/IIS/IIS/test/IIS.Shared.FunctionalTests/StdOutRedirectionTests.cs b/src/Servers/IIS/IIS/test/IIS.Shared.FunctionalTests/StdOutRedirectionTests.cs
index e880e37ac8..260919c6de 100644
--- a/src/Servers/IIS/IIS/test/IIS.Shared.FunctionalTests/StdOutRedirectionTests.cs
+++ b/src/Servers/IIS/IIS/test/IIS.Shared.FunctionalTests/StdOutRedirectionTests.cs
@@ -47,7 +47,9 @@ public class StdOutRedirectionTests : IISFunctionalTestBase
StopServer();
EventLogHelpers.VerifyEventLogEvent(deploymentResult,
- @"The framework 'Microsoft.NETCore.App', version '2.9.9' \(x64\) was not found.", Logger);
+ @"Framework: 'Microsoft.NETCore.App', version '2.9.9' \(x64\)", Logger);
+ EventLogHelpers.VerifyEventLogEvent(deploymentResult,
+ "To install missing framework, download:", Logger);
}
[ConditionalFact]
@@ -69,10 +71,13 @@ public class StdOutRedirectionTests : IISFunctionalTestBase
StopServer();
var contents = Helpers.ReadAllTextFromFile(Helpers.GetExpectedLogName(deploymentResult, LogFolderPath), Logger);
- var expectedString = "The framework 'Microsoft.NETCore.App', version '2.9.9' (x64) was not found.";
+ var missingFrameworkString = "To install missing framework, download:";
+ EventLogHelpers.VerifyEventLogEvent(deploymentResult,
+ @"Framework: 'Microsoft.NETCore.App', version '2.9.9' \(x64\)", Logger);
EventLogHelpers.VerifyEventLogEvent(deploymentResult,
- @"The framework 'Microsoft.NETCore.App', version '2.9.9' \(x64\) was not found.", Logger);
- Assert.Contains(expectedString, contents);
+ missingFrameworkString, Logger);
+ Assert.Contains(@"Framework: 'Microsoft.NETCore.App', version '2.9.9' (x64)", contents);
+ Assert.Contains(missingFrameworkString, contents);
}
[ConditionalFact]
diff --git a/src/Servers/IIS/IIS/test/IIS.Tests/Utilities/TestServer.cs b/src/Servers/IIS/IIS/test/IIS.Tests/Utilities/TestServer.cs
index 3bedbf730b..a4bd602edc 100644
--- a/src/Servers/IIS/IIS/test/IIS.Tests/Utilities/TestServer.cs
+++ b/src/Servers/IIS/IIS/test/IIS.Tests/Utilities/TestServer.cs
@@ -106,7 +106,8 @@ public class TestServer : IDisposable
HttpClient = new HttpClient(new LoggingHandler(new SocketsHttpHandler(), _loggerFactory.CreateLogger<TestServer>()))
{
- BaseAddress = BaseUri
+ BaseAddress = BaseUri,
+ Timeout = TimeSpan.FromSeconds(200),
};
}
diff --git a/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs b/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs
index 5911a68b89..65da17c282 100644
--- a/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs
+++ b/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs
@@ -31,7 +31,7 @@ public class WebSocketsTests
[ConditionalFact]
public async Task RequestWithBody_NotUpgradable()
{
- using var client = new HttpClient();
+ using var client = new HttpClient() { Timeout = TimeSpan.FromSeconds(200) };
using var response = await client.PostAsync(_requestUri + "WebSocketNotUpgradable", new StringContent("Hello World"));
response.EnsureSuccessStatusCode();
}
@@ -39,7 +39,7 @@ public class WebSocketsTests
[ConditionalFact]
public async Task RequestWithoutBody_Upgradable()
{
- using var client = new HttpClient();
+ using var client = new HttpClient() { Timeout = TimeSpan.FromSeconds(200) };
// POST with Content-Length: 0 counts as not having a body.
using var response = await client.PostAsync(_requestUri + "WebSocketUpgradable", new StringContent(""));
response.EnsureSuccessStatusCode();
diff --git a/src/Servers/IIS/IIS/test/testassets/IIS.Common.TestLib/TestConnections.cs b/src/Servers/IIS/IIS/test/testassets/IIS.Common.TestLib/TestConnections.cs
index f61a24d099..5e470444ed 100644
--- a/src/Servers/IIS/IIS/test/testassets/IIS.Common.TestLib/TestConnections.cs
+++ b/src/Servers/IIS/IIS/test/testassets/IIS.Common.TestLib/TestConnections.cs
@@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting;
/// </summary>
public class TestConnection : IDisposable
{
- private static readonly TimeSpan Timeout = TimeSpan.FromMinutes(1);
+ private static readonly TimeSpan Timeout = TimeSpan.FromMinutes(2);
private readonly bool _ownsSocket;
private readonly Socket _socket;
diff --git a/src/Servers/IIS/IIS/test/testassets/IIS.Common.TestLib/TimeoutExtensions.cs b/src/Servers/IIS/IIS/test/testassets/IIS.Common.TestLib/TimeoutExtensions.cs
index 1031829c15..6651f4cf5a 100644
--- a/src/Servers/IIS/IIS/test/testassets/IIS.Common.TestLib/TimeoutExtensions.cs
+++ b/src/Servers/IIS/IIS/test/testassets/IIS.Common.TestLib/TimeoutExtensions.cs
@@ -10,5 +10,5 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting;
public static class TimeoutExtensions
{
- public static TimeSpan DefaultTimeoutValue = TimeSpan.FromSeconds(300);
+ public static TimeSpan DefaultTimeoutValue = TimeSpan.FromMinutes(10);
}
diff --git a/src/Servers/IIS/IISIntegration/test/Tests/IISMiddlewareTests.cs b/src/Servers/IIS/IISIntegration/test/Tests/IISMiddlewareTests.cs
index 15fb0ec4d4..d431f8925b 100644
--- a/src/Servers/IIS/IISIntegration/test/Tests/IISMiddlewareTests.cs
+++ b/src/Servers/IIS/IISIntegration/test/Tests/IISMiddlewareTests.cs
@@ -135,7 +135,7 @@ public class IISMiddlewareTests
request.Headers.TryAddWithoutValidation("MS-ASPNETCORE-EVENT", shutdownEvent);
var response = await server.CreateClient().SendAsync(request);
- await applicationStoppingFired.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
+ await applicationStoppingFired.Task.TimeoutAfter(TimeSpan.FromSeconds(10));
Assert.False(requestExecuted.Task.IsCompleted);
Assert.Equal(HttpStatusCode.Accepted, response.StatusCode);
}
@@ -195,7 +195,7 @@ public class IISMiddlewareTests
var response = await server.CreateClient().SendAsync(request);
Assert.False(applicationStoppingFired.Task.IsCompleted);
- await requestExecuted.Task.TimeoutAfter(TimeSpan.FromSeconds(1));
+ await requestExecuted.Task.TimeoutAfter(TimeSpan.FromSeconds(2));
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
@@ -240,7 +240,7 @@ public class IISMiddlewareTests
var response = await server.CreateClient().SendAsync(request);
Assert.False(applicationStoppingFired.Task.IsCompleted);
- await requestExecuted.Task.TimeoutAfter(TimeSpan.FromSeconds(1));
+ await requestExecuted.Task.TimeoutAfter(TimeSpan.FromSeconds(2));
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
@@ -285,7 +285,7 @@ public class IISMiddlewareTests
var response = await server.CreateClient().SendAsync(request);
Assert.False(applicationStoppingFired.Task.IsCompleted);
- await requestExecuted.Task.TimeoutAfter(TimeSpan.FromSeconds(1));
+ await requestExecuted.Task.TimeoutAfter(TimeSpan.FromSeconds(2));
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
diff --git a/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeploymentResult.cs b/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeploymentResult.cs
index b81c145ee7..043852daa8 100644
--- a/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeploymentResult.cs
+++ b/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeploymentResult.cs
@@ -33,7 +33,8 @@ public class IISDeploymentResult : DeploymentResult
{
return new HttpClient(new LoggingHandler(messageHandler, Logger))
{
- BaseAddress = base.HttpClient.BaseAddress
+ BaseAddress = base.HttpClient.BaseAddress,
+ Timeout = TimeSpan.FromSeconds(200),
};
}
diff --git a/src/Servers/IIS/IntegrationTesting.IIS/src/IISExpressDeployer.cs b/src/Servers/IIS/IntegrationTesting.IIS/src/IISExpressDeployer.cs
index 927222da0f..9c3b101371 100644
--- a/src/Servers/IIS/IntegrationTesting.IIS/src/IISExpressDeployer.cs
+++ b/src/Servers/IIS/IntegrationTesting.IIS/src/IISExpressDeployer.cs
@@ -21,7 +21,7 @@ public class IISExpressDeployer : IISDeployerBase
private const string FailedToInitializeBindingsMessage = "Failed to initialize site bindings";
private const string UnableToStartIISExpressMessage = "Unable to start iisexpress.";
private const int MaximumAttempts = 5;
- private readonly TimeSpan ShutdownTimeSpan = Debugger.IsAttached ? TimeSpan.FromMinutes(60) : TimeSpan.FromMinutes(1);
+ private readonly TimeSpan ShutdownTimeSpan = Debugger.IsAttached ? TimeSpan.FromMinutes(60) : TimeSpan.FromMinutes(2);
private static readonly Regex UrlDetectorRegex = new Regex(@"^\s*Successfully registered URL ""(?<url>[^""]+)"" for site.*$");
private Process _hostProcess;
@@ -234,10 +234,10 @@ public class IISExpressDeployer : IISDeployerBase
}
// Wait for the app to start
- // The timeout here is large, because we don't know how long the test could need
- // We cover a lot of error cases above, but I want to make sure we eventually give up and don't hang the build
+ // The timeout here is large, because we don't know how long the test could need. We cover a lot
+ // of error cases above, but I want to make sure we eventually give up and don't hang the build
// just in case we missed one -anurse
- if (!await started.Task.TimeoutAfter(TimeSpan.FromMinutes(10)))
+ if (!await started.Task.TimeoutAfter(TimeSpan.FromMinutes(15)))
{
Logger.LogInformation("iisexpress Process {pid} failed to bind to port {port}, trying again", process.Id, port);
diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs
index d04e6b74c6..cec7e6d535 100644
--- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs
+++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs
@@ -172,8 +172,19 @@ internal class Http2FrameWriter
| Padding (*) ...
+---------------------------------------------------------------+
*/
- public void WriteResponseHeaders(int streamId, int statusCode, Http2HeadersFrameFlags headerFrameFlags, HttpResponseHeaders headers)
+ public void WriteResponseHeaders(Http2Stream stream, int statusCode, bool endStream, HttpResponseHeaders headers)
{
+ Http2HeadersFrameFlags headerFrameFlags;
+ if (endStream)
+ {
+ headerFrameFlags = Http2HeadersFrameFlags.END_STREAM;
+ stream.DecrementActiveClientStreamCount();
+ }
+ else
+ {
+ headerFrameFlags = Http2HeadersFrameFlags.NONE;
+ }
+
lock (_writeLock)
{
if (_completed)
@@ -184,24 +195,26 @@ internal class Http2FrameWriter
try
{
_headersEnumerator.Initialize(headers);
- _outgoingFrame.PrepareHeaders(headerFrameFlags, streamId);
+ _outgoingFrame.PrepareHeaders(headerFrameFlags, stream.StreamId);
var buffer = _headerEncodingBuffer.AsSpan();
var done = HPackHeaderWriter.BeginEncodeHeaders(statusCode, _hpackEncoder, _headersEnumerator, buffer, out var payloadLength);
- FinishWritingHeaders(streamId, payloadLength, done);
+ FinishWritingHeaders(stream.StreamId, payloadLength, done);
}
// Any exception from the HPack encoder can leave the dynamic table in a corrupt state.
// Since we allow custom header encoders we don't know what type of exceptions to expect.
catch (Exception ex)
{
- _log.HPackEncodingError(_connectionId, streamId, ex);
+ _log.HPackEncodingError(_connectionId, stream.StreamId, ex);
_http2Connection.Abort(new ConnectionAbortedException(ex.Message, ex));
throw new InvalidOperationException(ex.Message, ex); // Report the error to the user if this was the first write.
}
}
}
- public ValueTask<FlushResult> WriteResponseTrailersAsync(int streamId, HttpResponseTrailers headers)
+ public ValueTask<FlushResult> WriteResponseTrailersAsync(Http2Stream stream, HttpResponseTrailers headers)
{
+ stream.DecrementActiveClientStreamCount();
+
lock (_writeLock)
{
if (_completed)
@@ -212,16 +225,16 @@ internal class Http2FrameWriter
try
{
_headersEnumerator.Initialize(headers);
- _outgoingFrame.PrepareHeaders(Http2HeadersFrameFlags.END_STREAM, streamId);
+ _outgoingFrame.PrepareHeaders(Http2HeadersFrameFlags.END_STREAM, stream.StreamId);
var buffer = _headerEncodingBuffer.AsSpan();
var done = HPackHeaderWriter.BeginEncodeHeaders(_hpackEncoder, _headersEnumerator, buffer, out var payloadLength);
- FinishWritingHeaders(streamId, payloadLength, done);
+ FinishWritingHeaders(stream.StreamId, payloadLength, done);
}
// Any exception from the HPack encoder can leave the dynamic table in a corrupt state.
// Since we allow custom header encoders we don't know what type of exceptions to expect.
catch (Exception ex)
{
- _log.HPackEncodingError(_connectionId, streamId, ex);
+ _log.HPackEncodingError(_connectionId, stream.StreamId, ex);
_http2Connection.Abort(new ConnectionAbortedException(ex.Message, ex));
}
@@ -258,7 +271,7 @@ internal class Http2FrameWriter
}
}
- public ValueTask<FlushResult> WriteDataAsync(int streamId, StreamOutputFlowControl flowControl, in ReadOnlySequence<byte> data, bool endStream, bool firstWrite, bool forceFlush)
+ public ValueTask<FlushResult> WriteDataAsync(Http2Stream stream, StreamOutputFlowControl flowControl, in ReadOnlySequence<byte> data, bool endStream, bool firstWrite, bool forceFlush)
{
// Logic in this method is replicated in WriteDataAndTrailersAsync.
// Changes here may need to be mirrored in WriteDataAndTrailersAsync.
@@ -277,12 +290,12 @@ internal class Http2FrameWriter
// https://httpwg.org/specs/rfc7540.html#rfc.section.6.9.1
if (dataLength != 0 && dataLength > flowControl.Available)
{
- return WriteDataAsync(streamId, flowControl, data, dataLength, endStream, firstWrite);
+ return WriteDataAsync(stream, flowControl, data, dataLength, endStream, firstWrite);
}
// This cast is safe since if dataLength would overflow an int, it's guaranteed to be greater than the available flow control window.
flowControl.Advance((int)dataLength);
- WriteDataUnsynchronized(streamId, data, dataLength, endStream);
+ WriteDataUnsynchronized(stream, data, dataLength, endStream);
if (forceFlush)
{
@@ -293,7 +306,7 @@ internal class Http2FrameWriter
}
}
- public ValueTask<FlushResult> WriteDataAndTrailersAsync(int streamId, StreamOutputFlowControl flowControl, in ReadOnlySequence<byte> data, bool firstWrite, HttpResponseTrailers headers)
+ public ValueTask<FlushResult> WriteDataAndTrailersAsync(Http2Stream stream, StreamOutputFlowControl flowControl, in ReadOnlySequence<byte> data, bool firstWrite, HttpResponseTrailers headers)
{
// This method combines WriteDataAsync and WriteResponseTrailers.
// Changes here may need to be mirrored in WriteDataAsync.
@@ -312,21 +325,21 @@ internal class Http2FrameWriter
// https://httpwg.org/specs/rfc7540.html#rfc.section.6.9.1
if (dataLength != 0 && dataLength > flowControl.Available)
{
- return WriteDataAndTrailersAsyncCore(this, streamId, flowControl, data, dataLength, firstWrite, headers);
+ return WriteDataAndTrailersAsyncCore(this, stream, flowControl, data, dataLength, firstWrite, headers);
}
// This cast is safe since if dataLength would overflow an int, it's guaranteed to be greater than the available flow control window.
flowControl.Advance((int)dataLength);
- WriteDataUnsynchronized(streamId, data, dataLength, endStream: false);
+ WriteDataUnsynchronized(stream, data, dataLength, endStream: false);
- return WriteResponseTrailersAsync(streamId, headers);
+ return WriteResponseTrailersAsync(stream, headers);
}
- static async ValueTask<FlushResult> WriteDataAndTrailersAsyncCore(Http2FrameWriter writer, int streamId, StreamOutputFlowControl flowControl, ReadOnlySequence<byte> data, long dataLength, bool firstWrite, HttpResponseTrailers headers)
+ static async ValueTask<FlushResult> WriteDataAndTrailersAsyncCore(Http2FrameWriter writer, Http2Stream stream, StreamOutputFlowControl flowControl, ReadOnlySequence<byte> data, long dataLength, bool firstWrite, HttpResponseTrailers headers)
{
- await writer.WriteDataAsync(streamId, flowControl, data, dataLength, endStream: false, firstWrite);
+ await writer.WriteDataAsync(stream, flowControl, data, dataLength, endStream: false, firstWrite);
- return await writer.WriteResponseTrailersAsync(streamId, headers);
+ return await writer.WriteResponseTrailersAsync(stream, headers);
}
}
@@ -339,12 +352,12 @@ internal class Http2FrameWriter
| Padding (*) ...
+---------------------------------------------------------------+
*/
- private void WriteDataUnsynchronized(int streamId, in ReadOnlySequence<byte> data, long dataLength, bool endStream)
+ private void WriteDataUnsynchronized(Http2Stream stream, in ReadOnlySequence<byte> data, long dataLength, bool endStream)
{
Debug.Assert(dataLength == data.Length);
// Note padding is not implemented
- _outgoingFrame.PrepareData(streamId);
+ _outgoingFrame.PrepareData(stream.StreamId);
if (dataLength > _maxFrameSize) // Minus padding
{
@@ -352,16 +365,7 @@ internal class Http2FrameWriter
return;
}
- if (endStream)
- {
- _outgoingFrame.DataFlags |= Http2DataFrameFlags.END_STREAM;
- }
-
- _outgoingFrame.PayloadLength = (int)dataLength; // Plus padding
-
- WriteHeaderUnsynchronized();
-
- data.CopyTo(_outputWriter);
+ WriteDataUnsynchronizedCore(stream, endStream, dataLength, data);
// Plus padding
return;
@@ -378,14 +382,8 @@ internal class Http2FrameWriter
do
{
var currentData = remainingData.Slice(0, dataPayloadLength);
- _outgoingFrame.PayloadLength = dataPayloadLength; // Plus padding
- WriteHeaderUnsynchronized();
-
- foreach (var buffer in currentData)
- {
- _outputWriter.Write(buffer.Span);
- }
+ WriteDataUnsynchronizedCore(stream, endStream: false, dataPayloadLength, currentData);
// Plus padding
dataLength -= dataPayloadLength;
@@ -393,25 +391,37 @@ internal class Http2FrameWriter
} while (dataLength > dataPayloadLength);
+ WriteDataUnsynchronizedCore(stream, endStream, dataLength, remainingData);
+
+ // Plus padding
+ }
+
+ void WriteDataUnsynchronizedCore(Http2Stream stream, bool endStream, long dataLength, in ReadOnlySequence<byte> data)
+ {
+ Debug.Assert(dataLength == data.Length);
+
if (endStream)
{
_outgoingFrame.DataFlags |= Http2DataFrameFlags.END_STREAM;
+
+ // When writing data, must decrement active stream count after flow control availability is checked.
+ // If active stream count becomes zero while a graceful shutdown is in progress then the input side of connection is closed.
+ // This is a problem if a large amount of data is being written. The server must keep processing incoming WINDOW_UPDATE frames.
+ // No WINDOW_UPDATE frames means response write could hit flow control and hang.
+ // Decrement also has to happen before writing END_STREAM to client to avoid race over active stream count.
+ stream.DecrementActiveClientStreamCount();
}
+ // It can be expensive to get length from ROS. Use already available value.
_outgoingFrame.PayloadLength = (int)dataLength; // Plus padding
WriteHeaderUnsynchronized();
- foreach (var buffer in remainingData)
- {
- _outputWriter.Write(buffer.Span);
- }
-
- // Plus padding
+ data.CopyTo(_outputWriter);
}
}
- private async ValueTask<FlushResult> WriteDataAsync(int streamId, StreamOutputFlowControl flowControl, ReadOnlySequence<byte> data, long dataLength, bool endStream, bool firstWrite)
+ private async ValueTask<FlushResult> WriteDataAsync(Http2Stream stream, StreamOutputFlowControl flowControl, ReadOnlySequence<byte> data, long dataLength, bool endStream, bool firstWrite)
{
FlushResult flushResult = default;
@@ -436,13 +446,13 @@ internal class Http2FrameWriter
{
if (actual < dataLength)
{
- WriteDataUnsynchronized(streamId, data.Slice(0, actual), actual, endStream: false);
+ WriteDataUnsynchronized(stream, data.Slice(0, actual), actual, endStream: false);
data = data.Slice(actual);
dataLength -= actual;
}
else
{
- WriteDataUnsynchronized(streamId, data, actual, endStream);
+ WriteDataUnsynchronized(stream, data, actual, endStream);
dataLength = 0;
}
diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs
index fb507c02e5..c138befdf1 100644
--- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs
+++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs
@@ -203,20 +203,11 @@ internal class Http2OutputProducer : IHttpOutputProducer, IHttpOutputAborter, IV
// The headers will be the final frame if:
// 1. There is no content
// 2. There is no trailing HEADERS frame.
- Http2HeadersFrameFlags http2HeadersFrame;
+ _streamEnded = appCompleted
+ && !_startedWritingDataFrames
+ && (_stream.ResponseTrailers == null || _stream.ResponseTrailers.Count == 0);
- if (appCompleted && !_startedWritingDataFrames && (_stream.ResponseTrailers == null || _stream.ResponseTrailers.Count == 0))
- {
- _streamEnded = true;
- _stream.DecrementActiveClientStreamCount();
- http2HeadersFrame = Http2HeadersFrameFlags.END_STREAM;
- }
- else
- {
- http2HeadersFrame = Http2HeadersFrameFlags.NONE;
- }
-
- _frameWriter.WriteResponseHeaders(StreamId, statusCode, http2HeadersFrame, responseHeaders);
+ _frameWriter.WriteResponseHeaders(_stream, statusCode, _streamEnded, responseHeaders);
}
}
@@ -429,16 +420,15 @@ internal class Http2OutputProducer : IHttpOutputProducer, IHttpOutputAborter, IV
// Write any remaining content then write trailers
_stream.ResponseTrailers.SetReadOnly();
- _stream.DecrementActiveClientStreamCount();
if (readResult.Buffer.Length > 0)
{
// It is faster to write data and trailers together. Locking once reduces lock contention.
- flushResult = await _frameWriter.WriteDataAndTrailersAsync(StreamId, _flowControl, readResult.Buffer, firstWrite, _stream.ResponseTrailers);
+ flushResult = await _frameWriter.WriteDataAndTrailersAsync(_stream, _flowControl, readResult.Buffer, firstWrite, _stream.ResponseTrailers);
}
else
{
- flushResult = await _frameWriter.WriteResponseTrailersAsync(StreamId, _stream.ResponseTrailers);
+ flushResult = await _frameWriter.WriteResponseTrailersAsync(_stream, _stream.ResponseTrailers);
}
}
else if (readResult.IsCompleted && _streamEnded)
@@ -454,13 +444,7 @@ internal class Http2OutputProducer : IHttpOutputProducer, IHttpOutputAborter, IV
else
{
var endStream = readResult.IsCompleted;
-
- if (endStream)
- {
- _stream.DecrementActiveClientStreamCount();
- }
-
- flushResult = await _frameWriter.WriteDataAsync(StreamId, _flowControl, readResult.Buffer, endStream, firstWrite, forceFlush: true);
+ flushResult = await _frameWriter.WriteDataAsync(_stream, _flowControl, readResult.Buffer, endStream, firstWrite, forceFlush: true);
}
firstWrite = false;
diff --git a/src/Servers/Kestrel/perf/Microbenchmarks/Http2/Http2FrameWriterBenchmark.cs b/src/Servers/Kestrel/perf/Microbenchmarks/Http2/Http2FrameWriterBenchmark.cs
index 3a2844125c..bb5d2d7d8b 100644
--- a/src/Servers/Kestrel/perf/Microbenchmarks/Http2/Http2FrameWriterBenchmark.cs
+++ b/src/Servers/Kestrel/perf/Microbenchmarks/Http2/Http2FrameWriterBenchmark.cs
@@ -20,6 +20,7 @@ public class Http2FrameWriterBenchmark
private Pipe _pipe;
private Http2FrameWriter _frameWriter;
private HttpResponseHeaders _responseHeaders;
+ private Http2Stream _stream;
[GlobalSetup]
public void GlobalSetup()
@@ -45,6 +46,8 @@ public class Http2FrameWriterBenchmark
_memoryPool,
serviceContext);
+ _stream = new MockHttp2Stream(TestContextFactory.CreateHttp2StreamContext(streamId: 0));
+
_responseHeaders = new HttpResponseHeaders();
var headers = (IHeaderDictionary)_responseHeaders;
headers.ContentType = "application/json";
@@ -54,7 +57,7 @@ public class Http2FrameWriterBenchmark
[Benchmark]
public void WriteResponseHeaders()
{
- _frameWriter.WriteResponseHeaders(0, 200, Http2HeadersFrameFlags.END_HEADERS, _responseHeaders);
+ _frameWriter.WriteResponseHeaders(_stream, 200, endStream: true, _responseHeaders);
}
[GlobalCleanup]
@@ -63,4 +66,16 @@ public class Http2FrameWriterBenchmark
_pipe.Writer.Complete();
_memoryPool?.Dispose();
}
+
+ private class MockHttp2Stream : Http2Stream
+ {
+ public MockHttp2Stream(Http2StreamContext context)
+ {
+ Initialize(context);
+ }
+
+ public override void Execute()
+ {
+ }
+ }
}
diff --git a/src/Servers/Kestrel/shared/test/TestContextFactory.cs b/src/Servers/Kestrel/shared/test/TestContextFactory.cs
index 0f1fdba1f7..14df1153cb 100644
--- a/src/Servers/Kestrel/shared/test/TestContextFactory.cs
+++ b/src/Servers/Kestrel/shared/test/TestContextFactory.cs
@@ -155,7 +155,7 @@ internal static class TestContextFactory
localEndPoint: localEndPoint,
remoteEndPoint: remoteEndPoint,
streamId: streamId ?? 0,
- streamLifetimeHandler: streamLifetimeHandler,
+ streamLifetimeHandler: streamLifetimeHandler ?? new TestHttp2StreamLifetimeHandler(),
clientPeerSettings: clientPeerSettings ?? new Http2PeerSettings(),
serverPeerSettings: serverPeerSettings ?? new Http2PeerSettings(),
frameWriter: frameWriter,
@@ -201,6 +201,17 @@ internal static class TestContextFactory
return context;
}
+ private class TestHttp2StreamLifetimeHandler : IHttp2StreamLifetimeHandler
+ {
+ public void DecrementActiveClientStreamCount()
+ {
+ }
+
+ public void OnStreamCompleted(Http2Stream stream)
+ {
+ }
+ }
+
private class TestMultiplexedConnectionContext : MultiplexedConnectionContext
{
public override string ConnectionId { get; set; }
diff --git a/src/Servers/Kestrel/test/Interop.FunctionalTests/Http2/Http2RequestTests.cs b/src/Servers/Kestrel/test/Interop.FunctionalTests/Http2/Http2RequestTests.cs
index 142fb55770..59834b29ef 100644
--- a/src/Servers/Kestrel/test/Interop.FunctionalTests/Http2/Http2RequestTests.cs
+++ b/src/Servers/Kestrel/test/Interop.FunctionalTests/Http2/Http2RequestTests.cs
@@ -3,11 +3,16 @@
using System.Net;
using System.Net.Http;
+using System.Net.Http.Headers;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Http.Headers;
+using Microsoft.AspNetCore.Internal;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.Testing;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
namespace Interop.FunctionalTests.Http2;
@@ -37,6 +42,94 @@ public class Http2RequestTests : LoggedTest
}
}
+ [Theory]
+ [InlineData(true)]
+ [InlineData(false)]
+ public async Task GET_RequestReturnsLargeData_GracefulShutdownDuringRequest_RequestGracefullyCompletes(bool hasTrailers)
+ {
+ // Arrange
+ const int DataLength = 500_000;
+ var randomBytes = Enumerable.Range(1, DataLength).Select(i => (byte)((i % 10) + 48)).ToArray();
+
+ var syncPoint = new SyncPoint();
+
+ ILogger logger = null;
+ var builder = CreateHostBuilder(
+ async c =>
+ {
+ await syncPoint.WaitToContinue();
+
+ var memory = c.Response.BodyWriter.GetMemory(randomBytes.Length);
+
+ logger.LogInformation($"Server writing {randomBytes.Length} bytes response");
+ randomBytes.CopyTo(memory);
+
+ // It's important for this test that the large write is the last data written to
+ // the response and it's not awaited by the request delegate.
+ logger.LogInformation($"Server advancing {randomBytes.Length} bytes response");
+ c.Response.BodyWriter.Advance(randomBytes.Length);
+
+ if (hasTrailers)
+ {
+ c.Response.AppendTrailer("test-trailer", "value!");
+ }
+ },
+ protocol: HttpProtocols.Http2,
+ plaintext: true);
+
+ using var host = builder.Build();
+ logger = host.Services.GetRequiredService<ILoggerFactory>().CreateLogger("Test");
+
+ var client = HttpHelpers.CreateClient();
+
+ // Act
+ await host.StartAsync().DefaultTimeout();
+
+ var longRunningTask = StartLongRunningRequestAsync(logger, host, client);
+
+ logger.LogInformation("Waiting for request on server");
+ await syncPoint.WaitForSyncPoint().DefaultTimeout();
+
+ logger.LogInformation("Stopping server");
+ var stopTask = host.StopAsync();
+
+ syncPoint.Continue();
+
+ var (readData, trailers) = await longRunningTask.DefaultTimeout();
+ await stopTask.DefaultTimeout();
+
+ // Assert
+ Assert.Equal(randomBytes, readData);
+ if (hasTrailers)
+ {
+ Assert.Equal("value!", trailers.GetValues("test-trailer").Single());
+ }
+ }
+
+ private static async Task<(byte[], HttpResponseHeaders)> StartLongRunningRequestAsync(ILogger logger, IHost host, HttpMessageInvoker client)
+ {
+ var request = new HttpRequestMessage(HttpMethod.Get, $"http://127.0.0.1:{host.GetPort()}/");
+ request.Version = HttpVersion.Version20;
+ request.VersionPolicy = HttpVersionPolicy.RequestVersionExact;
+
+ var responseMessage = await client.SendAsync(request, CancellationToken.None).DefaultTimeout();
+ responseMessage.EnsureSuccessStatusCode();
+
+ var responseStream = await responseMessage.Content.ReadAsStreamAsync();
+
+ var data = new List<byte>();
+ var buffer = new byte[1024 * 128];
+ int readCount;
+ while ((readCount = await responseStream.ReadAsync(buffer)) != 0)
+ {
+ data.AddRange(buffer.AsMemory(0, readCount).ToArray());
+ logger.LogInformation($"Received {readCount} bytes. Total {data.Count} bytes.");
+ }
+ logger.LogInformation($"Finished reading response content");
+
+ return (data.ToArray(), responseMessage.TrailingHeaders);
+ }
+
private IHostBuilder CreateHostBuilder(RequestDelegate requestDelegate, HttpProtocols? protocol = null, Action<KestrelServerOptions> configureKestrel = null, bool? plaintext = null)
{
return HttpHelpers.CreateHostBuilder(AddTestLogging, requestDelegate, protocol, configureKestrel, plaintext);
diff --git a/src/Servers/Kestrel/test/Interop.FunctionalTests/HttpHelpers.cs b/src/Servers/Kestrel/test/Interop.FunctionalTests/HttpHelpers.cs
index dcb49dd6ce..6dec979584 100644
--- a/src/Servers/Kestrel/test/Interop.FunctionalTests/HttpHelpers.cs
+++ b/src/Servers/Kestrel/test/Interop.FunctionalTests/HttpHelpers.cs
@@ -81,7 +81,7 @@ internal static class HttpHelpers
}
else
{
- o.ShutdownTimeout = TimeSpan.FromSeconds(1);
+ o.ShutdownTimeout = TimeSpan.FromSeconds(5);
}
});
}
diff --git a/src/Shared/HttpValidationProblemDetailsJsonConverter.cs b/src/Shared/HttpValidationProblemDetailsJsonConverter.cs
index c2981548f2..9c8bd17871 100644
--- a/src/Shared/HttpValidationProblemDetailsJsonConverter.cs
+++ b/src/Shared/HttpValidationProblemDetailsJsonConverter.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using System.Text.Json.Serialization;
@@ -10,12 +11,14 @@ internal sealed class HttpValidationProblemDetailsJsonConverter : JsonConverter<
{
private static readonly JsonEncodedText Errors = JsonEncodedText.Encode("errors");
+ [UnconditionalSuppressMessage("Trimmer", "IL2026", Justification = "Trimmer does not allow annotating overriden methods with annotations different from the ones in base type.")]
public override HttpValidationProblemDetails Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var problemDetails = new HttpValidationProblemDetails();
return ReadProblemDetails(ref reader, options, problemDetails);
}
+ [RequiresUnreferencedCode("JSON serialization and deserialization ProblemDetails.Extensions might require types that cannot be statically analyzed. ")]
public static HttpValidationProblemDetails ReadProblemDetails(ref Utf8JsonReader reader, JsonSerializerOptions options, HttpValidationProblemDetails problemDetails)
{
if (reader.TokenType != JsonTokenType.StartObject)
@@ -27,7 +30,7 @@ internal sealed class HttpValidationProblemDetailsJsonConverter : JsonConverter<
{
if (reader.ValueTextEquals(Errors.EncodedUtf8Bytes))
{
- var errors = JsonSerializer.Deserialize<Dictionary<string, string[]>>(ref reader, options);
+ var errors = DeserializeErrors(ref reader, options);
if (errors is not null)
{
foreach (var item in errors)
@@ -48,21 +51,33 @@ internal sealed class HttpValidationProblemDetailsJsonConverter : JsonConverter<
}
return problemDetails;
+
+ [UnconditionalSuppressMessage("Trimmer", "IL2026", Justification = "We ensure Dictionary<string, string[]> is preserved.")]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicProperties, typeof(Dictionary<string, string[]>))]
+ static Dictionary<string, string[]>? DeserializeErrors(ref Utf8JsonReader reader, JsonSerializerOptions options)
+ => JsonSerializer.Deserialize<Dictionary<string, string[]>>(ref reader, options);
}
+ [UnconditionalSuppressMessage("Trimmer", "IL2026", Justification = "Trimmer does not allow annotating overriden methods with annotations different from the ones in base type.")]
public override void Write(Utf8JsonWriter writer, HttpValidationProblemDetails value, JsonSerializerOptions options)
{
WriteProblemDetails(writer, value, options);
}
+ [RequiresUnreferencedCode("JSON serialization and deserialization ProblemDetails.Extensions might require types that cannot be statically analyzed. ")]
public static void WriteProblemDetails(Utf8JsonWriter writer, HttpValidationProblemDetails value, JsonSerializerOptions options)
{
writer.WriteStartObject();
ProblemDetailsJsonConverter.WriteProblemDetails(writer, value, options);
writer.WritePropertyName(Errors);
- JsonSerializer.Serialize(writer, value.Errors, options);
+ SerializeErrors(writer, value.Errors, options);
writer.WriteEndObject();
+
+ [UnconditionalSuppressMessage("Trimmer", "IL2026", Justification = "We ensure IDictionary<string, string[]> is preserved.")]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties, typeof(IDictionary<string, string[]>))]
+ static void SerializeErrors(Utf8JsonWriter writer, IDictionary<string, string[]> errors, JsonSerializerOptions options)
+ => JsonSerializer.Serialize(writer, errors, options);
}
}
diff --git a/src/Shared/ObjectMethodExecutor/AwaitableInfo.cs b/src/Shared/ObjectMethodExecutor/AwaitableInfo.cs
index 01529fbbdc..9b854ba7ea 100644
--- a/src/Shared/ObjectMethodExecutor/AwaitableInfo.cs
+++ b/src/Shared/ObjectMethodExecutor/AwaitableInfo.cs
@@ -1,10 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-#nullable disable
+#nullable enable
-using System;
-using System.Linq;
+using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Runtime.CompilerServices;
@@ -12,11 +11,15 @@ namespace Microsoft.Extensions.Internal;
internal readonly struct AwaitableInfo
{
+ private const BindingFlags Everything = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
+ private static readonly MethodInfo INotifyCompletion_OnCompleted = typeof(INotifyCompletion).GetMethod(nameof(INotifyCompletion.OnCompleted), Everything, new[] { typeof(Action) })!;
+ private static readonly MethodInfo ICriticalNotifyCompletion_UnsafeOnCompleted = typeof(ICriticalNotifyCompletion).GetMethod(nameof(ICriticalNotifyCompletion.UnsafeOnCompleted), Everything, new[] { typeof(Action) })!;
+
public Type AwaiterType { get; }
public PropertyInfo AwaiterIsCompletedProperty { get; }
public MethodInfo AwaiterGetResultMethod { get; }
public MethodInfo AwaiterOnCompletedMethod { get; }
- public MethodInfo AwaiterUnsafeOnCompletedMethod { get; }
+ public MethodInfo? AwaiterUnsafeOnCompletedMethod { get; }
public Type ResultType { get; }
public MethodInfo GetAwaiterMethod { get; }
@@ -25,7 +28,7 @@ internal readonly struct AwaitableInfo
PropertyInfo awaiterIsCompletedProperty,
MethodInfo awaiterGetResultMethod,
MethodInfo awaiterOnCompletedMethod,
- MethodInfo awaiterUnsafeOnCompletedMethod,
+ MethodInfo? awaiterUnsafeOnCompletedMethod,
Type resultType,
MethodInfo getAwaiterMethod)
{
@@ -38,16 +41,18 @@ internal readonly struct AwaitableInfo
GetAwaiterMethod = getAwaiterMethod;
}
- public static bool IsTypeAwaitable(Type type, out AwaitableInfo awaitableInfo)
+ [UnconditionalSuppressMessage("Trimmer", "IL2070", Justification = "Reflecting over the async Task types contract")]
+ [UnconditionalSuppressMessage("Trimmer", "IL2075", Justification = "Reflecting over the async Task types contract")]
+ public static bool IsTypeAwaitable(
+ Type type,
+ out AwaitableInfo awaitableInfo)
{
// Based on Roslyn code: http://source.roslyn.io/#Microsoft.CodeAnalysis.Workspaces/Shared/Extensions/ISymbolExtensions.cs,db4d48ba694b9347
// Awaitable must have method matching "object GetAwaiter()"
- var getAwaiterMethod = type.GetRuntimeMethods().FirstOrDefault(m =>
- m.Name.Equals("GetAwaiter", StringComparison.OrdinalIgnoreCase)
- && m.GetParameters().Length == 0
- && m.ReturnType != null);
- if (getAwaiterMethod == null)
+ var getAwaiterMethod = type.GetMethod("GetAwaiter", Everything, Type.EmptyTypes);
+
+ if (getAwaiterMethod is null)
{
awaitableInfo = default(AwaitableInfo);
return false;
@@ -56,19 +61,15 @@ internal readonly struct AwaitableInfo
var awaiterType = getAwaiterMethod.ReturnType;
// Awaiter must have property matching "bool IsCompleted { get; }"
- var isCompletedProperty = awaiterType.GetRuntimeProperties().FirstOrDefault(p =>
- p.Name.Equals("IsCompleted", StringComparison.OrdinalIgnoreCase)
- && p.PropertyType == typeof(bool)
- && p.GetMethod != null);
- if (isCompletedProperty == null)
+ var isCompletedProperty = awaiterType.GetProperty("IsCompleted", Everything, binder: null, returnType: typeof(bool), types: Type.EmptyTypes, modifiers: null);
+ if (isCompletedProperty is null)
{
awaitableInfo = default(AwaitableInfo);
return false;
}
// Awaiter must implement INotifyCompletion
- var awaiterInterfaces = awaiterType.GetInterfaces();
- var implementsINotifyCompletion = awaiterInterfaces.Any(t => t == typeof(INotifyCompletion));
+ var implementsINotifyCompletion = typeof(INotifyCompletion).IsAssignableFrom(awaiterType);
if (!implementsINotifyCompletion)
{
awaitableInfo = default(AwaitableInfo);
@@ -76,34 +77,21 @@ internal readonly struct AwaitableInfo
}
// INotifyCompletion supplies a method matching "void OnCompleted(Action action)"
- var onCompletedMethod = typeof(INotifyCompletion).GetRuntimeMethods().Single(m =>
- m.Name.Equals("OnCompleted", StringComparison.OrdinalIgnoreCase)
- && m.ReturnType == typeof(void)
- && m.GetParameters().Length == 1
- && m.GetParameters()[0].ParameterType == typeof(Action));
+ var onCompletedMethod = INotifyCompletion_OnCompleted;
// Awaiter optionally implements ICriticalNotifyCompletion
- var implementsICriticalNotifyCompletion = awaiterInterfaces.Any(t => t == typeof(ICriticalNotifyCompletion));
- MethodInfo unsafeOnCompletedMethod;
+ var implementsICriticalNotifyCompletion = typeof(ICriticalNotifyCompletion).IsAssignableFrom(awaiterType);
+ MethodInfo? unsafeOnCompletedMethod = null;
if (implementsICriticalNotifyCompletion)
{
// ICriticalNotifyCompletion supplies a method matching "void UnsafeOnCompleted(Action action)"
- unsafeOnCompletedMethod = typeof(ICriticalNotifyCompletion).GetRuntimeMethods().Single(m =>
- m.Name.Equals("UnsafeOnCompleted", StringComparison.OrdinalIgnoreCase)
- && m.ReturnType == typeof(void)
- && m.GetParameters().Length == 1
- && m.GetParameters()[0].ParameterType == typeof(Action));
- }
- else
- {
- unsafeOnCompletedMethod = null;
+ unsafeOnCompletedMethod = ICriticalNotifyCompletion_UnsafeOnCompleted;
}
// Awaiter must have method matching "void GetResult" or "T GetResult()"
- var getResultMethod = awaiterType.GetRuntimeMethods().FirstOrDefault(m =>
- m.Name.Equals("GetResult")
- && m.GetParameters().Length == 0);
- if (getResultMethod == null)
+ var getResultMethod = awaiterType.GetMethod("GetResult", Everything, Type.EmptyTypes);
+
+ if (getResultMethod is null)
{
awaitableInfo = default(AwaitableInfo);
return false;
diff --git a/src/Shared/ObjectMethodExecutor/CoercedAwaitableInfo.cs b/src/Shared/ObjectMethodExecutor/CoercedAwaitableInfo.cs
index dbd6c5fb2b..d47f974735 100644
--- a/src/Shared/ObjectMethodExecutor/CoercedAwaitableInfo.cs
+++ b/src/Shared/ObjectMethodExecutor/CoercedAwaitableInfo.cs
@@ -3,7 +3,7 @@
#nullable disable
-using System;
+using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
namespace Microsoft.Extensions.Internal;
@@ -29,7 +29,9 @@ internal readonly struct CoercedAwaitableInfo
AwaitableInfo = coercedAwaitableInfo;
}
- public static bool IsTypeAwaitable(Type type, out CoercedAwaitableInfo info)
+ public static bool IsTypeAwaitable(
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type,
+ out CoercedAwaitableInfo info)
{
if (AwaitableInfo.IsTypeAwaitable(type, out var directlyAwaitableInfo))
{
diff --git a/src/Shared/ObjectMethodExecutor/ObjectMethodExecutor.cs b/src/Shared/ObjectMethodExecutor/ObjectMethodExecutor.cs
index f6c0acda2e..52272f4208 100644
--- a/src/Shared/ObjectMethodExecutor/ObjectMethodExecutor.cs
+++ b/src/Shared/ObjectMethodExecutor/ObjectMethodExecutor.cs
@@ -3,15 +3,14 @@
#nullable enable
-using System;
-using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Reflection;
namespace Microsoft.Extensions.Internal;
-internal class ObjectMethodExecutor
+internal sealed class ObjectMethodExecutor
{
private readonly object?[]? _parameterDefaultValues;
private readonly MethodExecutorAsync? _executorAsync;
@@ -19,14 +18,15 @@ internal class ObjectMethodExecutor
private static readonly ConstructorInfo _objectMethodExecutorAwaitableConstructor =
typeof(ObjectMethodExecutorAwaitable).GetConstructor(new[] {
- typeof(object), // customAwaitable
- typeof(Func<object, object>), // getAwaiterMethod
- typeof(Func<object, bool>), // isCompletedMethod
- typeof(Func<object, object>), // getResultMethod
- typeof(Action<object, Action>), // onCompletedMethod
- typeof(Action<object, Action>) // unsafeOnCompletedMethod
- })!;
-
+ typeof(object), // customAwaitable
+ typeof(Func<object, object>), // getAwaiterMethod
+ typeof(Func<object, bool>), // isCompletedMethod
+ typeof(Func<object, object>), // getResultMethod
+ typeof(Action<object, Action>), // onCompletedMethod
+ typeof(Action<object, Action>) // unsafeOnCompletedMethod
+ })!;
+
+ [RequiresUnreferencedCode("This method performs reflection on arbitrary types.")]
private ObjectMethodExecutor(MethodInfo methodInfo, TypeInfo targetTypeInfo, object?[]? parameterDefaultValues)
{
if (methodInfo == null)
@@ -76,11 +76,13 @@ internal class ObjectMethodExecutor
public bool IsMethodAsync { get; }
+ [RequiresUnreferencedCode("This method performs reflection on arbitrary types.")]
public static ObjectMethodExecutor Create(MethodInfo methodInfo, TypeInfo targetTypeInfo)
{
return new ObjectMethodExecutor(methodInfo, targetTypeInfo, null);
}
+ [RequiresUnreferencedCode("This method performs reflection on arbitrary types.")]
public static ObjectMethodExecutor Create(MethodInfo methodInfo, TypeInfo targetTypeInfo, object?[] parameterDefaultValues)
{
if (parameterDefaultValues == null)
diff --git a/src/Shared/ObjectMethodExecutor/ObjectMethodExecutorFSharpSupport.cs b/src/Shared/ObjectMethodExecutor/ObjectMethodExecutorFSharpSupport.cs
index 473343748c..5b2a7389d2 100644
--- a/src/Shared/ObjectMethodExecutor/ObjectMethodExecutorFSharpSupport.cs
+++ b/src/Shared/ObjectMethodExecutor/ObjectMethodExecutorFSharpSupport.cs
@@ -4,6 +4,7 @@
#nullable disable
using System;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
@@ -29,6 +30,7 @@ internal static class ObjectMethodExecutorFSharpSupport
private static PropertyInfo _fsharpOptionOfTaskCreationOptionsNoneProperty;
private static PropertyInfo _fsharpOptionOfCancellationTokenNoneProperty;
+ [UnconditionalSuppressMessage("Trimmer", "IL2060", Justification = "Reflecting over the async FSharpAsync<> contract")]
public static bool TryBuildCoercerFromFSharpAsyncToAwaitable(
Type possibleFSharpAsyncType,
out Expression coerceToAwaitableExpression,
@@ -96,6 +98,9 @@ internal static class ObjectMethodExecutorFSharpSupport
}
}
+ [UnconditionalSuppressMessage("Trimmer", "IL2026", Justification = "Reflecting over the async FSharpAsync<> contract")]
+ [UnconditionalSuppressMessage("Trimmer", "IL2055", Justification = "Reflecting over the async FSharpAsync<> contract")]
+ [UnconditionalSuppressMessage("Trimmer", "IL2072", Justification = "Reflecting over the async FSharpAsync<> contract")]
private static bool TryPopulateFSharpValueCaches(Type possibleFSharpAsyncGenericType)
{
var assembly = possibleFSharpAsyncGenericType.Assembly;
diff --git a/src/Shared/ParameterBindingMethodCache.cs b/src/Shared/ParameterBindingMethodCache.cs
index 2eb5acd77d..01b5c0895e 100644
--- a/src/Shared/ParameterBindingMethodCache.cs
+++ b/src/Shared/ParameterBindingMethodCache.cs
@@ -17,6 +17,9 @@ using Microsoft.Extensions.Internal;
namespace Microsoft.AspNetCore.Http;
+[UnconditionalSuppressMessage("Trimmer", "IL2060", Justification = "Trimmer warnings are presented in RequestDelegateFactory.")]
+[UnconditionalSuppressMessage("Trimmer", "IL2065", Justification = "Trimmer warnings are presented in RequestDelegateFactory.")]
+[UnconditionalSuppressMessage("Trimmer", "IL2070", Justification = "Trimmer warnings are presented in RequestDelegateFactory.")]
internal sealed class ParameterBindingMethodCache
{
private static readonly MethodInfo ConvertValueTaskMethod = typeof(ParameterBindingMethodCache).GetMethod(nameof(ConvertValueTask), BindingFlags.NonPublic | BindingFlags.Static)!;
@@ -208,8 +211,11 @@ internal sealed class ParameterBindingMethodCache
{
typedCall = Expression.Call(methodInfo, HttpContextExpr);
}
- return Expression.Call(ConvertValueTaskMethod.MakeGenericMethod(nonNullableParameterType), typedCall);
+ return Expression.Call(GetGenericConvertValueTask(nonNullableParameterType), typedCall);
}, hasParameterInfo ? 2 : 1);
+
+ [UnconditionalSuppressMessage("Trimmer", "IL2060", Justification = "Linker workaround. The type is annotated with RequiresUnreferencedCode")]
+ static MethodInfo GetGenericConvertValueTask(Type nonNullableParameterType) => ConvertValueTaskMethod.MakeGenericMethod(nonNullableParameterType);
}
// ValueTask<Nullable<{type}>>?
else if (valueTaskResultType.IsGenericType &&
@@ -229,8 +235,11 @@ internal sealed class ParameterBindingMethodCache
{
typedCall = Expression.Call(methodInfo, HttpContextExpr);
}
- return Expression.Call(ConvertValueTaskOfNullableResultMethod.MakeGenericMethod(nonNullableParameterType), typedCall);
+ return Expression.Call(GetGenericConvertValueTaskOfNullableResult(nonNullableParameterType), typedCall);
}, hasParameterInfo ? 2 : 1);
+
+ [UnconditionalSuppressMessage("Trimmer", "IL2060", Justification = "Linker workaround. The type is annotated with RequiresUnreferencedCode")]
+ static MethodInfo GetGenericConvertValueTaskOfNullableResult(Type nonNullableParameterType) => ConvertValueTaskOfNullableResultMethod.MakeGenericMethod(nonNullableParameterType);
}
}
diff --git a/src/Shared/ProblemDetailsJsonConverter.cs b/src/Shared/ProblemDetailsJsonConverter.cs
index ad21142f3a..13120d36d2 100644
--- a/src/Shared/ProblemDetailsJsonConverter.cs
+++ b/src/Shared/ProblemDetailsJsonConverter.cs
@@ -16,6 +16,7 @@ internal sealed class ProblemDetailsJsonConverter : JsonConverter<ProblemDetails
private static readonly JsonEncodedText Detail = JsonEncodedText.Encode("detail");
private static readonly JsonEncodedText Instance = JsonEncodedText.Encode("instance");
+ [UnconditionalSuppressMessage("Trimmer", "IL2026", Justification = "Trimmer does not allow annotating overriden methods with annotations different from the ones in base type.")]
public override ProblemDetails Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var problemDetails = new ProblemDetails();
@@ -38,6 +39,7 @@ internal sealed class ProblemDetailsJsonConverter : JsonConverter<ProblemDetails
return problemDetails;
}
+ [UnconditionalSuppressMessage("Trimmer", "IL2026", Justification = "Trimmer does not allow annotating overriden methods with annotations different from the ones in base type.")]
public override void Write(Utf8JsonWriter writer, ProblemDetails value, JsonSerializerOptions options)
{
writer.WriteStartObject();
@@ -45,6 +47,7 @@ internal sealed class ProblemDetailsJsonConverter : JsonConverter<ProblemDetails
writer.WriteEndObject();
}
+ [RequiresUnreferencedCode("JSON serialization and deserialization of ProblemDetails.Extensions might require types that cannot be statically analyzed.")]
internal static void ReadValue(ref Utf8JsonReader reader, ProblemDetails value, JsonSerializerOptions options)
{
if (TryReadStringProperty(ref reader, Type, out var propertyValue))
@@ -96,6 +99,7 @@ internal sealed class ProblemDetailsJsonConverter : JsonConverter<ProblemDetails
return true;
}
+ [RequiresUnreferencedCode("JSON serialization and deserialization of ProblemDetails.Extensions might require types that cannot be statically analyzed.")]
internal static void WriteProblemDetails(Utf8JsonWriter writer, ProblemDetails value, JsonSerializerOptions options)
{
if (value.Type != null)
diff --git a/src/Shared/runtime/Http3/QPack/QPackDecoder.cs b/src/Shared/runtime/Http3/QPack/QPackDecoder.cs
index 83e1b7f3a3..9e3d8fe8a2 100644
--- a/src/Shared/runtime/Http3/QPack/QPackDecoder.cs
+++ b/src/Shared/runtime/Http3/QPack/QPackDecoder.cs
@@ -710,7 +710,7 @@ namespace System.Net.Http.QPack
_state = State.HeaderValueLength;
}
- private void OnIndexedHeaderNamePostBase(int index)
+ private static void OnIndexedHeaderNamePostBase(int index)
{
ThrowDynamicTableNotSupported();
// TODO update with postbase index
@@ -718,7 +718,7 @@ namespace System.Net.Http.QPack
// _state = State.HeaderValueLength;
}
- private void OnPostBaseIndex(int intResult, IHttpStreamHeadersHandler handler)
+ private static void OnPostBaseIndex(int intResult, IHttpStreamHeadersHandler handler)
{
ThrowDynamicTableNotSupported();
// TODO
diff --git a/src/SignalR/clients/ts/FunctionalTests/package.json b/src/SignalR/clients/ts/FunctionalTests/package.json
index fbe107c3df..67032e21c6 100644
--- a/src/SignalR/clients/ts/FunctionalTests/package.json
+++ b/src/SignalR/clients/ts/FunctionalTests/package.json
@@ -55,7 +55,8 @@
"resolutions": {
"lodash": ">=4.17.21",
"url-parse": ">=1.5.6",
- "ua-parser-js": "^0.7.30"
+ "ua-parser-js": "^0.7.30",
+ "minimist": ">=1.2.6"
},
"author": "",
"license": "MIT"
diff --git a/src/SignalR/clients/ts/FunctionalTests/yarn.lock b/src/SignalR/clients/ts/FunctionalTests/yarn.lock
index 06a8997827..0cdc9768f1 100644
--- a/src/SignalR/clients/ts/FunctionalTests/yarn.lock
+++ b/src/SignalR/clients/ts/FunctionalTests/yarn.lock
@@ -2327,10 +2327,10 @@ minimatch@^3.0.4:
dependencies:
brace-expansion "^1.1.7"
-minimist@^1.2.5:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
- integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
+minimist@>=1.2.6, minimist@^1.2.5:
+ version "1.2.6"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
+ integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
mkdirp-classic@^0.5.2:
version "0.5.3"
diff --git a/src/SignalR/clients/ts/common/package.json b/src/SignalR/clients/ts/common/package.json
index 34f9eaa675..9e72399596 100644
--- a/src/SignalR/clients/ts/common/package.json
+++ b/src/SignalR/clients/ts/common/package.json
@@ -33,6 +33,7 @@
"dependencies": {},
"resolutions": {
"ansi-regex": "5.0.1",
- "set-value": ">=4.0.1"
+ "set-value": ">=4.0.1",
+ "minimist": ">=1.2.6"
}
}
diff --git a/src/SignalR/clients/ts/common/yarn.lock b/src/SignalR/clients/ts/common/yarn.lock
index 141c7c07fe..d85d111daa 100644
--- a/src/SignalR/clients/ts/common/yarn.lock
+++ b/src/SignalR/clients/ts/common/yarn.lock
@@ -3365,10 +3365,10 @@ minimatch@^3.0.4:
dependencies:
brace-expansion "^1.1.7"
-minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
- integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
+minimist@>=1.2.6, minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5:
+ version "1.2.6"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
+ integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
mixin-deep@^1.2.0:
version "1.3.2"
diff --git a/src/Tools/Tools.slnf b/src/Tools/Tools.slnf
index 098504c6a2..3db571352b 100644
--- a/src/Tools/Tools.slnf
+++ b/src/Tools/Tools.slnf
@@ -11,11 +11,14 @@
"src\\Components\\WebAssembly\\WebAssembly\\src\\Microsoft.AspNetCore.Components.WebAssembly.csproj",
"src\\Components\\Web\\src\\Microsoft.AspNetCore.Components.Web.csproj",
"src\\Extensions\\Features\\src\\Microsoft.Extensions.Features.csproj",
+ "src\\Hosting\\Abstractions\\src\\Microsoft.AspNetCore.Hosting.Abstractions.csproj",
+ "src\\Hosting\\Server.Abstractions\\src\\Microsoft.AspNetCore.Hosting.Server.Abstractions.csproj",
"src\\Http\\Headers\\src\\Microsoft.Net.Http.Headers.csproj",
"src\\Http\\Http.Abstractions\\src\\Microsoft.AspNetCore.Http.Abstractions.csproj",
"src\\Http\\Http.Features\\src\\Microsoft.AspNetCore.Http.Features.csproj",
"src\\Http\\Http\\src\\Microsoft.AspNetCore.Http.csproj",
"src\\Http\\Metadata\\src\\Microsoft.AspNetCore.Metadata.csproj",
+ "src\\Http\\Routing.Abstractions\\src\\Microsoft.AspNetCore.Routing.Abstractions.csproj",
"src\\Http\\WebUtilities\\src\\Microsoft.AspNetCore.WebUtilities.csproj",
"src\\JSInterop\\Microsoft.JSInterop\\src\\Microsoft.JSInterop.csproj",
"src\\ObjectPool\\src\\Microsoft.Extensions.ObjectPool.csproj",
diff --git a/src/submodules/googletest b/src/submodules/googletest
-Subproject b007c54f2944e193ac44fba1bc997cb65826a0b
+Subproject af29db7ec28d6df1c7f0f745186884091e602e0
diff --git a/src/submodules/spa-templates b/src/submodules/spa-templates
-Subproject 8b90832a77eb141d957b9c484cda6f750998bb7
+Subproject 800ef5837e1a23da863001d2448df67ec31ce2a