diff --git a/src/ProjectTemplates/Web.ProjectTemplates/WebApiAot-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/WebApiAot-CSharp.csproj.in index 135250791270..9445c03a87bd 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/WebApiAot-CSharp.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/WebApiAot-CSharp.csproj.in @@ -10,4 +10,10 @@ true + + + + + + diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/dotnetcli.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/dotnetcli.host.json index 2569634c24f9..d24ccc689f1c 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/dotnetcli.host.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/dotnetcli.host.json @@ -21,9 +21,13 @@ "UseProgramMain": { "longName": "use-program-main", "shortName": "" + }, + "DisableOpenAPI": { + "longName": "no-openapi", + "shortName": "" } }, "usageExamples": [ "" ] -} +} \ No newline at end of file diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/ide.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/ide.host.json index 00b1829bfeb4..de0bfb10ae91 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/ide.host.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/ide.host.json @@ -9,6 +9,21 @@ "isVisible": true, "persistenceScope": "shared", "persistenceScopeName": "Microsoft" + }, + { + "id": "DisableOpenAPI", + "name": { + "text": "Enable _OpenAPI support", + "overrideDefaultText": true + }, + "description": { + "text": "Enables OpenAPI (Swagger) support", + "overrideDefaultText": true + }, + "invertBoolean": true, + "isVisible": true, + "defaultValue": "true", + "persistenceScope": "templateGroup" } ] -} +} \ No newline at end of file diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.cs.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.cs.json index d9f5aba08d8d..1fa10bab25ad 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.cs.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.cs.json @@ -10,6 +10,7 @@ "symbols/skipRestore/description": "Pokud se tato možnost zadá, přeskočí automatické obnovení projektu při vytvoření.", "symbols/UseProgramMain/displayName": "Nepoužívat _příkazy nejvyšší úrovně", "symbols/UseProgramMain/description": "Určuje, jestli se má místo příkazů nejvyšší úrovně generovat explicitní třída Program a metoda Main.", + "symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support", "postActions/restore/description": "Obnoví balíčky NuGet vyžadované tímto projektem.", "postActions/restore/manualInstructions/default/text": "Spustit dotnet restore" } \ No newline at end of file diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.de.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.de.json index 82c0bf5121ef..72c37fdff835 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.de.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.de.json @@ -10,6 +10,7 @@ "symbols/skipRestore/description": "Wenn angegeben, wird die automatische Wiederherstellung des Projekts beim Erstellen übersprungen.", "symbols/UseProgramMain/displayName": "Keine Anweisungen_der obersten Ebene verwenden", "symbols/UseProgramMain/description": "Gibt an, ob anstelle von Anweisungen der obersten Ebene eine explizite Programmklasse und eine Main-Methode generiert werden soll.", + "symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support", "postActions/restore/description": "„NuGet-Pakete“ wiederherstellen, die für dieses Projekt erforderlich sind.", "postActions/restore/manualInstructions/default/text": "„dotnet restore“ ausführen" } \ No newline at end of file diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.en.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.en.json index 0805132c3eb8..1507b1e8498f 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.en.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.en.json @@ -1,7 +1,7 @@ { "author": "Microsoft", "name": "ASP.NET Core Web API (native AOT)", - "description": "A project template for creating a RESTful Web API using ASP.NET Core minimal APIs published as native AOT.", + "description": "A project template for creating a RESTful Web API using ASP.NET Core minimal APIs published as native AOT, with optional support for OpenAPI.", "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.", @@ -10,6 +10,7 @@ "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/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support", "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/WebApiAot-CSharp/.template.config/localize/templatestrings.es.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.es.json index 538c473b54a8..d6902478a520 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.es.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.es.json @@ -10,6 +10,7 @@ "symbols/skipRestore/description": "Si se especifica, se omite la restauración automática del proyecto durante la creación.", "symbols/UseProgramMain/displayName": "No usar instrucciones de _nivel superior", "symbols/UseProgramMain/description": "Indica si se debe generar una clase Program explícita y un método Main en lugar de instrucciones de nivel superior.", + "symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support", "postActions/restore/description": "Restaure los paquetes NuGet necesarios para este proyecto.", "postActions/restore/manualInstructions/default/text": "Ejecutar \"dotnet restore\"" } \ No newline at end of file diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.fr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.fr.json index 463429e219a1..5a6146402f37 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.fr.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.fr.json @@ -10,6 +10,7 @@ "symbols/skipRestore/description": "S’il est spécifié, ignore la restauration automatique du projet lors de la création.", "symbols/UseProgramMain/displayName": "N’utilisez pas _d’instructions de niveau supérieur.", "symbols/UseProgramMain/description": "Indique s’il faut générer une classe Programme explicite et une méthode Main au lieu d’instructions de niveau supérieur.", + "symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support", "postActions/restore/description": "Restaurez les packages NuGet requis par ce projet.", "postActions/restore/manualInstructions/default/text": "Exécuter « dotnet restore »" } \ No newline at end of file diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.it.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.it.json index 15792378214e..18be8dbf2fa2 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.it.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.it.json @@ -10,6 +10,7 @@ "symbols/skipRestore/description": "Se specificato, ignora il ripristino automatico del progetto durante la creazione.", "symbols/UseProgramMain/displayName": "Non usare_istruzioni di primo livello", "symbols/UseProgramMain/description": "Indica se generare una classe Program esplicita e un metodo Main anziché istruzioni di primo livello.", + "symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support", "postActions/restore/description": "Ripristina i pacchetti NuGet richiesti da questo progetto.", "postActions/restore/manualInstructions/default/text": "Esegui 'dotnet restore'" } \ No newline at end of file diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.ja.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.ja.json index 16fad5c66aa0..04549054ce8f 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.ja.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.ja.json @@ -10,6 +10,7 @@ "symbols/skipRestore/description": "指定した場合、作成時にプロジェクトの自動復元がスキップされます。", "symbols/UseProgramMain/displayName": "最上位レベルのステートメントを使用しない(_T)", "symbols/UseProgramMain/description": "最上位レベルのステートメントではなく、明示的な Program クラスと Main メソッドを生成するかどうか。", + "symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support", "postActions/restore/description": "このプロジェクトに必要な NuGet パッケージを復元します。", "postActions/restore/manualInstructions/default/text": "'dotnet restore' を実行する" } \ No newline at end of file diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.ko.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.ko.json index 763695fd5a3e..795971474519 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.ko.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.ko.json @@ -10,6 +10,7 @@ "symbols/skipRestore/description": "지정된 경우, 프로젝트 생성 시 자동 복원을 건너뜁니다.", "symbols/UseProgramMain/displayName": "최상위 문 사용 안 함(_T)", "symbols/UseProgramMain/description": "최상위 문 대신 명시적 Program 클래스 및 Main 메서드를 생성할지 여부입니다.", + "symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support", "postActions/restore/description": "이 프로젝트에 필요한 NuGet 패키지를 복원합니다.", "postActions/restore/manualInstructions/default/text": "'dotnet restore' 실행" } \ No newline at end of file diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.pl.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.pl.json index f85ea12cb58c..9d140822a380 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.pl.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.pl.json @@ -10,6 +10,7 @@ "symbols/skipRestore/description": "Jeśli ta opcja jest określona, pomija automatyczne przywracanie projektu podczas tworzenia.", "symbols/UseProgramMain/displayName": "Nie używaj ins_trukcji najwyższego poziomu", "symbols/UseProgramMain/description": "Określa, czy wygenerować jawną klasę Program i metodę Main zamiast instrukcji najwyższego poziomu.", + "symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support", "postActions/restore/description": "Przywróć pakiety NuGet wymagane przez ten projekt.", "postActions/restore/manualInstructions/default/text": "Uruchom polecenie \"dotnet restore\"" } \ No newline at end of file diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.pt-BR.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.pt-BR.json index d56c2f98339b..387de16a6714 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.pt-BR.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.pt-BR.json @@ -10,6 +10,7 @@ "symbols/skipRestore/description": "Se especificado, ignora a restauração automática do projeto sendo criado.", "symbols/UseProgramMain/displayName": "Não use ins_truções de nível superior", "symbols/UseProgramMain/description": "Se deve gerar uma classe de Programa explícita e um método principal em vez de instruções de nível superior.", + "symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support", "postActions/restore/description": "Restaure os pacotes NuGet exigidos por este projeto.", "postActions/restore/manualInstructions/default/text": "Executa 'dotnet restore'" } \ No newline at end of file diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.ru.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.ru.json index b1303ffe207e..34073d1f5999 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.ru.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.ru.json @@ -10,6 +10,7 @@ "symbols/skipRestore/description": "Если установлено, автоматическое восстановление проекта при создании пропускается.", "symbols/UseProgramMain/displayName": "Не использовать _операторы верхнего уровня", "symbols/UseProgramMain/description": "Следует ли создавать явный класс Program и метод Main вместо операторов верхнего уровня.", + "symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support", "postActions/restore/description": "Восстановление пакетов NuGet, необходимых для этого проекта.", "postActions/restore/manualInstructions/default/text": "Выполнить команду \"dotnet restore\"" } \ No newline at end of file diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.tr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.tr.json index 008a53a65f0f..c2b211a3eac5 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.tr.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.tr.json @@ -10,6 +10,7 @@ "symbols/skipRestore/description": "Belirtilirse, oluşturma sırasında projenin otomatik geri yüklenmesini atlar.", "symbols/UseProgramMain/displayName": "_Üst düzey deyimler kullanmayın", "symbols/UseProgramMain/description": "Üst düzey deyimler yerine açık bir Program sınıfı ve Ana yöntem oluşturup oluşturulmayacağını belirtir.", + "symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support", "postActions/restore/description": "Bu projenin gerektirdiği NuGet paketlerini geri yükleyin.", "postActions/restore/manualInstructions/default/text": "'dotnet restore' çalıştır" } \ No newline at end of file diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.zh-Hans.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.zh-Hans.json index 2247dc6d4b36..cedb5e3c71aa 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.zh-Hans.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.zh-Hans.json @@ -10,6 +10,7 @@ "symbols/skipRestore/description": "如果指定,则在创建时跳过项目的自动还原。", "symbols/UseProgramMain/displayName": "不使用顶级语句(_T)", "symbols/UseProgramMain/description": "是否生成显式程序类和主方法,而不是顶级语句。", + "symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support", "postActions/restore/description": "还原此项目所需的 NuGet 包。", "postActions/restore/manualInstructions/default/text": "运行 \"dotnet restore\"" } \ No newline at end of file diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.zh-Hant.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.zh-Hant.json index 7691752108c9..19940e8d352a 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.zh-Hant.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/localize/templatestrings.zh-Hant.json @@ -10,6 +10,7 @@ "symbols/skipRestore/description": "若指定,會在建立時跳過專案的自動還原。", "symbols/UseProgramMain/displayName": "不要使用最上層陳述式(_T)", "symbols/UseProgramMain/description": "是否要產生明確的 Program 類別和 Main 方法,而非最上層語句。", + "symbols/DisableOpenAPI/description": "Disable OpenAPI (Swagger) support", "postActions/restore/description": "還原此專案所需的 NuGet 套件。", "postActions/restore/manualInstructions/default/text": "執行 'dotnet restore'" } \ No newline at end of file diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/template.json index bbc12adc0cc1..26f2ea88e496 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/template.json @@ -9,7 +9,7 @@ ], "name": "ASP.NET Core Web API (native AOT)", "generatorVersions": "[1.0.0.0-*)", - "description": "A project template for creating a RESTful Web API using ASP.NET Core minimal APIs published as native AOT.", + "description": "A project template for creating a RESTful Web API using ASP.NET Core minimal APIs published as native AOT, with optional support for OpenAPI.", "groupIdentity": "Microsoft.Web.WebApiAot", "precedence": "10000", "identity": "Microsoft.Web.WebApiAot.CSharp.10.0", @@ -130,6 +130,16 @@ "defaultValue": "false", "displayName": "Do not use _top-level statements", "description": "Whether to generate an explicit Program class and Main method instead of top-level statements." + }, + "DisableOpenAPI": { + "type": "parameter", + "dataType": "bool", + "defaultValue": "false", + "description": "Disable OpenAPI (Swagger) support" + }, + "EnableOpenAPI": { + "type": "computed", + "value": "(!DisableOpenAPI)" } }, "primaryOutputs": [ @@ -152,4 +162,4 @@ "continueOnError": true } ] -} +} \ No newline at end of file diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/Program.Main.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/Program.Main.cs index ea2807072a37..5cbfe789b9ed 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/Program.Main.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/Program.Main.cs @@ -1,4 +1,5 @@ using System.Text.Json.Serialization; +using Microsoft.AspNetCore.Http.HttpResults; namespace Company.WebApplication1; @@ -13,8 +14,20 @@ public static void Main(string[] args) options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default); }); +#if (EnableOpenAPI) + // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi + builder.Services.AddOpenApi(); +#endif + var app = builder.Build(); +#if (EnableOpenAPI) + if (app.Environment.IsDevelopment()) + { + app.MapOpenApi(); + } +#endif + var sampleTodos = new Todo[] { new(1, "Walk the dog"), new(2, "Do the dishes", DateOnly.FromDateTime(DateTime.Now)), @@ -24,11 +37,23 @@ public static void Main(string[] args) }; var todosApi = app.MapGroup("/todos"); +#if (EnableOpenAPI) + todosApi.MapGet("/", () => sampleTodos) + .WithName("GetTodos"); + + todosApi.MapGet("/{id}", Results, NotFound> (int id) => + sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo + ? TypedResults.Ok(todo) + : TypedResults.NotFound()) + .WithName("GetTodoById"); +#else todosApi.MapGet("/", () => sampleTodos); - todosApi.MapGet("/{id}", (int id) => + + todosApi.MapGet("/{id}", Results, NotFound> (int id) => sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo - ? Results.Ok(todo) - : Results.NotFound()); + ? TypedResults.Ok(todo) + : TypedResults.NotFound()); +#endif app.Run(); } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/Program.cs index d3b48c954001..819db8fb6a3a 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/Program.cs @@ -1,4 +1,5 @@ using System.Text.Json.Serialization; +using Microsoft.AspNetCore.Http.HttpResults; var builder = WebApplication.CreateSlimBuilder(args); @@ -7,8 +8,20 @@ options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default); }); +#if (EnableOpenAPI) +// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi +builder.Services.AddOpenApi(); +#endif + var app = builder.Build(); +#if (EnableOpenAPI) +if (app.Environment.IsDevelopment()) +{ + app.MapOpenApi(); +} +#endif + var sampleTodos = new Todo[] { new(1, "Walk the dog"), new(2, "Do the dishes", DateOnly.FromDateTime(DateTime.Now)), @@ -18,11 +31,23 @@ }; var todosApi = app.MapGroup("/todos"); +#if (EnableOpenAPI) +todosApi.MapGet("/", () => sampleTodos) + .WithName("GetTodos"); + +todosApi.MapGet("/{id}", Results, NotFound> (int id) => + sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo + ? TypedResults.Ok(todo) + : TypedResults.NotFound()) + .WithName("GetTodoById"); +#else todosApi.MapGet("/", () => sampleTodos); -todosApi.MapGet("/{id}", (int id) => + +todosApi.MapGet("/{id}", Results, NotFound> (int id) => sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo - ? Results.Ok(todo) - : Results.NotFound()); + ? TypedResults.Ok(todo) + : TypedResults.NotFound()); +#endif app.Run(); diff --git a/src/ProjectTemplates/test/Templates.Tests/WebApiNativeAotTemplateTest.cs b/src/ProjectTemplates/test/Templates.Tests/WebApiNativeAotTemplateTest.cs index 71c113aa7105..d1d6547c8484 100644 --- a/src/ProjectTemplates/test/Templates.Tests/WebApiNativeAotTemplateTest.cs +++ b/src/ProjectTemplates/test/Templates.Tests/WebApiNativeAotTemplateTest.cs @@ -34,17 +34,60 @@ public ITestOutputHelper Output [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/47478", Queues = HelixConstants.NativeAotNotSupportedHelixQueues)] public async Task WebApiNativeAotTemplateCSharp() { - await WebApiNativeAotTemplateCore(languageOverride: null); + await WebApiNativeAotTemplateCore( + languageOverride: null, + additionalEndpointsThatShould200OkForBuiltProjects: new[] { "/openapi/v1.json" }); } [ConditionalFact] [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/47478", Queues = HelixConstants.NativeAotNotSupportedHelixQueues)] public async Task WebApiNativeAotTemplateProgramMainCSharp() { - await WebApiNativeAotTemplateCore(languageOverride: null, args: new[] { ArgConstants.UseProgramMain }); + await WebApiNativeAotTemplateCore( + languageOverride: null, + args: new[] { ArgConstants.UseProgramMain }, + additionalEndpointsThatShould200OkForBuiltProjects: new[] { "/openapi/v1.json" }); } - private async Task WebApiNativeAotTemplateCore(string languageOverride, string[] args = null) + [ConditionalTheory] + [InlineData(false)] + [InlineData(true)] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/47478", Queues = HelixConstants.NativeAotNotSupportedHelixQueues)] + public async Task WebApiNativeAotTemplateCSharp_OpenApiDisabledInProductionEnvironment(bool useProgramMain) + { + var args = useProgramMain + ? new[] { ArgConstants.UseProgramMain } + : new string[] { }; + + await WebApiNativeAotTemplateCore( + languageOverride: null, + args: args, + additionalEndpointsThatShould404NotFoundForPublishedProjects: new[] { "/openapi/v1.json" }); + } + + [ConditionalTheory] + [InlineData(false)] + [InlineData(true)] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/47478", Queues = HelixConstants.NativeAotNotSupportedHelixQueues)] + public async Task WebApiNativeAotTemplateCSharp_WithoutOpenAPI(bool useProgramMain) + { + var args = useProgramMain + ? new[] { ArgConstants.UseProgramMain, ArgConstants.NoOpenApi } + : new[] { ArgConstants.NoOpenApi }; + + await WebApiNativeAotTemplateCore( + languageOverride: null, + args: args, + additionalEndpointsThatShould404NotFoundForBuiltProjects: new[] { "/openapi/v1.json" }); + } + + private async Task WebApiNativeAotTemplateCore( + string languageOverride, + string[] args = null, + string[] additionalEndpointsThatShould200OkForBuiltProjects = null, + string[] additionalEndpointsThatShould200OkForPublishedProjects = null, + string[] additionalEndpointsThatShould404NotFoundForBuiltProjects = null, + string[] additionalEndpointsThatShould404NotFoundForPublishedProjects = null) { var project = await ProjectFactory.CreateProject(Output); project.SetCurrentRuntimeIdentifier(); @@ -77,7 +120,7 @@ private async Task WebApiNativeAotTemplateCore(string languageOverride, string[] Assert.False( aspNetProcess.Process.HasExited, ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", project, aspNetProcess.Process)); - await AssertEndpoints(aspNetProcess); + await AssertEndpoints(aspNetProcess, additionalEndpointsThatShould200OkForBuiltProjects, additionalEndpointsThatShould404NotFoundForBuiltProjects); } using (var aspNetProcess = project.StartPublishedProjectAsync(noHttps: true, usePublishedAppHost: true)) @@ -86,15 +129,31 @@ private async Task WebApiNativeAotTemplateCore(string languageOverride, string[] aspNetProcess.Process.HasExited, ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", project, aspNetProcess.Process)); - await AssertEndpoints(aspNetProcess); + await AssertEndpoints(aspNetProcess, additionalEndpointsThatShould200OkForPublishedProjects, additionalEndpointsThatShould404NotFoundForPublishedProjects); } } - private async Task AssertEndpoints(AspNetProcess aspNetProcess) + private async Task AssertEndpoints(AspNetProcess aspNetProcess, string[] additionalEndpointsThatShould200Ok = null, string[] additionalEndpointsThatShould404NotFound = null) { await aspNetProcess.AssertOk("/todos"); await aspNetProcess.AssertOk("/todos/1"); await aspNetProcess.AssertNotFound("/todos/100"); await aspNetProcess.AssertNotFound("/"); + + if (additionalEndpointsThatShould200Ok is not null) + { + foreach (var endpoint in additionalEndpointsThatShould200Ok) + { + await aspNetProcess.AssertOk(endpoint); + } + } + + if (additionalEndpointsThatShould404NotFound is not null) + { + foreach (var endpoint in additionalEndpointsThatShould404NotFound) + { + await aspNetProcess.AssertNotFound(endpoint); + } + } } }