From 03ea0a9e0c19ddcca841596d897f9f20df99fe23 Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Fri, 6 Jan 2023 17:27:38 -0800 Subject: [PATCH 01/21] Initial draft of API project template --- .../Web.ProjectTemplates/Api-CSharp.csproj.in | 15 ++ .../.template.config/dotnetcli.host.json | 33 ++++ .../Api-CSharp/.template.config/ide.host.json | 15 ++ .../Api-CSharp/.template.config/ide/Empty.png | Bin 0 -> 532 bytes .../Api-CSharp/.template.config/template.json | 160 ++++++++++++++++++ .../content/Api-CSharp/Album.cs | 63 +++++++ .../content/Api-CSharp/Program.Main.cs | 34 ++++ .../content/Api-CSharp/Program.cs | 28 +++ .../Api-CSharp/Properties/launchSettings.json | 30 ++++ 9 files changed, 378 insertions(+) create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/dotnetcli.host.json create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide.host.json create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide/Empty.png create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/template.json create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Album.cs create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Properties/launchSettings.json diff --git a/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in new file mode 100644 index 000000000000..4b0628f2cafe --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in @@ -0,0 +1,15 @@ + + + + ${DefaultNetCoreTargetFramework} + enable + enable + True + Company.WebApplication1 + false + true + full + true + + + diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/dotnetcli.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/dotnetcli.host.json new file mode 100644 index 000000000000..5ab517c8b695 --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/dotnetcli.host.json @@ -0,0 +1,33 @@ +{ + "$schema": "http://json.schemastore.org/dotnetcli.host", + "symbolInfo": { + "Framework": { + "longName": "framework" + }, + "skipRestore": { + "longName": "no-restore", + "shortName": "" + }, + "kestrelHttpPort": { + "isHidden": true + }, + "iisHttpPort": { + "isHidden": true + }, + "ExcludeLaunchSettings": { + "longName": "exclude-launch-settings", + "shortName": "" + }, + "UseProgramMain": { + "longName": "use-program-main", + "shortName": "" + }, + "NativeAot": { + "longName": "publish-native-aot", + "shortName": "aot" + } + }, + "usageExamples": [ + "" + ] +} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide.host.json new file mode 100644 index 000000000000..8cee32047e88 --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide.host.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json.schemastore.org/ide.host", + "order": 100, + "icon": "ide/Empty.png", + "supportsDocker": true, + "symbolInfo": [ + { + "id": "UseProgramMain", + "isVisible": true, + "persistenceScope": "shared", + "persistenceScopeName": "Microsoft" + } + ], + "disableHttpsSymbol": "NoHttps" +} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide/Empty.png b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide/Empty.png new file mode 100644 index 0000000000000000000000000000000000000000..69e76c44480d5ccc4de590382d871eb8c6a1c25e GIT binary patch literal 532 zcmV+v0_**WP)>F zk1-Ld)v93?D0KxV_eZ#Sx(0E(cgJ%5c$Ga<5*8Q;Z9X?M58u)jmKK(2b4?OrH}d&B z!r?IVl1`^t(#cP^Q<$Eb?rp)01{mzry_*kiz<2>xeeV5%-35Xg(4>(9rBaEd+vR4t zdlBf~2bKdQ`UPAr7o1Kf^peSBSo&82?BacXec&p0NllFQ8dfS5ghC-mk_0^@lgU31 z;q`idy|^No*zI=2<8iz^ze0tIaVeL-Aj= GenerateAlbums(int count = 5) + { + var wordCombos = new List(); + for (var i = 0; i < _words.Length; i++) + { + wordCombos.Add(new[] { i }); + + for (var j = 0; j < _words.Length; j++) + { + if (i == j) continue; + + wordCombos.Add(new[] { i, j }); + } + } + + var random = new Random(); + + for (var id = 1; id <= count; id++) + { + yield return new Album + { + Id = id, + Title = GetNextName(), + Artist = GetNextName(), + FirstReleased = DateOnly.FromDateTime(DateTime.Now.AddDays(random.Next(-365 * 60, -1))), + TrackCount = random.Next(10, 30), + Price = random.Next(7, 35) + 0.99 + }; + + string GetNextName() + { + var index = random.Next(0, wordCombos.Count - 1); + var combo = wordCombos[index]; + wordCombos.RemoveAt(index); + return string.Join(' ', combo.Select(i => _words[i])); + } + } + } +} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs new file mode 100644 index 000000000000..ebffe7e2cd25 --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs @@ -0,0 +1,34 @@ +using System.Text.Json.Serialization; +namespace Company.WebApplication1; + +public class Program +{ + public static void Main(string[] args) + { + var builder = WebApplication.CreateBuilder(args); + + builder.Services.ConfigureHttpJsonOptions(options => + { + options.SerializerOptions.AddContext(); + }); + + var app = builder.Build(); + + var sampleAlbums = AlbumGenerator.GenerateAlbums().ToArray(); + + var api = app.MapGroup("/albums"); + api.MapGet("/", () => sampleAlbums); + api.MapGet("/{id}", (int id) => + sampleAlbums.FirstOrDefault(a => a.Id == id) is { } album + ? Results.Ok(album) + : Results.NotFound($"Album with id {id} not found")); + + app.Run(); + } +} + +[JsonSerializable(typeof(Album))] +internal partial class AppJsonSerializerContext : JsonSerializerContext +{ + +} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs new file mode 100644 index 000000000000..67fa5d55e717 --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; +using Company.WebApplication1; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.ConfigureHttpJsonOptions(options => +{ + options.SerializerOptions.AddContext(); +}); + +var app = builder.Build(); + +var sampleAlbums = AlbumGenerator.GenerateAlbums().ToArray(); + +var api = app.MapGroup("/albums"); +api.MapGet("/", () => sampleAlbums); +api.MapGet("/{id}", (int id) => + sampleAlbums.FirstOrDefault(a => a.Id == id) is { } album + ? Results.Ok(album) + : Results.NotFound($"Album with id {id} not found")); + +app.Run(); + +[JsonSerializable(typeof(Album))] +internal partial class AppJsonSerializerContext : JsonSerializerContext +{ + +} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Properties/launchSettings.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Properties/launchSettings.json new file mode 100644 index 000000000000..7b75f546723b --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Properties/launchSettings.json @@ -0,0 +1,30 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:8080", + "sslPort": 0 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "albums", + "applicationUrl": "http://localhost:5000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "albums", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} From dcd6740d60296a4a500a282f34955f28f8f20281 Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Mon, 9 Jan 2023 10:49:06 -0800 Subject: [PATCH 02/21] Added "api" project template - Updated template IDs for 8.0 --- .../Api-CSharp/.template.config/ide.host.json | 9 ++++++--- .../Api-CSharp/.template.config/ide/Empty.png | Bin 532 -> 0 bytes .../Api-CSharp/.template.config/ide/WebAPI.png | Bin 0 -> 602 bytes .../content/Api-CSharp/Program.Main.cs | 2 ++ .../content/Api-CSharp/Program.cs | 2 ++ .../scripts/Run-Angular-Locally.ps1 | 2 +- .../scripts/Run-AngularProgramMain-Locally.ps1 | 2 +- src/ProjectTemplates/scripts/Run-Api-Locally.ps1 | 12 ++++++++++++ .../scripts/Run-Blazor-Locally.ps1 | 2 +- .../scripts/Run-BlazorProgramMain-Locally.ps1 | 2 +- .../scripts/Run-BlazorWasm-Locally.ps1 | 2 +- .../scripts/Run-BlazorWasmProgramMain-Locally.ps1 | 2 +- .../scripts/Run-EmptyWeb-Locally.ps1 | 2 +- .../scripts/Run-EmptyWebProgramMain-Locally.ps1 | 2 +- .../scripts/Run-Razor-Locally.ps1 | 2 +- .../scripts/Run-RazorProgramMain-Locally.ps1 | 2 +- .../scripts/Run-React-Locally.ps1 | 2 +- .../scripts/Run-ReactProgramMain-Locally.ps1 | 2 +- .../scripts/Run-ReactRedux-Locally.ps1 | 2 +- .../scripts/Run-Starterweb-Locally.ps1 | 2 +- .../scripts/Run-StarterwebProgramMain-Locally.ps1 | 2 +- .../scripts/Run-WebApi-Locally.ps1 | 2 +- .../scripts/Run-WebApiMinimal-Locally.ps1 | 2 +- .../scripts/Run-WebApiProgamMain-Locally.ps1 | 2 +- .../Run-WebApiProgamMainMinimal-Locally.ps1 | 2 +- .../scripts/Run-Worker-Locally.ps1 | 2 +- .../scripts/Run-WorkerProgramMain-Locally.ps1 | 2 +- src/ProjectTemplates/scripts/Run-gRPC-Locally.ps1 | 2 +- 28 files changed, 44 insertions(+), 25 deletions(-) delete mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide/Empty.png create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide/WebAPI.png create mode 100644 src/ProjectTemplates/scripts/Run-Api-Locally.ps1 diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide.host.json index 8cee32047e88..82a422a0222c 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide.host.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide.host.json @@ -1,7 +1,7 @@ { "$schema": "http://json.schemastore.org/ide.host", "order": 100, - "icon": "ide/Empty.png", + "icon": "ide/API.png", "supportsDocker": true, "symbolInfo": [ { @@ -9,7 +9,10 @@ "isVisible": true, "persistenceScope": "shared", "persistenceScopeName": "Microsoft" + }, + { + "id": "NativeAot", + "isVisible": true } - ], - "disableHttpsSymbol": "NoHttps" + ] } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide/Empty.png b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide/Empty.png deleted file mode 100644 index 69e76c44480d5ccc4de590382d871eb8c6a1c25e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 532 zcmV+v0_**WP)>F zk1-Ld)v93?D0KxV_eZ#Sx(0E(cgJ%5c$Ga<5*8Q;Z9X?M58u)jmKK(2b4?OrH}d&B z!r?IVl1`^t(#cP^Q<$Eb?rp)01{mzry_*kiz<2>xeeV5%-35Xg(4>(9rBaEd+vR4t zdlBf~2bKdQ`UPAr7o1Kf^peSBSo&82?BacXec&p0NllFQ8dfS5ghC-mk_0^@lgU31 z;q`idy|^No*zI=2<8iz^ze0tIaVeL-Aj=7=p7V- zgHC;ug*&)*EMY_v-EP;K1nq-1UVMIr4`1Iy@$uFtkPFYxGw-j8W3Y&7e)7aA zEX-cU?CEo=xp5^)l@tmEjEfKgM4kNQ;wwxapVn1~T>%A8tv4U0Ks*Cb`n_*oq!);$ zfWF#Spw()D%$=PBxmjJNAGi)1!tMaIS`B0=zbuXSWB)t0_uf#6=+}@Y{2MBj3bNTO z3@DQujhn;(Z@1rJT!P>bQ&UGp4G%*ELD2u*OA8mFlY~WrpMi`B*uMp?TgA2OS9wAP zbJqUN0C(=*hP&nBx1XS3&KjSMH9)7+!P zZb2@WGuC*Y^+>1FAnsNbg9s@-xM%bM_zv|Un6oy>yp$f4T6(1J*U@M+n6sw#jP3!) zaZoO;<4+Wei`eyc>2@}hp_9pExF=o@JbC;S#VbW!YUZrTX9lc)im3#{o(bdU{{UtW o@JlzL3J4)4(*yi-I@!127eKuPHMZCUp#T5?07*qoM6N<$f}rphga7~l literal 0 HcmV?d00001 diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs index ebffe7e2cd25..8c5f60453f15 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs @@ -27,7 +27,9 @@ public static void Main(string[] args) } } +[JsonSerializable(typeof(string))] [JsonSerializable(typeof(Album))] +[JsonSerializable(typeof(Album[]))] internal partial class AppJsonSerializerContext : JsonSerializerContext { diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs index 67fa5d55e717..1dc36751e894 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs @@ -21,7 +21,9 @@ app.Run(); +[JsonSerializable(typeof(string))] [JsonSerializable(typeof(Album))] +[JsonSerializable(typeof(Album[]))] internal partial class AppJsonSerializerContext : JsonSerializerContext { diff --git a/src/ProjectTemplates/scripts/Run-Angular-Locally.ps1 b/src/ProjectTemplates/scripts/Run-Angular-Locally.ps1 index 606071f0618c..d7456ebf9c7f 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.7.0.7.0.0-dev.nupkg" $false +Test-Template "angular" "angular" "Microsoft.DotNet.Web.Spa.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-AngularProgramMain-Locally.ps1 b/src/ProjectTemplates/scripts/Run-AngularProgramMain-Locally.ps1 index 955b9450bab9..37bd91bda683 100644 --- a/src/ProjectTemplates/scripts/Run-AngularProgramMain-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-AngularProgramMain-Locally.ps1 @@ -9,4 +9,4 @@ $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 +Test-Template "angular" "angular --use-program-main" "Microsoft.DotNet.Web.Spa.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-Api-Locally.ps1 b/src/ProjectTemplates/scripts/Run-Api-Locally.ps1 new file mode 100644 index 000000000000..1833059b765b --- /dev/null +++ b/src/ProjectTemplates/scripts/Run-Api-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 "api" "api" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-Blazor-Locally.ps1 b/src/ProjectTemplates/scripts/Run-Blazor-Locally.ps1 index 22b9f6db9671..35cca9a4abb2 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.7.0.7.0.0-dev.nupkg" $false +Test-Template "blazorserver" "blazorserver" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-BlazorProgramMain-Locally.ps1 b/src/ProjectTemplates/scripts/Run-BlazorProgramMain-Locally.ps1 index a5f89a1201d1..cd289c916dc0 100644 --- a/src/ProjectTemplates/scripts/Run-BlazorProgramMain-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-BlazorProgramMain-Locally.ps1 @@ -10,4 +10,4 @@ $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 +Test-Template "blazorserver" "blazorserver --use-program-main" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-BlazorWasm-Locally.ps1 b/src/ProjectTemplates/scripts/Run-BlazorWasm-Locally.ps1 index 184f3c28f886..9eede752aac6 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.7.0.7.0.0-dev.nupkg" $true +Test-Template "blazorwasm" "blazorwasm --hosted --auth Individual" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $true diff --git a/src/ProjectTemplates/scripts/Run-BlazorWasmProgramMain-Locally.ps1 b/src/ProjectTemplates/scripts/Run-BlazorWasmProgramMain-Locally.ps1 index 4c28a987937b..a4e4e360addc 100644 --- a/src/ProjectTemplates/scripts/Run-BlazorWasmProgramMain-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-BlazorWasmProgramMain-Locally.ps1 @@ -10,4 +10,4 @@ $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 +Test-Template "blazorwasm" "blazorwasm --use-program-main --hosted --auth Individual" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $true diff --git a/src/ProjectTemplates/scripts/Run-EmptyWeb-Locally.ps1 b/src/ProjectTemplates/scripts/Run-EmptyWeb-Locally.ps1 index 9d55079bf9bf..3a7607863305 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.7.0.7.0.0-dev.nupkg" $false +Test-Template "web" "web" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-EmptyWebProgramMain-Locally.ps1 b/src/ProjectTemplates/scripts/Run-EmptyWebProgramMain-Locally.ps1 index 4fd0f95af099..6a20bf49489a 100644 --- a/src/ProjectTemplates/scripts/Run-EmptyWebProgramMain-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-EmptyWebProgramMain-Locally.ps1 @@ -9,4 +9,4 @@ $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 +Test-Template "web" "web --use-program-main" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-Razor-Locally.ps1 b/src/ProjectTemplates/scripts/Run-Razor-Locally.ps1 index 9dfe0c217816..81ad557a86ca 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.7.0.7.0.0-dev.nupkg" $false +Test-Template "webapp" "webapp -au Individual" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-RazorProgramMain-Locally.ps1 b/src/ProjectTemplates/scripts/Run-RazorProgramMain-Locally.ps1 index ada9e210b673..6a63b579a12b 100644 --- a/src/ProjectTemplates/scripts/Run-RazorProgramMain-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-RazorProgramMain-Locally.ps1 @@ -6,4 +6,4 @@ 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 +Test-Template "webapp" "webapp -au Individual --use-program-main" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-React-Locally.ps1 b/src/ProjectTemplates/scripts/Run-React-Locally.ps1 index 5be4be7ff5a4..4136d4b02cdd 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.7.0.7.0.0-dev.nupkg" $false +Test-Template "react" "react" "Microsoft.DotNet.Web.Spa.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-ReactProgramMain-Locally.ps1 b/src/ProjectTemplates/scripts/Run-ReactProgramMain-Locally.ps1 index ef8cc77d324b..7b5c366de665 100644 --- a/src/ProjectTemplates/scripts/Run-ReactProgramMain-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-ReactProgramMain-Locally.ps1 @@ -9,4 +9,4 @@ $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 +Test-Template "react" "react --use-program-main" "Microsoft.DotNet.Web.Spa.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-ReactRedux-Locally.ps1 b/src/ProjectTemplates/scripts/Run-ReactRedux-Locally.ps1 index 06303a076a04..c90fb6dd9c13 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.7.0.7.0.0-dev.nupkg" $false +Test-Template "reactredux" "reactredux" "Microsoft.DotNet.Web.Spa.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-Starterweb-Locally.ps1 b/src/ProjectTemplates/scripts/Run-Starterweb-Locally.ps1 index c411befc5a08..1e37fa976fa2 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.7.0.7.0.0-dev.nupkg" $false +Test-Template "mvc" "mvc -au Individual" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-StarterwebProgramMain-Locally.ps1 b/src/ProjectTemplates/scripts/Run-StarterwebProgramMain-Locally.ps1 index d262c5eb50a3..17396806d9f1 100644 --- a/src/ProjectTemplates/scripts/Run-StarterwebProgramMain-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-StarterwebProgramMain-Locally.ps1 @@ -9,4 +9,4 @@ $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 +Test-Template "mvc" "mvc -au Individual --use-program-main" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-WebApi-Locally.ps1 b/src/ProjectTemplates/scripts/Run-WebApi-Locally.ps1 index 14f003acfdda..27c064433eae 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.7.0.7.0.0-dev.nupkg" $false +Test-Template "webapi" "webapi" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-WebApiMinimal-Locally.ps1 b/src/ProjectTemplates/scripts/Run-WebApiMinimal-Locally.ps1 index 4e32b826f804..feee0afcb44f 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.7.0.7.0.0-dev.nupkg" $false +Test-Template "webapimin" "webapi -minimal" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-WebApiProgamMain-Locally.ps1 b/src/ProjectTemplates/scripts/Run-WebApiProgamMain-Locally.ps1 index dafce7776393..fb3565c9c6d9 100644 --- a/src/ProjectTemplates/scripts/Run-WebApiProgamMain-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-WebApiProgamMain-Locally.ps1 @@ -9,4 +9,4 @@ $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 +Test-Template "webapi" "webapi --use-program-main" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-WebApiProgamMainMinimal-Locally.ps1 b/src/ProjectTemplates/scripts/Run-WebApiProgamMainMinimal-Locally.ps1 index e4c2eb0f36ed..63fa1e8ae9d1 100644 --- a/src/ProjectTemplates/scripts/Run-WebApiProgamMainMinimal-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-WebApiProgamMainMinimal-Locally.ps1 @@ -9,4 +9,4 @@ $ErrorActionPreference = 'Stop' . $PSScriptRoot\Test-Template.ps1 -Test-Template "webapi" "webapi --use-program-main --use-minimal-apis" "Microsoft.DotNet.Web.ProjectTemplates.7.0.7.0.0-dev.nupkg" $false +Test-Template "webapi" "webapi --use-program-main --use-minimal-apis" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-Worker-Locally.ps1 b/src/ProjectTemplates/scripts/Run-Worker-Locally.ps1 index 7ccf87d528f4..b2320d5adfe8 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.7.0.7.0.0-dev.nupkg" $false +Test-Template "worker" "worker" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-WorkerProgramMain-Locally.ps1 b/src/ProjectTemplates/scripts/Run-WorkerProgramMain-Locally.ps1 index 42b013ef277d..fa9119dea0bd 100644 --- a/src/ProjectTemplates/scripts/Run-WorkerProgramMain-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-WorkerProgramMain-Locally.ps1 @@ -9,4 +9,4 @@ $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 +Test-Template "worker" "worker --use-program-main" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-gRPC-Locally.ps1 b/src/ProjectTemplates/scripts/Run-gRPC-Locally.ps1 index d201cda0479d..9d8c5bffdcb8 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.7.0.7.0.0-dev.nupkg" $false +Test-Template "grpc" "grpc" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false From 4b06b8714ee8b4c89938af4368246d2ebf5625ea Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Mon, 9 Jan 2023 10:50:35 -0800 Subject: [PATCH 03/21] Add script for running "dotnet new api -aot" locally --- .../scripts/Run-Api-NativeAot-Locally.ps1 | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/ProjectTemplates/scripts/Run-Api-NativeAot-Locally.ps1 diff --git a/src/ProjectTemplates/scripts/Run-Api-NativeAot-Locally.ps1 b/src/ProjectTemplates/scripts/Run-Api-NativeAot-Locally.ps1 new file mode 100644 index 000000000000..940ac2e085ff --- /dev/null +++ b/src/ProjectTemplates/scripts/Run-Api-NativeAot-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 "api" "api -aot" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false From 4d5c25ee1593efdd1071cda2737dfed3934cefb3 Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Mon, 9 Jan 2023 11:11:56 -0800 Subject: [PATCH 04/21] Fixes to api project template --- .../Web.ProjectTemplates/Api-CSharp.csproj.in | 8 +++++--- ...Microsoft.DotNet.Web.ProjectTemplates.csproj | 3 ++- .../localize/templatestrings.cs.json | 17 +++++++++++++++++ .../localize/templatestrings.de.json | 17 +++++++++++++++++ .../localize/templatestrings.en.json | 17 +++++++++++++++++ .../localize/templatestrings.es.json | 17 +++++++++++++++++ .../localize/templatestrings.fr.json | 17 +++++++++++++++++ .../localize/templatestrings.it.json | 17 +++++++++++++++++ .../localize/templatestrings.ja.json | 17 +++++++++++++++++ .../localize/templatestrings.ko.json | 17 +++++++++++++++++ .../localize/templatestrings.pl.json | 17 +++++++++++++++++ .../localize/templatestrings.pt-BR.json | 17 +++++++++++++++++ .../localize/templatestrings.ru.json | 17 +++++++++++++++++ .../localize/templatestrings.tr.json | 17 +++++++++++++++++ .../localize/templatestrings.zh-Hans.json | 17 +++++++++++++++++ .../localize/templatestrings.zh-Hant.json | 17 +++++++++++++++++ .../Api-CSharp/.template.config/template.json | 4 ++-- .../content/Api-CSharp/Album.cs | 4 ++-- 18 files changed, 249 insertions(+), 8 deletions(-) create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.cs.json create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.de.json create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.en.json create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.es.json create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.fr.json create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.it.json create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.ja.json create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.ko.json create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.pl.json create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.pt-BR.json create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.ru.json create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.tr.json create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.zh-Hans.json create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.zh-Hant.json diff --git a/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in index 4b0628f2cafe..426fc64567d8 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in @@ -7,9 +7,11 @@ True Company.WebApplication1 false - true - full - true + + True + full + True + diff --git a/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj b/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj index 8528b64842df..67ffc2559937 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj +++ b/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj @@ -30,7 +30,7 @@ - + @@ -59,6 +59,7 @@ + diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.cs.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.cs.json new file mode 100644 index 000000000000..ae777401202e --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.cs.json @@ -0,0 +1,17 @@ +{ + "author": "Microsoft", + "name": "ASP.NET Core API", + "description": "A project template for creating an ASP.NET Core API application.", + "symbols/ExcludeLaunchSettings/description": "Whether to exclude launchSettings.json from the generated template.", + "symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.", + "symbols/iisHttpPort/description": "Port number to use for the IIS Express HTTP endpoint in launchSettings.json.", + "symbols/Framework/description": "The target framework for the project.", + "symbols/Framework/choices/net8.0/description": "Target net8.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.", + "symbols/NativeAot/displayName": "Enable _native AOT publish", + "symbols/NativeAot/description": "Whether to enable the project for publishing as native AOT.", + "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/Api-CSharp/.template.config/localize/templatestrings.de.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.de.json new file mode 100644 index 000000000000..ae777401202e --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.de.json @@ -0,0 +1,17 @@ +{ + "author": "Microsoft", + "name": "ASP.NET Core API", + "description": "A project template for creating an ASP.NET Core API application.", + "symbols/ExcludeLaunchSettings/description": "Whether to exclude launchSettings.json from the generated template.", + "symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.", + "symbols/iisHttpPort/description": "Port number to use for the IIS Express HTTP endpoint in launchSettings.json.", + "symbols/Framework/description": "The target framework for the project.", + "symbols/Framework/choices/net8.0/description": "Target net8.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.", + "symbols/NativeAot/displayName": "Enable _native AOT publish", + "symbols/NativeAot/description": "Whether to enable the project for publishing as native AOT.", + "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/Api-CSharp/.template.config/localize/templatestrings.en.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.en.json new file mode 100644 index 000000000000..ae777401202e --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.en.json @@ -0,0 +1,17 @@ +{ + "author": "Microsoft", + "name": "ASP.NET Core API", + "description": "A project template for creating an ASP.NET Core API application.", + "symbols/ExcludeLaunchSettings/description": "Whether to exclude launchSettings.json from the generated template.", + "symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.", + "symbols/iisHttpPort/description": "Port number to use for the IIS Express HTTP endpoint in launchSettings.json.", + "symbols/Framework/description": "The target framework for the project.", + "symbols/Framework/choices/net8.0/description": "Target net8.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.", + "symbols/NativeAot/displayName": "Enable _native AOT publish", + "symbols/NativeAot/description": "Whether to enable the project for publishing as native AOT.", + "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/Api-CSharp/.template.config/localize/templatestrings.es.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.es.json new file mode 100644 index 000000000000..ae777401202e --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.es.json @@ -0,0 +1,17 @@ +{ + "author": "Microsoft", + "name": "ASP.NET Core API", + "description": "A project template for creating an ASP.NET Core API application.", + "symbols/ExcludeLaunchSettings/description": "Whether to exclude launchSettings.json from the generated template.", + "symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.", + "symbols/iisHttpPort/description": "Port number to use for the IIS Express HTTP endpoint in launchSettings.json.", + "symbols/Framework/description": "The target framework for the project.", + "symbols/Framework/choices/net8.0/description": "Target net8.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.", + "symbols/NativeAot/displayName": "Enable _native AOT publish", + "symbols/NativeAot/description": "Whether to enable the project for publishing as native AOT.", + "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/Api-CSharp/.template.config/localize/templatestrings.fr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.fr.json new file mode 100644 index 000000000000..ae777401202e --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.fr.json @@ -0,0 +1,17 @@ +{ + "author": "Microsoft", + "name": "ASP.NET Core API", + "description": "A project template for creating an ASP.NET Core API application.", + "symbols/ExcludeLaunchSettings/description": "Whether to exclude launchSettings.json from the generated template.", + "symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.", + "symbols/iisHttpPort/description": "Port number to use for the IIS Express HTTP endpoint in launchSettings.json.", + "symbols/Framework/description": "The target framework for the project.", + "symbols/Framework/choices/net8.0/description": "Target net8.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.", + "symbols/NativeAot/displayName": "Enable _native AOT publish", + "symbols/NativeAot/description": "Whether to enable the project for publishing as native AOT.", + "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/Api-CSharp/.template.config/localize/templatestrings.it.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.it.json new file mode 100644 index 000000000000..ae777401202e --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.it.json @@ -0,0 +1,17 @@ +{ + "author": "Microsoft", + "name": "ASP.NET Core API", + "description": "A project template for creating an ASP.NET Core API application.", + "symbols/ExcludeLaunchSettings/description": "Whether to exclude launchSettings.json from the generated template.", + "symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.", + "symbols/iisHttpPort/description": "Port number to use for the IIS Express HTTP endpoint in launchSettings.json.", + "symbols/Framework/description": "The target framework for the project.", + "symbols/Framework/choices/net8.0/description": "Target net8.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.", + "symbols/NativeAot/displayName": "Enable _native AOT publish", + "symbols/NativeAot/description": "Whether to enable the project for publishing as native AOT.", + "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/Api-CSharp/.template.config/localize/templatestrings.ja.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.ja.json new file mode 100644 index 000000000000..ae777401202e --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.ja.json @@ -0,0 +1,17 @@ +{ + "author": "Microsoft", + "name": "ASP.NET Core API", + "description": "A project template for creating an ASP.NET Core API application.", + "symbols/ExcludeLaunchSettings/description": "Whether to exclude launchSettings.json from the generated template.", + "symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.", + "symbols/iisHttpPort/description": "Port number to use for the IIS Express HTTP endpoint in launchSettings.json.", + "symbols/Framework/description": "The target framework for the project.", + "symbols/Framework/choices/net8.0/description": "Target net8.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.", + "symbols/NativeAot/displayName": "Enable _native AOT publish", + "symbols/NativeAot/description": "Whether to enable the project for publishing as native AOT.", + "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/Api-CSharp/.template.config/localize/templatestrings.ko.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.ko.json new file mode 100644 index 000000000000..ae777401202e --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.ko.json @@ -0,0 +1,17 @@ +{ + "author": "Microsoft", + "name": "ASP.NET Core API", + "description": "A project template for creating an ASP.NET Core API application.", + "symbols/ExcludeLaunchSettings/description": "Whether to exclude launchSettings.json from the generated template.", + "symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.", + "symbols/iisHttpPort/description": "Port number to use for the IIS Express HTTP endpoint in launchSettings.json.", + "symbols/Framework/description": "The target framework for the project.", + "symbols/Framework/choices/net8.0/description": "Target net8.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.", + "symbols/NativeAot/displayName": "Enable _native AOT publish", + "symbols/NativeAot/description": "Whether to enable the project for publishing as native AOT.", + "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/Api-CSharp/.template.config/localize/templatestrings.pl.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.pl.json new file mode 100644 index 000000000000..ae777401202e --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.pl.json @@ -0,0 +1,17 @@ +{ + "author": "Microsoft", + "name": "ASP.NET Core API", + "description": "A project template for creating an ASP.NET Core API application.", + "symbols/ExcludeLaunchSettings/description": "Whether to exclude launchSettings.json from the generated template.", + "symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.", + "symbols/iisHttpPort/description": "Port number to use for the IIS Express HTTP endpoint in launchSettings.json.", + "symbols/Framework/description": "The target framework for the project.", + "symbols/Framework/choices/net8.0/description": "Target net8.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.", + "symbols/NativeAot/displayName": "Enable _native AOT publish", + "symbols/NativeAot/description": "Whether to enable the project for publishing as native AOT.", + "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/Api-CSharp/.template.config/localize/templatestrings.pt-BR.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.pt-BR.json new file mode 100644 index 000000000000..ae777401202e --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.pt-BR.json @@ -0,0 +1,17 @@ +{ + "author": "Microsoft", + "name": "ASP.NET Core API", + "description": "A project template for creating an ASP.NET Core API application.", + "symbols/ExcludeLaunchSettings/description": "Whether to exclude launchSettings.json from the generated template.", + "symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.", + "symbols/iisHttpPort/description": "Port number to use for the IIS Express HTTP endpoint in launchSettings.json.", + "symbols/Framework/description": "The target framework for the project.", + "symbols/Framework/choices/net8.0/description": "Target net8.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.", + "symbols/NativeAot/displayName": "Enable _native AOT publish", + "symbols/NativeAot/description": "Whether to enable the project for publishing as native AOT.", + "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/Api-CSharp/.template.config/localize/templatestrings.ru.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.ru.json new file mode 100644 index 000000000000..ae777401202e --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.ru.json @@ -0,0 +1,17 @@ +{ + "author": "Microsoft", + "name": "ASP.NET Core API", + "description": "A project template for creating an ASP.NET Core API application.", + "symbols/ExcludeLaunchSettings/description": "Whether to exclude launchSettings.json from the generated template.", + "symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.", + "symbols/iisHttpPort/description": "Port number to use for the IIS Express HTTP endpoint in launchSettings.json.", + "symbols/Framework/description": "The target framework for the project.", + "symbols/Framework/choices/net8.0/description": "Target net8.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.", + "symbols/NativeAot/displayName": "Enable _native AOT publish", + "symbols/NativeAot/description": "Whether to enable the project for publishing as native AOT.", + "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/Api-CSharp/.template.config/localize/templatestrings.tr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.tr.json new file mode 100644 index 000000000000..ae777401202e --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.tr.json @@ -0,0 +1,17 @@ +{ + "author": "Microsoft", + "name": "ASP.NET Core API", + "description": "A project template for creating an ASP.NET Core API application.", + "symbols/ExcludeLaunchSettings/description": "Whether to exclude launchSettings.json from the generated template.", + "symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.", + "symbols/iisHttpPort/description": "Port number to use for the IIS Express HTTP endpoint in launchSettings.json.", + "symbols/Framework/description": "The target framework for the project.", + "symbols/Framework/choices/net8.0/description": "Target net8.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.", + "symbols/NativeAot/displayName": "Enable _native AOT publish", + "symbols/NativeAot/description": "Whether to enable the project for publishing as native AOT.", + "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/Api-CSharp/.template.config/localize/templatestrings.zh-Hans.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.zh-Hans.json new file mode 100644 index 000000000000..ae777401202e --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.zh-Hans.json @@ -0,0 +1,17 @@ +{ + "author": "Microsoft", + "name": "ASP.NET Core API", + "description": "A project template for creating an ASP.NET Core API application.", + "symbols/ExcludeLaunchSettings/description": "Whether to exclude launchSettings.json from the generated template.", + "symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.", + "symbols/iisHttpPort/description": "Port number to use for the IIS Express HTTP endpoint in launchSettings.json.", + "symbols/Framework/description": "The target framework for the project.", + "symbols/Framework/choices/net8.0/description": "Target net8.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.", + "symbols/NativeAot/displayName": "Enable _native AOT publish", + "symbols/NativeAot/description": "Whether to enable the project for publishing as native AOT.", + "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/Api-CSharp/.template.config/localize/templatestrings.zh-Hant.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.zh-Hant.json new file mode 100644 index 000000000000..ae777401202e --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/localize/templatestrings.zh-Hant.json @@ -0,0 +1,17 @@ +{ + "author": "Microsoft", + "name": "ASP.NET Core API", + "description": "A project template for creating an ASP.NET Core API application.", + "symbols/ExcludeLaunchSettings/description": "Whether to exclude launchSettings.json from the generated template.", + "symbols/kestrelHttpPort/description": "Port number to use for the HTTP endpoint in launchSettings.json.", + "symbols/iisHttpPort/description": "Port number to use for the IIS Express HTTP endpoint in launchSettings.json.", + "symbols/Framework/description": "The target framework for the project.", + "symbols/Framework/choices/net8.0/description": "Target net8.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.", + "symbols/NativeAot/displayName": "Enable _native AOT publish", + "symbols/NativeAot/description": "Whether to enable the project for publishing as native AOT.", + "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/Api-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/template.json index 3fa997128d49..3861a38bdbb1 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/template.json @@ -11,12 +11,12 @@ "groupIdentity": "Microsoft.Web.Api", "precedence": "9000", "identity": "Microsoft.Web.Api.CSharp.8.0", - "shortName": "web", + "shortName": "api", "tags": { "language": "C#", "type": "project" }, - "sourceName": "Company.WebApplication1", + "sourceName": "Company.ApiApplication1", "preferNameDirectory": true, "guids": [ "53bc9b9d-9d6a-45d4-8429-2a2761773502" diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Album.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Album.cs index 6d09c83792a8..0e3d315ebf53 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Album.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Album.cs @@ -4,9 +4,9 @@ public class Album { public int Id { get; set; } - public required string Title { get; set; } + public string? Title { get; set; } - public required string Artist { get; set; } + public string? Artist { get; set; } public DateOnly FirstReleased { get; set; } From 90dc1d16b89dea319ec5578b265237af8c44e5f4 Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Mon, 9 Jan 2023 18:33:00 -0800 Subject: [PATCH 05/21] api project template native AOT fixes --- .../content/Api-CSharp/Program.Main.cs | 34 +++++++++++++++--- .../content/Api-CSharp/Program.cs | 35 +++++++++++++++---- 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs index 8c5f60453f15..b81300228884 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs @@ -1,4 +1,8 @@ using System.Text.Json.Serialization; +#if NativeAot +using Microsoft.AspNetCore.Http.Json; +using Microsoft.Extensions.Options; +#endif namespace Company.WebApplication1; public class Program @@ -7,26 +11,45 @@ public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); - builder.Services.ConfigureHttpJsonOptions(options => - { - options.SerializerOptions.AddContext(); - }); - var app = builder.Build(); var sampleAlbums = AlbumGenerator.GenerateAlbums().ToArray(); + #if (NativeAot) + var jsonHttpOptions = app.Services.GetRequiredService>().Value; + var jsonSerializerContext = new AppJsonSerializerContext(jsonHttpOptions.SerializerOptions); + + app.MapGet("/albums", (HttpContext context) => context.Response.WriteAsJsonAsync(sampleAlbums, jsonSerializerContext.AlbumArray)); + app.MapGet("/albums/{id}", (HttpContext context) => + { + if (!int.TryParse(context.GetRouteValue("id")?.ToString(), out int id)) + { + context.Response.StatusCode = 400; + return Task.CompletedTask; + } + + if (sampleAlbums.FirstOrDefault(a => a.Id == id) is { } album) + { + return context.Response.WriteAsJsonAsync(album, jsonSerializerContext.Album); + } + + context.Response.StatusCode = 404; + return context.Response.WriteAsJsonAsync($"Album with id {id} not found", jsonSerializerContext.String); + }); + #else var api = app.MapGroup("/albums"); api.MapGet("/", () => sampleAlbums); api.MapGet("/{id}", (int id) => sampleAlbums.FirstOrDefault(a => a.Id == id) is { } album ? Results.Ok(album) : Results.NotFound($"Album with id {id} not found")); + #endif app.Run(); } } +#if (NativeAot) [JsonSerializable(typeof(string))] [JsonSerializable(typeof(Album))] [JsonSerializable(typeof(Album[]))] @@ -34,3 +57,4 @@ internal partial class AppJsonSerializerContext : JsonSerializerContext { } +#endif diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs index 1dc36751e894..50de8a492b74 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs @@ -1,26 +1,48 @@ using System.Text.Json.Serialization; +#if (NativeAot) +using Microsoft.AspNetCore.Http.Json; +using Microsoft.Extensions.Options; +#endif using Company.WebApplication1; var builder = WebApplication.CreateBuilder(args); - -builder.Services.ConfigureHttpJsonOptions(options => -{ - options.SerializerOptions.AddContext(); -}); - var app = builder.Build(); var sampleAlbums = AlbumGenerator.GenerateAlbums().ToArray(); +#if (NativeAot) +var jsonHttpOptions = app.Services.GetRequiredService>().Value; +var jsonSerializerContext = new AppJsonSerializerContext(jsonHttpOptions.SerializerOptions); + +app.MapGet("/albums", (HttpContext context) => context.Response.WriteAsJsonAsync(sampleAlbums, jsonSerializerContext.AlbumArray)); +app.MapGet("/albums/{id}", (HttpContext context) => +{ + if (!int.TryParse(context.GetRouteValue("id")?.ToString(), out int id)) + { + context.Response.StatusCode = 400; + return Task.CompletedTask; + } + + if (sampleAlbums.FirstOrDefault(a => a.Id == id) is { } album) + { + return context.Response.WriteAsJsonAsync(album, jsonSerializerContext.Album); + } + + context.Response.StatusCode = 404; + return context.Response.WriteAsJsonAsync($"Album with id {id} not found", jsonSerializerContext.String); +}); +#else var api = app.MapGroup("/albums"); api.MapGet("/", () => sampleAlbums); api.MapGet("/{id}", (int id) => sampleAlbums.FirstOrDefault(a => a.Id == id) is { } album ? Results.Ok(album) : Results.NotFound($"Album with id {id} not found")); +#endif app.Run(); +#if (NativeAot) [JsonSerializable(typeof(string))] [JsonSerializable(typeof(Album))] [JsonSerializable(typeof(Album[]))] @@ -28,3 +50,4 @@ internal partial class AppJsonSerializerContext : JsonSerializerContext { } +#endif From 87c9ed54284e9046d82a7a89210cdf0737d681db Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Mon, 9 Jan 2023 18:33:30 -0800 Subject: [PATCH 06/21] Fix casing --- src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in index 426fc64567d8..f8c21f3e8bb1 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in @@ -6,7 +6,7 @@ enable True Company.WebApplication1 - false + False True full From ddec1b601d2481e066ed0c0f729b7bc5f9a46dc2 Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Tue, 10 Jan 2023 10:26:21 -0800 Subject: [PATCH 07/21] Update Test-Template.ps1 to handle RID-specific publish output --- src/ProjectTemplates/scripts/Test-Template.ps1 | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/ProjectTemplates/scripts/Test-Template.ps1 b/src/ProjectTemplates/scripts/Test-Template.ps1 index 2fe07cc5e2d4..c9c818099a9e 100644 --- a/src/ProjectTemplates/scripts/Test-Template.ps1 +++ b/src/ProjectTemplates/scripts/Test-Template.ps1 @@ -67,8 +67,17 @@ function Test-Template($templateName, $templateArgs, $templateNupkg, $isBlazorWa if ($templateArgs -match '-au') { dotnet.exe ef migrations add Initial } - dotnet.exe publish --configuration Release - Set-Location .\bin\Release\net8.0\publish + + $publishOutputDir = ".\.publish"; + dotnet.exe publish --configuration Release --output $publishOutputDir + + if (Test-Path $publishOutputDir) { + Set-Location $publishOutputDir + } + else { + throw "Publish output directory could not be found"; + } + if ($isBlazorWasm -eq $false) { Invoke-Expression "./$templateName.exe" } From 6fbe795581898400cc2b6388e864452e5ec8ce42 Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Tue, 10 Jan 2023 16:45:55 -0800 Subject: [PATCH 08/21] Use minimal APIs in api template for native AOT - Ensure local run scripts disable TreatWarningsAsErrors --- .../Web.ProjectTemplates/Api-CSharp.csproj.in | 1 - .../content/Api-CSharp/Program.Main.cs | 31 ++++------------ .../content/Api-CSharp/Program.cs | 36 +++++-------------- .../scripts/Test-Template.ps1 | 1 + 4 files changed, 17 insertions(+), 52 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in index f8c21f3e8bb1..103ff099dac6 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in @@ -10,7 +10,6 @@ True full - True diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs index b81300228884..93135fc8b109 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs @@ -11,39 +11,23 @@ public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); + #if (NativeAot) + builder.Services.ConfigureHttpJsonOptions(options => + { + options.SerializerOptions.AddContext(); + }); + + #endif var app = builder.Build(); var sampleAlbums = AlbumGenerator.GenerateAlbums().ToArray(); - #if (NativeAot) - var jsonHttpOptions = app.Services.GetRequiredService>().Value; - var jsonSerializerContext = new AppJsonSerializerContext(jsonHttpOptions.SerializerOptions); - - app.MapGet("/albums", (HttpContext context) => context.Response.WriteAsJsonAsync(sampleAlbums, jsonSerializerContext.AlbumArray)); - app.MapGet("/albums/{id}", (HttpContext context) => - { - if (!int.TryParse(context.GetRouteValue("id")?.ToString(), out int id)) - { - context.Response.StatusCode = 400; - return Task.CompletedTask; - } - - if (sampleAlbums.FirstOrDefault(a => a.Id == id) is { } album) - { - return context.Response.WriteAsJsonAsync(album, jsonSerializerContext.Album); - } - - context.Response.StatusCode = 404; - return context.Response.WriteAsJsonAsync($"Album with id {id} not found", jsonSerializerContext.String); - }); - #else var api = app.MapGroup("/albums"); api.MapGet("/", () => sampleAlbums); api.MapGet("/{id}", (int id) => sampleAlbums.FirstOrDefault(a => a.Id == id) is { } album ? Results.Ok(album) : Results.NotFound($"Album with id {id} not found")); - #endif app.Run(); } @@ -57,4 +41,3 @@ internal partial class AppJsonSerializerContext : JsonSerializerContext { } -#endif diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs index 50de8a492b74..ff82c0114844 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs @@ -1,44 +1,27 @@ -using System.Text.Json.Serialization; #if (NativeAot) -using Microsoft.AspNetCore.Http.Json; -using Microsoft.Extensions.Options; +using System.Text.Json.Serialization; #endif using Company.WebApplication1; var builder = WebApplication.CreateBuilder(args); -var app = builder.Build(); - -var sampleAlbums = AlbumGenerator.GenerateAlbums().ToArray(); #if (NativeAot) -var jsonHttpOptions = app.Services.GetRequiredService>().Value; -var jsonSerializerContext = new AppJsonSerializerContext(jsonHttpOptions.SerializerOptions); - -app.MapGet("/albums", (HttpContext context) => context.Response.WriteAsJsonAsync(sampleAlbums, jsonSerializerContext.AlbumArray)); -app.MapGet("/albums/{id}", (HttpContext context) => +builder.Services.ConfigureHttpJsonOptions(options => { - if (!int.TryParse(context.GetRouteValue("id")?.ToString(), out int id)) - { - context.Response.StatusCode = 400; - return Task.CompletedTask; - } - - if (sampleAlbums.FirstOrDefault(a => a.Id == id) is { } album) - { - return context.Response.WriteAsJsonAsync(album, jsonSerializerContext.Album); - } - - context.Response.StatusCode = 404; - return context.Response.WriteAsJsonAsync($"Album with id {id} not found", jsonSerializerContext.String); + options.SerializerOptions.AddContext(); }); -#else + +#endif +var app = builder.Build(); + +var sampleAlbums = AlbumGenerator.GenerateAlbums().ToArray(); + var api = app.MapGroup("/albums"); api.MapGet("/", () => sampleAlbums); api.MapGet("/{id}", (int id) => sampleAlbums.FirstOrDefault(a => a.Id == id) is { } album ? Results.Ok(album) : Results.NotFound($"Album with id {id} not found")); -#endif app.Run(); @@ -50,4 +33,3 @@ internal partial class AppJsonSerializerContext : JsonSerializerContext { } -#endif diff --git a/src/ProjectTemplates/scripts/Test-Template.ps1 b/src/ProjectTemplates/scripts/Test-Template.ps1 index c9c818099a9e..699ea38adcdb 100644 --- a/src/ProjectTemplates/scripts/Test-Template.ps1 +++ b/src/ProjectTemplates/scripts/Test-Template.ps1 @@ -57,6 +57,7 @@ function Test-Template($templateName, $templateArgs, $templateNupkg, $isBlazorWa true + False ')) $projContent | Set-Content $projPath } From edd2573dabcb8e7f10b50609902fe2eccbc7b4c9 Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Wed, 11 Jan 2023 10:17:06 -0800 Subject: [PATCH 09/21] Add explicit call to add console logging in api template --- .../Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs | 1 + .../Web.ProjectTemplates/content/Api-CSharp/Program.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs index 93135fc8b109..06ffecda1241 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs @@ -10,6 +10,7 @@ public class Program public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); + builder.Logging.AddConsole(); #if (NativeAot) builder.Services.ConfigureHttpJsonOptions(options => diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs index ff82c0114844..90880f03f4d1 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs @@ -4,6 +4,7 @@ using Company.WebApplication1; var builder = WebApplication.CreateBuilder(args); +builder.Logging.AddConsole(); #if (NativeAot) builder.Services.ConfigureHttpJsonOptions(options => From 7abf696079c72e176dcf870258ae653defebb4ef Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Wed, 11 Jan 2023 11:16:01 -0800 Subject: [PATCH 10/21] Add more local run scripts for api project template --- ...eAot-Locally.ps1 => Run-ApiNativeAot-Locally.ps1} | 0 .../scripts/Run-ApiProgramMain-Locally.ps1 | 12 ++++++++++++ .../scripts/Run-ApiProgramMainNativeAot-Locally.ps1 | 12 ++++++++++++ 3 files changed, 24 insertions(+) rename src/ProjectTemplates/scripts/{Run-Api-NativeAot-Locally.ps1 => Run-ApiNativeAot-Locally.ps1} (100%) create mode 100644 src/ProjectTemplates/scripts/Run-ApiProgramMain-Locally.ps1 create mode 100644 src/ProjectTemplates/scripts/Run-ApiProgramMainNativeAot-Locally.ps1 diff --git a/src/ProjectTemplates/scripts/Run-Api-NativeAot-Locally.ps1 b/src/ProjectTemplates/scripts/Run-ApiNativeAot-Locally.ps1 similarity index 100% rename from src/ProjectTemplates/scripts/Run-Api-NativeAot-Locally.ps1 rename to src/ProjectTemplates/scripts/Run-ApiNativeAot-Locally.ps1 diff --git a/src/ProjectTemplates/scripts/Run-ApiProgramMain-Locally.ps1 b/src/ProjectTemplates/scripts/Run-ApiProgramMain-Locally.ps1 new file mode 100644 index 000000000000..607250bd2e82 --- /dev/null +++ b/src/ProjectTemplates/scripts/Run-ApiProgramMain-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 "api" "api --use-program-main" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-ApiProgramMainNativeAot-Locally.ps1 b/src/ProjectTemplates/scripts/Run-ApiProgramMainNativeAot-Locally.ps1 new file mode 100644 index 000000000000..142ca4478cbd --- /dev/null +++ b/src/ProjectTemplates/scripts/Run-ApiProgramMainNativeAot-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 "api" "api -aot --use-program-main" "Microsoft.DotNet.Web.ProjectTemplates.8.0.8.0.0-dev.nupkg" $false From 571531376fa394b6f192ee19ea346e99acea400a Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Wed, 11 Jan 2023 12:01:34 -0800 Subject: [PATCH 11/21] Hide the api project template in VS --- .../content/Api-CSharp/.template.config/ide.host.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide.host.json index 82a422a0222c..d073830080c1 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide.host.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide.host.json @@ -14,5 +14,10 @@ "id": "NativeAot", "isVisible": true } + ], + "unsupportedHosts": [ + { + "id": "vs" + } ] } From 1f6e0c7e4651555c2977f25f5e1ca0f7bb1bd12d Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Wed, 11 Jan 2023 16:43:47 -0800 Subject: [PATCH 12/21] Disable IIS settings in api project template when native AOT --- .../Web.ProjectTemplates/Api-CSharp.csproj.in | 6 ++- .../Api-CSharp/Properties/launchSettings.json | 8 +++- .../Templates.Tests/template-baselines.json | 42 +++++++++++++++++++ 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in index 103ff099dac6..d499599b4768 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in @@ -4,12 +4,14 @@ ${DefaultNetCoreTargetFramework} enable enable - True + true Company.WebApplication1 False - True + false full + false + false diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Properties/launchSettings.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Properties/launchSettings.json index 7b75f546723b..295c4272b320 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Properties/launchSettings.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Properties/launchSettings.json @@ -1,4 +1,5 @@ -{ +{ +//#if (!NativeAot) "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, @@ -7,6 +8,7 @@ "sslPort": 0 } }, +//#endif "profiles": { "http": { "commandName": "Project", @@ -17,6 +19,7 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } +//#if (!NativeAot) }, "IIS Express": { "commandName": "IISExpress", @@ -26,5 +29,8 @@ "ASPNETCORE_ENVIRONMENT": "Development" } } +//#else + } +//#endif } } diff --git a/src/ProjectTemplates/test/Templates.Tests/template-baselines.json b/src/ProjectTemplates/test/Templates.Tests/template-baselines.json index e751f7e95982..aaff02e198f4 100644 --- a/src/ProjectTemplates/test/Templates.Tests/template-baselines.json +++ b/src/ProjectTemplates/test/Templates.Tests/template-baselines.json @@ -527,6 +527,48 @@ "AuthOption": "None" } }, + "api": { + "Default": { + "Template": "api", + "Arguments": "new api", + "Files": [ + "Album.cs", + "Program.cs", + "Properties/launchSettings.json" + ], + "AuthOption": "None" + }, + "NativeAot": { + "Template": "api", + "Arguments": "new api -aot", + "Files": [ + "Album.cs", + "Program.cs", + "Properties/launchSettings.json" + ], + "AuthOption": "None" + }, + "ProgramMain": { + "Template": "api", + "Arguments": "new api --use-program-main", + "Files": [ + "Album.cs", + "Program.cs", + "Properties/launchSettings.json" + ], + "AuthOption": "None" + }, + "ProgramMainNativeAot": { + "Template": "api", + "Arguments": "new api -aot --use-program-main", + "Files": [ + "Album.cs", + "Program.cs", + "Properties/launchSettings.json" + ], + "AuthOption": "None" + } + }, "webapi": { "IndividualB2C": { "Template": "webapi", From 1cbd2c0dfe12a612fb840fc15302c108ce0548e8 Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Thu, 12 Jan 2023 11:31:27 -0800 Subject: [PATCH 13/21] Move TrimmerSingleWarn to test infrastructure scripts --- src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in | 1 - src/ProjectTemplates/scripts/Test-Template.ps1 | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in index d499599b4768..0a5f59af3aa8 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in @@ -11,7 +11,6 @@ false full false - false diff --git a/src/ProjectTemplates/scripts/Test-Template.ps1 b/src/ProjectTemplates/scripts/Test-Template.ps1 index 699ea38adcdb..fa06ad55a2a5 100644 --- a/src/ProjectTemplates/scripts/Test-Template.ps1 +++ b/src/ProjectTemplates/scripts/Test-Template.ps1 @@ -58,6 +58,7 @@ function Test-Template($templateName, $templateArgs, $templateNupkg, $isBlazorWa true False + false ')) $projContent | Set-Content $projPath } From 82de5c7548675a164fc2a628688c5724b26b8e7f Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Thu, 12 Jan 2023 11:53:38 -0800 Subject: [PATCH 14/21] Fix namespace in api project template --- .../Web.ProjectTemplates/content/Api-CSharp/Album.cs | 2 +- .../Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs | 2 +- .../Web.ProjectTemplates/content/Api-CSharp/Program.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Album.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Album.cs index 0e3d315ebf53..d53be90e8af9 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Album.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Album.cs @@ -1,4 +1,4 @@ -namespace Company.WebApplication1; +namespace Company.ApiApplication1; public class Album { diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs index 06ffecda1241..c79392fd940a 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Http.Json; using Microsoft.Extensions.Options; #endif -namespace Company.WebApplication1; +namespace Company.ApiApplication1; public class Program { diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs index 90880f03f4d1..c556a87612c2 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs @@ -1,7 +1,7 @@ #if (NativeAot) using System.Text.Json.Serialization; #endif -using Company.WebApplication1; +using Company.ApiApplication1; var builder = WebApplication.CreateBuilder(args); builder.Logging.AddConsole(); From db91d0a70099d0828327d88ede7a4658a4898488 Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Thu, 12 Jan 2023 13:26:22 -0800 Subject: [PATCH 15/21] Add initial api template tests --- src/ProjectTemplates/Shared/ArgConstants.cs | 1 + .../test/Templates.Tests/ApiTemplateTest.cs | 112 ++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs diff --git a/src/ProjectTemplates/Shared/ArgConstants.cs b/src/ProjectTemplates/Shared/ArgConstants.cs index f68cd1ce4af4..c2cd932e76c8 100644 --- a/src/ProjectTemplates/Shared/ArgConstants.cs +++ b/src/ProjectTemplates/Shared/ArgConstants.cs @@ -25,4 +25,5 @@ internal static class ArgConstants public const string AadB2cInstance = "--aad-b2c-instance"; public const string UseLocalDb = "-uld"; public const string NoHttps = "--no-https"; + public const string PublishNativeAot = "--publish-native-aot"; } diff --git a/src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs b/src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs new file mode 100644 index 000000000000..aa1a089036b8 --- /dev/null +++ b/src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs @@ -0,0 +1,112 @@ +// 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.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Testing; +using Templates.Test.Helpers; +using Xunit.Abstractions; + +namespace Templates.Test; + +public class ApiTemplateTest : LoggedTest +{ + public ApiTemplateTest(ProjectFactoryFixture factoryFixture) + { + ProjectFactory = factoryFixture; + } + + public ProjectFactoryFixture ProjectFactory { get; } + + private ITestOutputHelper _output; + public ITestOutputHelper Output + { + get + { + if (_output == null) + { + _output = new TestOutputLogger(Logger); + } + return _output; + } + } + + [ConditionalFact] + public async Task ApiTemplateCSharp() + { + await ApiTemplateCore(languageOverride: null); + } + + [ConditionalFact] + public async Task ApiTemplateNativeAotCSharp() + { + await ApiTemplateCore(languageOverride: null, args: new[] { ArgConstants.PublishNativeAot }); + } + + [ConditionalFact] + public async Task ApiTemplateProgramMainCSharp() + { + await ApiTemplateCore(languageOverride: null, args: new[] { ArgConstants.UseProgramMain }); + } + + [ConditionalFact] + public async Task ApiTemplateProgramMainNativeAotCSharp() + { + await ApiTemplateCore(languageOverride: null, args: new[] { ArgConstants.UseProgramMain, ArgConstants.PublishNativeAot }); + } + + private async Task ApiTemplateCore(string languageOverride, string[] args = null) + { + var project = await ProjectFactory.CreateProject(Output); + + await project.RunDotNetNewAsync("api", args: args, language: languageOverride); + + var nativeAot = args?.Contains(ArgConstants.PublishNativeAot) ?? false; + var expectedLaunchProfileNames = nativeAot + ? new[] { "http" } + : new[] { "http", "IIS Express" }; + await project.VerifyLaunchSettings(expectedLaunchProfileNames); + + // Avoid the F# compiler. See https://github.com/dotnet/aspnetcore/issues/14022 + if (languageOverride != null) + { + return; + } + + await project.RunDotNetPublishAsync(); + + // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release + // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build + // later, while the opposite is not true. + + await project.RunDotNetBuildAsync(); + + using (var aspNetProcess = project.StartBuiltProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", project, aspNetProcess.Process)); + + await AssertEndpoints(aspNetProcess); + } + + using (var aspNetProcess = project.StartPublishedProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", project, aspNetProcess.Process)); + + await AssertEndpoints(aspNetProcess); + } + } + + private async Task AssertEndpoints(AspNetProcess aspNetProcess) + { + await aspNetProcess.AssertOk("/albums"); + await aspNetProcess.AssertOk("/albums/1"); + await aspNetProcess.AssertNotFound("/albums/100"); + } +} From 761e4763755719a1740701cbdd7971dd87941473 Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Thu, 12 Jan 2023 13:34:20 -0800 Subject: [PATCH 16/21] Update ApiTemplateTest.cs --- .../test/Templates.Tests/ApiTemplateTest.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs b/src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs index aa1a089036b8..91178840f855 100644 --- a/src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs +++ b/src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs @@ -1,11 +1,6 @@ // 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.Linq; -using System.Text; -using System.Threading.Tasks; using Microsoft.AspNetCore.Testing; using Templates.Test.Helpers; using Xunit.Abstractions; @@ -108,5 +103,6 @@ private async Task AssertEndpoints(AspNetProcess aspNetProcess) await aspNetProcess.AssertOk("/albums"); await aspNetProcess.AssertOk("/albums/1"); await aspNetProcess.AssertNotFound("/albums/100"); + await aspNetProcess.AssertNotFound("/"); } } From 2800c2dbd7093db37a7becb963ab4a9c9ac8ccd8 Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Thu, 12 Jan 2023 13:35:39 -0800 Subject: [PATCH 17/21] Rename api project template IDE icon --- .../.template.config/ide/{WebAPI.png => API.png} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide/{WebAPI.png => API.png} (100%) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide/WebAPI.png b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide/API.png similarity index 100% rename from src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide/WebAPI.png rename to src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/.template.config/ide/API.png From 837a60aa22729a357026ea426f5333ce95fa5e6d Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Thu, 12 Jan 2023 16:33:42 -0800 Subject: [PATCH 18/21] Actually publish native aot in api template --- .../Web.ProjectTemplates/Api-CSharp.csproj.in | 2 +- .../test/Templates.Tests/ApiTemplateTest.cs | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in index 0a5f59af3aa8..ead01179c249 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/Api-CSharp.csproj.in @@ -8,7 +8,7 @@ Company.WebApplication1 False - false + true full false diff --git a/src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs b/src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs index 91178840f855..a78bf6d2383f 100644 --- a/src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs +++ b/src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs @@ -35,7 +35,7 @@ public async Task ApiTemplateCSharp() await ApiTemplateCore(languageOverride: null); } - [ConditionalFact] + [ConditionalFact(Skip = "Unskip when there are no more build or publish warnings for native AOT.")] public async Task ApiTemplateNativeAotCSharp() { await ApiTemplateCore(languageOverride: null, args: new[] { ArgConstants.PublishNativeAot }); @@ -47,7 +47,7 @@ public async Task ApiTemplateProgramMainCSharp() await ApiTemplateCore(languageOverride: null, args: new[] { ArgConstants.UseProgramMain }); } - [ConditionalFact] + [ConditionalFact(Skip = "Unskip when there are no more build or publish warnings for native AOT.")] public async Task ApiTemplateProgramMainNativeAotCSharp() { await ApiTemplateCore(languageOverride: null, args: new[] { ArgConstants.UseProgramMain, ArgConstants.PublishNativeAot }); @@ -71,7 +71,8 @@ private async Task ApiTemplateCore(string languageOverride, string[] args = null return; } - await project.RunDotNetPublishAsync(); + // Force a restore if native AOT so that RID-specific assets are restored + await project.RunDotNetPublishAsync(noRestore: !nativeAot); // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build From efd0206a11c9d41d7a8f9e95572d311238e60d4b Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Fri, 13 Jan 2023 11:51:53 -0800 Subject: [PATCH 19/21] Change api template to todos --- .../content/Api-CSharp/Album.cs | 63 ------------------ .../content/Api-CSharp/Program.Main.cs | 17 +++-- .../content/Api-CSharp/Program.cs | 17 +++-- .../content/Api-CSharp/Todo.cs | 64 +++++++++++++++++++ .../test/Templates.Tests/ApiTemplateTest.cs | 6 +- 5 files changed, 83 insertions(+), 84 deletions(-) delete mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Album.cs create mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Todo.cs diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Album.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Album.cs deleted file mode 100644 index d53be90e8af9..000000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Album.cs +++ /dev/null @@ -1,63 +0,0 @@ -namespace Company.ApiApplication1; - -public class Album -{ - public int Id { get; set; } - - public string? Title { get; set; } - - public string? Artist { get; set; } - - public DateOnly FirstReleased { get; set; } - - public int TrackCount { get; set; } - - public double Price { get; set; } -} - -static class AlbumGenerator -{ - private static readonly string[] _words =new[] - { - "Exceptional", "Forgotten", "Comfortable", "Dramatic", "Temporary", "Secret", "Memory", "Dancing", "Feeling", "Nature" - }; - - internal static IEnumerable GenerateAlbums(int count = 5) - { - var wordCombos = new List(); - for (var i = 0; i < _words.Length; i++) - { - wordCombos.Add(new[] { i }); - - for (var j = 0; j < _words.Length; j++) - { - if (i == j) continue; - - wordCombos.Add(new[] { i, j }); - } - } - - var random = new Random(); - - for (var id = 1; id <= count; id++) - { - yield return new Album - { - Id = id, - Title = GetNextName(), - Artist = GetNextName(), - FirstReleased = DateOnly.FromDateTime(DateTime.Now.AddDays(random.Next(-365 * 60, -1))), - TrackCount = random.Next(10, 30), - Price = random.Next(7, 35) + 0.99 - }; - - string GetNextName() - { - var index = random.Next(0, wordCombos.Count - 1); - var combo = wordCombos[index]; - wordCombos.RemoveAt(index); - return string.Join(' ', combo.Select(i => _words[i])); - } - } - } -} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs index c79392fd940a..412eee4e993f 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs @@ -21,23 +21,22 @@ public static void Main(string[] args) #endif var app = builder.Build(); - var sampleAlbums = AlbumGenerator.GenerateAlbums().ToArray(); + var sampleTodos = TodoGenerator.GenerateTodos().ToArray(); - var api = app.MapGroup("/albums"); - api.MapGet("/", () => sampleAlbums); + var api = app.MapGroup("/todos"); + api.MapGet("/", () => sampleTodos); api.MapGet("/{id}", (int id) => - sampleAlbums.FirstOrDefault(a => a.Id == id) is { } album - ? Results.Ok(album) - : Results.NotFound($"Album with id {id} not found")); + sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo + ? Results.Ok(todo) + : Results.NotFound()); app.Run(); } } #if (NativeAot) -[JsonSerializable(typeof(string))] -[JsonSerializable(typeof(Album))] -[JsonSerializable(typeof(Album[]))] +[JsonSerializable(typeof(Todo))] +[JsonSerializable(typeof(Todo[]))] internal partial class AppJsonSerializerContext : JsonSerializerContext { diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs index c556a87612c2..537db6c548ae 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs @@ -15,21 +15,20 @@ #endif var app = builder.Build(); -var sampleAlbums = AlbumGenerator.GenerateAlbums().ToArray(); +var sampleTodos = TodoGenerator.GenerateTodos().ToArray(); -var api = app.MapGroup("/albums"); -api.MapGet("/", () => sampleAlbums); +var api = app.MapGroup("/todos"); +api.MapGet("/", () => sampleTodos); api.MapGet("/{id}", (int id) => - sampleAlbums.FirstOrDefault(a => a.Id == id) is { } album - ? Results.Ok(album) - : Results.NotFound($"Album with id {id} not found")); + sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo + ? Results.Ok(todo) + : Results.NotFound()); app.Run(); #if (NativeAot) -[JsonSerializable(typeof(string))] -[JsonSerializable(typeof(Album))] -[JsonSerializable(typeof(Album[]))] +[JsonSerializable(typeof(Todo))] +[JsonSerializable(typeof(Todo[]))] internal partial class AppJsonSerializerContext : JsonSerializerContext { diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Todo.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Todo.cs new file mode 100644 index 000000000000..74990e150827 --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Todo.cs @@ -0,0 +1,64 @@ +namespace Company.ApiApplication1; + +public class Todo +{ + public int Id { get; set; } + + public string? Title { get; set; } + + public DateOnly? DueBy { get; set; } + + public bool IsComplete { get; set; } +} + +static class TodoGenerator +{ + private static readonly (string[] Prefixes, string[] Suffixes)[] _parts = new[] + { + (new[] { "Walk the", "Feed the" }, new[] { "dog", "cat", "goat" }), + (new[] { "Do the", "Put away the" }, new[] { "groceries", "dishes", "laundry" }), + (new[] { "Clean the" }, new[] { "bathroom", "pool", "blinds", "car" }) + }; + + internal static IEnumerable GenerateTodos(int count = 5) + { + var titleMap = new List<(int Row, int Prefix, int Suffix)>(); + for (var i = 0; i < _parts.Length; i++) + { + var prefixes = _parts[i].Prefixes; + var suffixes = _parts[i].Suffixes; + for (int j = 0; j < prefixes.Length; j++) + { + for (int k = 0; k < suffixes.Length; k++) + { + titleMap.Add((i, j, k)); + } + } + } + + var random = new Random(); + + for (var id = 1; id <= count; id++) + { + yield return new Todo + { + Id = id, + Title = GetNextTitle(), + DueBy = random.Next(-200, 365) switch + { + < 0 => null, + var days => DateOnly.FromDateTime(DateTime.Now.AddDays(days)) + } + }; + + string GetNextTitle() + { + var index = random.Next(0, titleMap.Count - 1); + var map = titleMap[index]; + var row = _parts[map.Row]; + titleMap.RemoveAt(index); + return string.Join(' ', row.Prefixes[map.Prefix], row.Suffixes[map.Suffix]); + } + } + } +} diff --git a/src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs b/src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs index a78bf6d2383f..319c7054207e 100644 --- a/src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs +++ b/src/ProjectTemplates/test/Templates.Tests/ApiTemplateTest.cs @@ -101,9 +101,9 @@ private async Task ApiTemplateCore(string languageOverride, string[] args = null private async Task AssertEndpoints(AspNetProcess aspNetProcess) { - await aspNetProcess.AssertOk("/albums"); - await aspNetProcess.AssertOk("/albums/1"); - await aspNetProcess.AssertNotFound("/albums/100"); + await aspNetProcess.AssertOk("/todos"); + await aspNetProcess.AssertOk("/todos/1"); + await aspNetProcess.AssertNotFound("/todos/100"); await aspNetProcess.AssertNotFound("/"); } } From 697bdc0523cc1957d04a1ffb3452e13faf127e89 Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Fri, 13 Jan 2023 11:57:44 -0800 Subject: [PATCH 20/21] PR feedback --- .../content/Api-CSharp/Program.Main.cs | 7 +++---- .../Web.ProjectTemplates/content/Api-CSharp/Program.cs | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs index 412eee4e993f..1e7082c4f9cb 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.Main.cs @@ -23,9 +23,9 @@ public static void Main(string[] args) var sampleTodos = TodoGenerator.GenerateTodos().ToArray(); - var api = app.MapGroup("/todos"); - api.MapGet("/", () => sampleTodos); - api.MapGet("/{id}", (int id) => + var todosApi = app.MapGroup("/todos"); + todosApi.MapGet("/", () => sampleTodos); + todosApi.MapGet("/{id}", (int id) => sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo ? Results.Ok(todo) : Results.NotFound()); @@ -35,7 +35,6 @@ public static void Main(string[] args) } #if (NativeAot) -[JsonSerializable(typeof(Todo))] [JsonSerializable(typeof(Todo[]))] internal partial class AppJsonSerializerContext : JsonSerializerContext { diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs index 537db6c548ae..be0ffccde6fa 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Program.cs @@ -17,9 +17,9 @@ var sampleTodos = TodoGenerator.GenerateTodos().ToArray(); -var api = app.MapGroup("/todos"); -api.MapGet("/", () => sampleTodos); -api.MapGet("/{id}", (int id) => +var todosApi = app.MapGroup("/todos"); +todosApi.MapGet("/", () => sampleTodos); +todosApi.MapGet("/{id}", (int id) => sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo ? Results.Ok(todo) : Results.NotFound()); @@ -27,7 +27,6 @@ app.Run(); #if (NativeAot) -[JsonSerializable(typeof(Todo))] [JsonSerializable(typeof(Todo[]))] internal partial class AppJsonSerializerContext : JsonSerializerContext { From 0d6c670bf5267426ad0b35a77d5dfe87124b37da Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Fri, 13 Jan 2023 12:18:49 -0800 Subject: [PATCH 21/21] Update api template baseline & launchsettings --- .../content/Api-CSharp/Properties/launchSettings.json | 4 ++-- .../test/Templates.Tests/template-baselines.json | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Properties/launchSettings.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Properties/launchSettings.json index 295c4272b320..444a41bf94bf 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Properties/launchSettings.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Api-CSharp/Properties/launchSettings.json @@ -14,7 +14,7 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "launchUrl": "albums", + "launchUrl": "todos", "applicationUrl": "http://localhost:5000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" @@ -24,7 +24,7 @@ "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, - "launchUrl": "albums", + "launchUrl": "todos", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/src/ProjectTemplates/test/Templates.Tests/template-baselines.json b/src/ProjectTemplates/test/Templates.Tests/template-baselines.json index aaff02e198f4..39cef80de61b 100644 --- a/src/ProjectTemplates/test/Templates.Tests/template-baselines.json +++ b/src/ProjectTemplates/test/Templates.Tests/template-baselines.json @@ -532,7 +532,7 @@ "Template": "api", "Arguments": "new api", "Files": [ - "Album.cs", + "Todo.cs", "Program.cs", "Properties/launchSettings.json" ], @@ -542,7 +542,7 @@ "Template": "api", "Arguments": "new api -aot", "Files": [ - "Album.cs", + "Todo.cs", "Program.cs", "Properties/launchSettings.json" ], @@ -552,7 +552,7 @@ "Template": "api", "Arguments": "new api --use-program-main", "Files": [ - "Album.cs", + "Todo.cs", "Program.cs", "Properties/launchSettings.json" ], @@ -562,7 +562,7 @@ "Template": "api", "Arguments": "new api -aot --use-program-main", "Files": [ - "Album.cs", + "Todo.cs", "Program.cs", "Properties/launchSettings.json" ],