diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todo/Message.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todo/Message.cs
new file mode 100644
index 000000000000..b352fffdee18
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todo/Message.cs
@@ -0,0 +1,8 @@
+public class Message
+{
+ public Message()
+ {
+ }
+
+ public string Text { get; set; }
+}
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todo/Program.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todo/Program.cs
new file mode 100644
index 000000000000..0cd1540ced1f
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todo/Program.cs
@@ -0,0 +1,205 @@
+#define FINAL // MINIMAL FINAL WITHPATCH TYPEDR
+#if MINIMAL
+//
+var builder = WebApplication.CreateBuilder(args);
+var app = builder.Build();
+
+app.MapGet("/", () => "Hello World!");
+
+app.Run();
+//
+#elif FINAL
+//
+using Microsoft.EntityFrameworkCore;
+
+//
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddDbContext(opt => opt.UseInMemoryDatabase("TodoList"));
+builder.Services.AddDatabaseDeveloperPageExceptionFilter();
+var app = builder.Build();
+//
+
+//
+app.MapGet("/todoitems", async (TodoDb db) =>
+ await db.Todos.ToListAsync());
+
+app.MapGet("/todoitems/complete", async (TodoDb db) =>
+ await db.Todos.Where(t => t.IsComplete).ToListAsync());
+
+//
+app.MapGet("/todoitems/{id}", async (int id, TodoDb db) =>
+ await db.Todos.FindAsync(id)
+ is Todo todo
+ ? Results.Ok(todo)
+ : Results.NotFound());
+//
+//
+
+//
+app.MapPost("/todoitems", async (Todo todo, TodoDb db) =>
+{
+ db.Todos.Add(todo);
+ await db.SaveChangesAsync();
+
+ return Results.Created($"/todoitems/{todo.Id}", todo);
+});
+//
+
+//
+app.MapPut("/todoitems/{id}", async (int id, Todo inputTodo, TodoDb db) =>
+{
+ var todo = await db.Todos.FindAsync(id);
+
+ if (todo is null) return Results.NotFound();
+
+ todo.Name = inputTodo.Name;
+ todo.IsComplete = inputTodo.IsComplete;
+
+ await db.SaveChangesAsync();
+
+ return Results.NoContent();
+});
+//
+
+//
+app.MapDelete("/todoitems/{id}", async (int id, TodoDb db) =>
+{
+ if (await db.Todos.FindAsync(id) is Todo todo)
+ {
+ db.Todos.Remove(todo);
+ await db.SaveChangesAsync();
+ return Results.NoContent();
+ }
+
+ return Results.NotFound();
+});
+//
+
+app.Run();
+//
+#elif WITHPATCH
+using Microsoft.EntityFrameworkCore;
+
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddDbContext(opt => opt.UseInMemoryDatabase("TodoList"));
+builder.Services.AddDatabaseDeveloperPageExceptionFilter();
+var app = builder.Build();
+
+app.MapGet("/todoitems", async (TodoDb db) =>
+ await db.Todos.ToListAsync());
+
+app.MapGet("/todoitems/complete", async (TodoDb db) =>
+ await db.Todos.Where(t => t.IsComplete).ToListAsync());
+
+app.MapGet("/todoitems/{id}", async (int id, TodoDb db) =>
+ await db.Todos.FindAsync(id)
+ is Todo todo
+ ? Results.Ok(todo)
+ : Results.NotFound());
+
+app.MapPost("/todoitems", async (Todo todo, TodoDb db) =>
+{
+ db.Todos.Add(todo);
+ await db.SaveChangesAsync();
+
+ return Results.Created($"/todoitems/{todo.Id}", todo);
+});
+
+app.MapPut("/todoitems/{id}", async (int id, Todo inputTodo, TodoDb db) =>
+{
+ var todo = await db.Todos.FindAsync(id);
+
+ if (todo is null) return Results.NotFound();
+
+ todo.Name = inputTodo.Name;
+ todo.IsComplete = inputTodo.IsComplete;
+
+ await db.SaveChangesAsync();
+
+ return Results.NoContent();
+});
+
+//
+app.MapPatch("/todoitems/{id}", async (int id, TodoPatchDto inputTodo, TodoDb db) =>
+{
+ var todo = await db.Todos.FindAsync(id);
+
+ if (todo is null) return Results.NotFound();
+
+ if (inputTodo.Name is not null) todo.Name = inputTodo.Name;
+ if (inputTodo.IsComplete is not null) todo.IsComplete = inputTodo.IsComplete.Value;
+
+ await db.SaveChangesAsync();
+
+ return Results.NoContent();
+});
+//
+
+app.MapDelete("/todoitems/{id}", async (int id, TodoDb db) =>
+{
+ if (await db.Todos.FindAsync(id) is Todo todo)
+ {
+ db.Todos.Remove(todo);
+ await db.SaveChangesAsync();
+ return Results.NoContent();
+ }
+
+ return Results.NotFound();
+});
+
+app.Run();
+#elif TYPEDR
+using Microsoft.AspNetCore.Http.HttpResults;
+using Microsoft.EntityFrameworkCore;
+
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddDbContext(opt => opt.UseInMemoryDatabase("TodoList"));
+builder.Services.AddDatabaseDeveloperPageExceptionFilter();
+var app = builder.Build();
+
+app.MapGet("/todoitems", async (TodoDb db) =>
+ await db.Todos.ToListAsync());
+
+app.MapGet("/todoitems/complete", async (TodoDb db) =>
+ await db.Todos.Where(t => t.IsComplete).ToListAsync());
+
+//
+app.MapGet("/todoitems/{id}", async (int id, TodoDb db) =>
+ await db.Todos.FindAsync(id)
+ is Todo todo
+ ? Results.Ok(todo)
+ : Results.NotFound());
+//
+
+/*
+//
+ app.MapGet("/todoitems/{id}", async Task, NotFound>> (int id, TodoDb db) =>
+ await db.Todos.FindAsync(id)
+ is Todo todo
+ ? TypedResults.Ok(todo)
+ : TypedResults.NotFound());
+//
+*/
+
+/*
+//
+app.MapGet("/todoitems/{id}", async (int id, TodoDb db) =>
+ await db.Todos.FindAsync(id)
+ is Todo todo
+ ? TypedResults.Ok(todo)
+ : TypedResults.NotFound());
+//
+*/
+
+//
+app.MapGet("/hello", () => Results.Ok(new Message() { Text = "Hello World!" }))
+ .Produces();
+//
+
+//
+app.MapGet("/hello2", () => TypedResults.Ok(new Message() { Text = "Hello World!" }));
+//
+
+app.Run();
+#endif
+
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todo/Todo.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todo/Todo.cs
new file mode 100644
index 000000000000..2900a835b043
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todo/Todo.cs
@@ -0,0 +1,6 @@
+class Todo
+{
+ public int Id { get; set; }
+ public string? Name { get; set; }
+ public bool IsComplete { get; set; }
+}
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todo/TodoApi.csproj b/aspnetcore/tutorials/min-web-api/samples/10.x/todo/TodoApi.csproj
new file mode 100644
index 000000000000..abc9f7648bf9
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todo/TodoApi.csproj
@@ -0,0 +1,14 @@
+
+
+
+ net9.0
+ enable
+ enable
+
+
+
+
+
+
+
+
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todo/TodoDb.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todo/TodoDb.cs
new file mode 100644
index 000000000000..c1584b807819
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todo/TodoDb.cs
@@ -0,0 +1,9 @@
+using Microsoft.EntityFrameworkCore;
+
+class TodoDb : DbContext
+{
+ public TodoDb(DbContextOptions options)
+ : base(options) { }
+
+ public DbSet Todos => Set();
+}
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todo/TodoPatchDto.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todo/TodoPatchDto.cs
new file mode 100644
index 000000000000..ab225cf2280b
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todo/TodoPatchDto.cs
@@ -0,0 +1,5 @@
+public class TodoPatchDto
+{
+ public string? Name { get; set; }
+ public bool? IsComplete { get; set; }
+}
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO/Program.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO/Program.cs
new file mode 100644
index 000000000000..861c355b7387
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO/Program.cs
@@ -0,0 +1,84 @@
+//
+using Microsoft.EntityFrameworkCore;
+
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddDbContext(opt => opt.UseInMemoryDatabase("TodoList"));
+builder.Services.AddDatabaseDeveloperPageExceptionFilter();
+var app = builder.Build();
+
+//
+RouteGroupBuilder todoItems = app.MapGroup("/todoitems");
+
+todoItems.MapGet("/", GetAllTodos);
+todoItems.MapGet("/complete", GetCompleteTodos);
+todoItems.MapGet("/{id}", GetTodo);
+todoItems.MapPost("/", CreateTodo);
+todoItems.MapPut("/{id}", UpdateTodo);
+todoItems.MapDelete("/{id}", DeleteTodo);
+//
+
+app.Run();
+
+//
+//
+static async Task GetAllTodos(TodoDb db)
+{
+ return TypedResults.Ok(await db.Todos.Select(x => new TodoItemDTO(x)).ToArrayAsync());
+}
+//
+
+static async Task GetCompleteTodos(TodoDb db) {
+ return TypedResults.Ok(await db.Todos.Where(t => t.IsComplete).Select(x => new TodoItemDTO(x)).ToListAsync());
+}
+
+static async Task GetTodo(int id, TodoDb db)
+{
+ return await db.Todos.FindAsync(id)
+ is Todo todo
+ ? TypedResults.Ok(new TodoItemDTO(todo))
+ : TypedResults.NotFound();
+}
+
+static async Task CreateTodo(TodoItemDTO todoItemDTO, TodoDb db)
+{
+ var todoItem = new Todo
+ {
+ IsComplete = todoItemDTO.IsComplete,
+ Name = todoItemDTO.Name
+ };
+
+ db.Todos.Add(todoItem);
+ await db.SaveChangesAsync();
+
+ todoItemDTO = new TodoItemDTO(todoItem);
+
+ return TypedResults.Created($"/todoitems/{todoItem.Id}", todoItemDTO);
+}
+
+static async Task UpdateTodo(int id, TodoItemDTO todoItemDTO, TodoDb db)
+{
+ var todo = await db.Todos.FindAsync(id);
+
+ if (todo is null) return TypedResults.NotFound();
+
+ todo.Name = todoItemDTO.Name;
+ todo.IsComplete = todoItemDTO.IsComplete;
+
+ await db.SaveChangesAsync();
+
+ return TypedResults.NoContent();
+}
+
+static async Task DeleteTodo(int id, TodoDb db)
+{
+ if (await db.Todos.FindAsync(id) is Todo todo)
+ {
+ db.Todos.Remove(todo);
+ await db.SaveChangesAsync();
+ return TypedResults.NoContent();
+ }
+
+ return TypedResults.NotFound();
+}
+//
+//
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO/Todo.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO/Todo.cs
new file mode 100644
index 000000000000..d9ea203029c5
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO/Todo.cs
@@ -0,0 +1,7 @@
+public class Todo
+{
+ public int Id { get; set; }
+ public string? Name { get; set; }
+ public bool IsComplete { get; set; }
+ public string? Secret { get; set; }
+}
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO/TodoApi.csproj b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO/TodoApi.csproj
new file mode 100644
index 000000000000..abc9f7648bf9
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO/TodoApi.csproj
@@ -0,0 +1,14 @@
+
+
+
+ net9.0
+ enable
+ enable
+
+
+
+
+
+
+
+
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO/TodoDb.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO/TodoDb.cs
new file mode 100644
index 000000000000..c1584b807819
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO/TodoDb.cs
@@ -0,0 +1,9 @@
+using Microsoft.EntityFrameworkCore;
+
+class TodoDb : DbContext
+{
+ public TodoDb(DbContextOptions options)
+ : base(options) { }
+
+ public DbSet Todos => Set();
+}
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO/TodoItemDTO.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO/TodoItemDTO.cs
new file mode 100644
index 000000000000..76f99abe44bd
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO/TodoItemDTO.cs
@@ -0,0 +1,10 @@
+public class TodoItemDTO
+{
+ public int Id { get; set; }
+ public string? Name { get; set; }
+ public bool IsComplete { get; set; }
+
+ public TodoItemDTO() { }
+ public TodoItemDTO(Todo todoItem) =>
+ (Id, Name, IsComplete) = (todoItem.Id, todoItem.Name, todoItem.IsComplete);
+}
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO_SwaggerVersion/Program.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO_SwaggerVersion/Program.cs
new file mode 100644
index 000000000000..aa53df894a24
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO_SwaggerVersion/Program.cs
@@ -0,0 +1,105 @@
+//
+using Microsoft.EntityFrameworkCore;
+
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddDbContext(opt => opt.UseInMemoryDatabase("TodoList"));
+builder.Services.AddDatabaseDeveloperPageExceptionFilter();
+
+builder.Services.AddEndpointsApiExplorer();
+builder.Services.AddOpenApiDocument(config =>
+{
+ config.DocumentName = "TodoAPI";
+ config.Title = "TodoAPI v1";
+ config.Version = "v1";
+});
+
+var app = builder.Build();
+
+if (app.Environment.IsDevelopment())
+{
+ app.UseOpenApi();
+ app.UseSwaggerUi(config =>
+ {
+ config.DocumentTitle = "TodoAPI";
+ config.Path = "/swagger";
+ config.DocumentPath = "/swagger/{documentName}/swagger.json";
+ config.DocExpansion = "list";
+ });
+}
+
+//
+RouteGroupBuilder todoItems = app.MapGroup("/todoitems");
+
+todoItems.MapGet("/", GetAllTodos);
+todoItems.MapGet("/complete", GetCompleteTodos);
+todoItems.MapGet("/{id}", GetTodo);
+todoItems.MapPost("/", CreateTodo);
+todoItems.MapPut("/{id}", UpdateTodo);
+todoItems.MapDelete("/{id}", DeleteTodo);
+//
+
+app.Run();
+
+//
+//
+static async Task GetAllTodos(TodoDb db)
+{
+ return TypedResults.Ok(await db.Todos.Select(x => new TodoItemDTO(x)).ToArrayAsync());
+}
+//
+
+static async Task GetCompleteTodos(TodoDb db) {
+ return TypedResults.Ok(await db.Todos.Where(t => t.IsComplete).Select(x => new TodoItemDTO(x)).ToListAsync());
+}
+
+static async Task GetTodo(int id, TodoDb db)
+{
+ return await db.Todos.FindAsync(id)
+ is Todo todo
+ ? TypedResults.Ok(new TodoItemDTO(todo))
+ : TypedResults.NotFound();
+}
+
+static async Task CreateTodo(TodoItemDTO todoItemDTO, TodoDb db)
+{
+ var todoItem = new Todo
+ {
+ IsComplete = todoItemDTO.IsComplete,
+ Name = todoItemDTO.Name
+ };
+
+ db.Todos.Add(todoItem);
+ await db.SaveChangesAsync();
+
+ todoItemDTO = new TodoItemDTO(todoItem);
+
+ return TypedResults.Created($"/todoitems/{todoItem.Id}", todoItemDTO);
+}
+
+static async Task UpdateTodo(int id, TodoItemDTO todoItemDTO, TodoDb db)
+{
+ var todo = await db.Todos.FindAsync(id);
+
+ if (todo is null) return TypedResults.NotFound();
+
+ todo.Name = todoItemDTO.Name;
+ todo.IsComplete = todoItemDTO.IsComplete;
+
+ await db.SaveChangesAsync();
+
+ return TypedResults.NoContent();
+}
+
+static async Task DeleteTodo(int id, TodoDb db)
+{
+ if (await db.Todos.FindAsync(id) is Todo todo)
+ {
+ db.Todos.Remove(todo);
+ await db.SaveChangesAsync();
+ return TypedResults.NoContent();
+ }
+
+ return TypedResults.NotFound();
+}
+//
+//
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO_SwaggerVersion/Todo.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO_SwaggerVersion/Todo.cs
new file mode 100644
index 000000000000..d9ea203029c5
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO_SwaggerVersion/Todo.cs
@@ -0,0 +1,7 @@
+public class Todo
+{
+ public int Id { get; set; }
+ public string? Name { get; set; }
+ public bool IsComplete { get; set; }
+ public string? Secret { get; set; }
+}
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO_SwaggerVersion/TodoApi.csproj b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO_SwaggerVersion/TodoApi.csproj
new file mode 100644
index 000000000000..067275c7128b
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO_SwaggerVersion/TodoApi.csproj
@@ -0,0 +1,15 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO_SwaggerVersion/TodoDb.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO_SwaggerVersion/TodoDb.cs
new file mode 100644
index 000000000000..c1584b807819
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO_SwaggerVersion/TodoDb.cs
@@ -0,0 +1,9 @@
+using Microsoft.EntityFrameworkCore;
+
+class TodoDb : DbContext
+{
+ public TodoDb(DbContextOptions options)
+ : base(options) { }
+
+ public DbSet Todos => Set();
+}
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO_SwaggerVersion/TodoItemDTO.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO_SwaggerVersion/TodoItemDTO.cs
new file mode 100644
index 000000000000..76f99abe44bd
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoDTO_SwaggerVersion/TodoItemDTO.cs
@@ -0,0 +1,10 @@
+public class TodoItemDTO
+{
+ public int Id { get; set; }
+ public string? Name { get; set; }
+ public bool IsComplete { get; set; }
+
+ public TodoItemDTO() { }
+ public TodoItemDTO(Todo todoItem) =>
+ (Id, Name, IsComplete) = (todoItem.Id, todoItem.Name, todoItem.IsComplete);
+}
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup/Program.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup/Program.cs
new file mode 100644
index 000000000000..2a82ad8c9f76
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup/Program.cs
@@ -0,0 +1,60 @@
+//
+using Microsoft.EntityFrameworkCore;
+
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddDbContext(opt => opt.UseInMemoryDatabase("TodoList"));
+builder.Services.AddDatabaseDeveloperPageExceptionFilter();
+var app = builder.Build();
+
+//
+var todoItems = app.MapGroup("/todoitems");
+
+todoItems.MapGet("/", async (TodoDb db) =>
+ await db.Todos.ToListAsync());
+
+todoItems.MapGet("/complete", async (TodoDb db) =>
+ await db.Todos.Where(t => t.IsComplete).ToListAsync());
+
+todoItems.MapGet("/{id}", async (int id, TodoDb db) =>
+ await db.Todos.FindAsync(id)
+ is Todo todo
+ ? Results.Ok(todo)
+ : Results.NotFound());
+
+todoItems.MapPost("/", async (Todo todo, TodoDb db) =>
+{
+ db.Todos.Add(todo);
+ await db.SaveChangesAsync();
+
+ return Results.Created($"/todoitems/{todo.Id}", todo);
+});
+
+todoItems.MapPut("/{id}", async (int id, Todo inputTodo, TodoDb db) =>
+{
+ var todo = await db.Todos.FindAsync(id);
+
+ if (todo is null) return Results.NotFound();
+
+ todo.Name = inputTodo.Name;
+ todo.IsComplete = inputTodo.IsComplete;
+
+ await db.SaveChangesAsync();
+
+ return Results.NoContent();
+});
+
+todoItems.MapDelete("/{id}", async (int id, TodoDb db) =>
+{
+ if (await db.Todos.FindAsync(id) is Todo todo)
+ {
+ db.Todos.Remove(todo);
+ await db.SaveChangesAsync();
+ return Results.NoContent();
+ }
+
+ return Results.NotFound();
+});
+//
+
+app.Run();
+//
\ No newline at end of file
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup/Todo.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup/Todo.cs
new file mode 100644
index 000000000000..986d0c7de8c4
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup/Todo.cs
@@ -0,0 +1,6 @@
+public class Todo
+{
+ public int Id { get; set; }
+ public string? Name { get; set; }
+ public bool IsComplete { get; set; }
+}
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup/TodoApi.csproj b/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup/TodoApi.csproj
new file mode 100644
index 000000000000..abc9f7648bf9
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup/TodoApi.csproj
@@ -0,0 +1,14 @@
+
+
+
+ net9.0
+ enable
+ enable
+
+
+
+
+
+
+
+
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup/TodoDb.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup/TodoDb.cs
new file mode 100644
index 000000000000..c1584b807819
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup/TodoDb.cs
@@ -0,0 +1,9 @@
+using Microsoft.EntityFrameworkCore;
+
+class TodoDb : DbContext
+{
+ public TodoDb(DbContextOptions options)
+ : base(options) { }
+
+ public DbSet Todos => Set();
+}
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup_SwaggerVersion/Program.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup_SwaggerVersion/Program.cs
new file mode 100644
index 000000000000..3787cd75a0ce
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup_SwaggerVersion/Program.cs
@@ -0,0 +1,81 @@
+//
+using Microsoft.EntityFrameworkCore;
+
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddDbContext(opt => opt.UseInMemoryDatabase("TodoList"));
+builder.Services.AddDatabaseDeveloperPageExceptionFilter();
+
+builder.Services.AddEndpointsApiExplorer();
+builder.Services.AddOpenApiDocument(config =>
+{
+ config.DocumentName = "TodoAPI";
+ config.Title = "TodoAPI v1";
+ config.Version = "v1";
+});
+
+var app = builder.Build();
+
+if (app.Environment.IsDevelopment())
+{
+ app.UseOpenApi();
+ app.UseSwaggerUi(config =>
+ {
+ config.DocumentTitle = "TodoAPI";
+ config.Path = "/swagger";
+ config.DocumentPath = "/swagger/{documentName}/swagger.json";
+ config.DocExpansion = "list";
+ });
+}
+
+//
+var todoItems = app.MapGroup("/todoitems");
+
+todoItems.MapGet("/", async (TodoDb db) =>
+ await db.Todos.ToListAsync());
+
+todoItems.MapGet("/complete", async (TodoDb db) =>
+ await db.Todos.Where(t => t.IsComplete).ToListAsync());
+
+todoItems.MapGet("/{id}", async (int id, TodoDb db) =>
+ await db.Todos.FindAsync(id)
+ is Todo todo
+ ? Results.Ok(todo)
+ : Results.NotFound());
+
+todoItems.MapPost("/", async (Todo todo, TodoDb db) =>
+{
+ db.Todos.Add(todo);
+ await db.SaveChangesAsync();
+
+ return Results.Created($"/todoitems/{todo.Id}", todo);
+});
+
+todoItems.MapPut("/{id}", async (int id, Todo inputTodo, TodoDb db) =>
+{
+ var todo = await db.Todos.FindAsync(id);
+
+ if (todo is null) return Results.NotFound();
+
+ todo.Name = inputTodo.Name;
+ todo.IsComplete = inputTodo.IsComplete;
+
+ await db.SaveChangesAsync();
+
+ return Results.NoContent();
+});
+
+todoItems.MapDelete("/{id}", async (int id, TodoDb db) =>
+{
+ if (await db.Todos.FindAsync(id) is Todo todo)
+ {
+ db.Todos.Remove(todo);
+ await db.SaveChangesAsync();
+ return Results.NoContent();
+ }
+
+ return Results.NotFound();
+});
+//
+
+app.Run();
+//
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup_SwaggerVersion/Todo.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup_SwaggerVersion/Todo.cs
new file mode 100644
index 000000000000..986d0c7de8c4
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup_SwaggerVersion/Todo.cs
@@ -0,0 +1,6 @@
+public class Todo
+{
+ public int Id { get; set; }
+ public string? Name { get; set; }
+ public bool IsComplete { get; set; }
+}
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup_SwaggerVersion/TodoApi.csproj b/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup_SwaggerVersion/TodoApi.csproj
new file mode 100644
index 000000000000..067275c7128b
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup_SwaggerVersion/TodoApi.csproj
@@ -0,0 +1,15 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup_SwaggerVersion/TodoDb.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup_SwaggerVersion/TodoDb.cs
new file mode 100644
index 000000000000..c1584b807819
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoGroup_SwaggerVersion/TodoDb.cs
@@ -0,0 +1,9 @@
+using Microsoft.EntityFrameworkCore;
+
+class TodoDb : DbContext
+{
+ public TodoDb(DbContextOptions options)
+ : base(options) { }
+
+ public DbSet Todos => Set();
+}
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults/Program.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults/Program.cs
new file mode 100644
index 000000000000..591f97decb52
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults/Program.cs
@@ -0,0 +1,79 @@
+//
+using Microsoft.EntityFrameworkCore;
+
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddDbContext(opt => opt.UseInMemoryDatabase("TodoList"));
+builder.Services.AddDatabaseDeveloperPageExceptionFilter();
+var app = builder.Build();
+
+//
+var todoItems = app.MapGroup("/todoitems");
+
+todoItems.MapGet("/", GetAllTodos);
+todoItems.MapGet("/complete", GetCompleteTodos);
+todoItems.MapGet("/{id}", GetTodo);
+todoItems.MapPost("/", CreateTodo);
+todoItems.MapPut("/{id}", UpdateTodo);
+todoItems.MapDelete("/{id}", DeleteTodo);
+//
+
+app.Run();
+
+//
+//
+static async Task GetAllTodos(TodoDb db)
+{
+ return TypedResults.Ok(await db.Todos.ToArrayAsync());
+}
+//
+
+static async Task GetCompleteTodos(TodoDb db)
+{
+ return TypedResults.Ok(await db.Todos.Where(t => t.IsComplete).ToListAsync());
+}
+
+//
+static async Task GetTodo(int id, TodoDb db)
+{
+ return await db.Todos.FindAsync(id)
+ is Todo todo
+ ? TypedResults.Ok(todo)
+ : TypedResults.NotFound();
+}
+//
+
+static async Task CreateTodo(Todo todo, TodoDb db)
+{
+ db.Todos.Add(todo);
+ await db.SaveChangesAsync();
+
+ return TypedResults.Created($"/todoitems/{todo.Id}", todo);
+}
+
+static async Task UpdateTodo(int id, Todo inputTodo, TodoDb db)
+{
+ var todo = await db.Todos.FindAsync(id);
+
+ if (todo is null) return TypedResults.NotFound();
+
+ todo.Name = inputTodo.Name;
+ todo.IsComplete = inputTodo.IsComplete;
+
+ await db.SaveChangesAsync();
+
+ return TypedResults.NoContent();
+}
+
+static async Task DeleteTodo(int id, TodoDb db)
+{
+ if (await db.Todos.FindAsync(id) is Todo todo)
+ {
+ db.Todos.Remove(todo);
+ await db.SaveChangesAsync();
+ return TypedResults.NoContent();
+ }
+
+ return TypedResults.NotFound();
+}
+//
+//
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults/Todo.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults/Todo.cs
new file mode 100644
index 000000000000..2900a835b043
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults/Todo.cs
@@ -0,0 +1,6 @@
+class Todo
+{
+ public int Id { get; set; }
+ public string? Name { get; set; }
+ public bool IsComplete { get; set; }
+}
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults/TodoApi.csproj b/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults/TodoApi.csproj
new file mode 100644
index 000000000000..abc9f7648bf9
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults/TodoApi.csproj
@@ -0,0 +1,14 @@
+
+
+
+ net9.0
+ enable
+ enable
+
+
+
+
+
+
+
+
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults/TodoDb.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults/TodoDb.cs
new file mode 100644
index 000000000000..c1584b807819
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults/TodoDb.cs
@@ -0,0 +1,9 @@
+using Microsoft.EntityFrameworkCore;
+
+class TodoDb : DbContext
+{
+ public TodoDb(DbContextOptions options)
+ : base(options) { }
+
+ public DbSet Todos => Set();
+}
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults_SwaggerVersion/Program.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults_SwaggerVersion/Program.cs
new file mode 100644
index 000000000000..522968205c21
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults_SwaggerVersion/Program.cs
@@ -0,0 +1,100 @@
+//
+using Microsoft.EntityFrameworkCore;
+
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddDbContext(opt => opt.UseInMemoryDatabase("TodoList"));
+builder.Services.AddDatabaseDeveloperPageExceptionFilter();
+
+builder.Services.AddEndpointsApiExplorer();
+builder.Services.AddOpenApiDocument(config =>
+{
+ config.DocumentName = "TodoAPI";
+ config.Title = "TodoAPI v1";
+ config.Version = "v1";
+});
+
+var app = builder.Build();
+
+if (app.Environment.IsDevelopment())
+{
+ app.UseOpenApi();
+ app.UseSwaggerUi(config =>
+ {
+ config.DocumentTitle = "TodoAPI";
+ config.Path = "/swagger";
+ config.DocumentPath = "/swagger/{documentName}/swagger.json";
+ config.DocExpansion = "list";
+ });
+}
+
+//
+var todoItems = app.MapGroup("/todoitems");
+
+todoItems.MapGet("/", GetAllTodos);
+todoItems.MapGet("/complete", GetCompleteTodos);
+todoItems.MapGet("/{id}", GetTodo);
+todoItems.MapPost("/", CreateTodo);
+todoItems.MapPut("/{id}", UpdateTodo);
+todoItems.MapDelete("/{id}", DeleteTodo);
+//
+
+app.Run();
+
+//
+//
+static async Task GetAllTodos(TodoDb db)
+{
+ return TypedResults.Ok(await db.Todos.ToArrayAsync());
+}
+//
+
+static async Task GetCompleteTodos(TodoDb db)
+{
+ return TypedResults.Ok(await db.Todos.Where(t => t.IsComplete).ToListAsync());
+}
+
+//
+static async Task GetTodo(int id, TodoDb db)
+{
+ return await db.Todos.FindAsync(id)
+ is Todo todo
+ ? TypedResults.Ok(todo)
+ : TypedResults.NotFound();
+}
+//
+
+static async Task CreateTodo(Todo todo, TodoDb db)
+{
+ db.Todos.Add(todo);
+ await db.SaveChangesAsync();
+
+ return TypedResults.Created($"/todoitems/{todo.Id}", todo);
+}
+
+static async Task UpdateTodo(int id, Todo inputTodo, TodoDb db)
+{
+ var todo = await db.Todos.FindAsync(id);
+
+ if (todo is null) return TypedResults.NotFound();
+
+ todo.Name = inputTodo.Name;
+ todo.IsComplete = inputTodo.IsComplete;
+
+ await db.SaveChangesAsync();
+
+ return TypedResults.NoContent();
+}
+
+static async Task DeleteTodo(int id, TodoDb db)
+{
+ if (await db.Todos.FindAsync(id) is Todo todo)
+ {
+ db.Todos.Remove(todo);
+ await db.SaveChangesAsync();
+ return TypedResults.NoContent();
+ }
+
+ return TypedResults.NotFound();
+}
+//
+//
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults_SwaggerVersion/Todo.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults_SwaggerVersion/Todo.cs
new file mode 100644
index 000000000000..2900a835b043
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults_SwaggerVersion/Todo.cs
@@ -0,0 +1,6 @@
+class Todo
+{
+ public int Id { get; set; }
+ public string? Name { get; set; }
+ public bool IsComplete { get; set; }
+}
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults_SwaggerVersion/TodoApi.csproj b/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults_SwaggerVersion/TodoApi.csproj
new file mode 100644
index 000000000000..067275c7128b
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults_SwaggerVersion/TodoApi.csproj
@@ -0,0 +1,15 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults_SwaggerVersion/TodoDb.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults_SwaggerVersion/TodoDb.cs
new file mode 100644
index 000000000000..c1584b807819
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todoTypedResults_SwaggerVersion/TodoDb.cs
@@ -0,0 +1,9 @@
+using Microsoft.EntityFrameworkCore;
+
+class TodoDb : DbContext
+{
+ public TodoDb(DbContextOptions options)
+ : base(options) { }
+
+ public DbSet Todos => Set();
+}
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todo_SwaggerVersion/Program.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todo_SwaggerVersion/Program.cs
new file mode 100644
index 000000000000..b657be5cd7ad
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todo_SwaggerVersion/Program.cs
@@ -0,0 +1,149 @@
+#define FINAL // MINIMAL FINAL TYPEDR
+#if MINIMAL
+//
+var builder = WebApplication.CreateBuilder(args);
+var app = builder.Build();
+
+app.MapGet("/", () => "Hello World!");
+
+app.Run();
+//
+#elif FINAL
+//
+//
+using Microsoft.EntityFrameworkCore;
+
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddDbContext(opt => opt.UseInMemoryDatabase("TodoList"));
+builder.Services.AddDatabaseDeveloperPageExceptionFilter();
+
+builder.Services.AddEndpointsApiExplorer();
+builder.Services.AddOpenApiDocument(config =>
+{
+ config.DocumentName = "TodoAPI";
+ config.Title = "TodoAPI v1";
+ config.Version = "v1";
+});
+//
+var app = builder.Build();
+//
+if (app.Environment.IsDevelopment())
+{
+ app.UseOpenApi();
+ app.UseSwaggerUi(config =>
+ {
+ config.DocumentTitle = "TodoAPI";
+ config.Path = "/swagger";
+ config.DocumentPath = "/swagger/{documentName}/swagger.json";
+ config.DocExpansion = "list";
+ });
+}
+//
+//
+app.MapGet("/todoitems", async (TodoDb db) =>
+ await db.Todos.ToListAsync());
+
+app.MapGet("/todoitems/complete", async (TodoDb db) =>
+ await db.Todos.Where(t => t.IsComplete).ToListAsync());
+
+//
+app.MapGet("/todoitems/{id}", async (int id, TodoDb db) =>
+ await db.Todos.FindAsync(id)
+ is Todo todo
+ ? Results.Ok(todo)
+ : Results.NotFound());
+//
+//
+
+//
+app.MapPost("/todoitems", async (Todo todo, TodoDb db) =>
+{
+ db.Todos.Add(todo);
+ await db.SaveChangesAsync();
+
+ return Results.Created($"/todoitems/{todo.Id}", todo);
+});
+//
+
+//
+app.MapPut("/todoitems/{id}", async (int id, Todo inputTodo, TodoDb db) =>
+{
+ var todo = await db.Todos.FindAsync(id);
+
+ if (todo is null) return Results.NotFound();
+
+ todo.Name = inputTodo.Name;
+ todo.IsComplete = inputTodo.IsComplete;
+
+ await db.SaveChangesAsync();
+
+ return Results.NoContent();
+});
+//
+
+//
+app.MapDelete("/todoitems/{id}", async (int id, TodoDb db) =>
+{
+ if (await db.Todos.FindAsync(id) is Todo todo)
+ {
+ db.Todos.Remove(todo);
+ await db.SaveChangesAsync();
+ return Results.NoContent();
+ }
+
+ return Results.NotFound();
+});
+//
+
+app.Run();
+//
+#elif TYPEDR
+using Microsoft.AspNetCore.Http.HttpResults;
+using Microsoft.EntityFrameworkCore;
+
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddDbContext(opt => opt.UseInMemoryDatabase("TodoList"));
+builder.Services.AddDatabaseDeveloperPageExceptionFilter();
+var app = builder.Build();
+
+app.MapGet("/todoitems", async (TodoDb db) =>
+ await db.Todos.ToListAsync());
+
+app.MapGet("/todoitems/complete", async (TodoDb db) =>
+ await db.Todos.Where(t => t.IsComplete).ToListAsync());
+
+app.MapGet("/todoitems/{id}", async (int id, TodoDb db) =>
+ await db.Todos.FindAsync(id)
+ is Todo todo
+ ? Results.Ok(todo)
+ : Results.NotFound());
+
+//
+ app.MapGet("/todos/{id}", async Task, NotFound>> (int id, TodoDb db) =>
+ await db.Todos.FindAsync(id)
+ is Todo todo
+ ? TypedResults.Ok(todo)
+ : TypedResults.NotFound());
+//
+
+/*
+//
+app.MapGet("/todos/{id}", async (int id, TodoDb db) =>
+ await db.Todos.FindAsync(id)
+ is Todo todo
+ ? TypedResults.Ok(todo)
+ : TypedResults.NotFound());
+//
+*/
+
+//
+app.MapGet("/hello", () => Results.Ok(new Message() { Text = "Hello World!" }))
+ .Produces();
+//
+
+//
+app.MapGet("/hello2", () => TypedResults.Ok(new Message() { Text = "Hello World!" }));
+//
+
+app.Run();
+#endif
\ No newline at end of file
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todo_SwaggerVersion/Todo.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todo_SwaggerVersion/Todo.cs
new file mode 100644
index 000000000000..86aba6a37cee
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todo_SwaggerVersion/Todo.cs
@@ -0,0 +1,6 @@
+public class Todo
+{
+ public int Id { get; set; }
+ public string? Name { get; set; }
+ public bool IsComplete { get; set; }
+}
\ No newline at end of file
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todo_SwaggerVersion/TodoApi.csproj b/aspnetcore/tutorials/min-web-api/samples/10.x/todo_SwaggerVersion/TodoApi.csproj
new file mode 100644
index 000000000000..067275c7128b
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todo_SwaggerVersion/TodoApi.csproj
@@ -0,0 +1,15 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
diff --git a/aspnetcore/tutorials/min-web-api/samples/10.x/todo_SwaggerVersion/TodoDb.cs b/aspnetcore/tutorials/min-web-api/samples/10.x/todo_SwaggerVersion/TodoDb.cs
new file mode 100644
index 000000000000..d202ecad4cc8
--- /dev/null
+++ b/aspnetcore/tutorials/min-web-api/samples/10.x/todo_SwaggerVersion/TodoDb.cs
@@ -0,0 +1,9 @@
+using Microsoft.EntityFrameworkCore;
+
+class TodoDb : DbContext
+{
+ public TodoDb(DbContextOptions options)
+ : base(options) { }
+
+ public DbSet Todos => Set();
+}
\ No newline at end of file