Build a minimal API using ASP.NET Core with Android Studio
Building HTTP APIs with fewer dependencies is facilitated by minimal API. These new ASP.Net Core Web API are ideal for microservices and applications that have few features, files, and other dependencies of that kind.
We provide a step-by-step tutorial on creating a minimal API for your application in this ASP.Net Core course. Building an ASP.Net API can be done in a variety of ways, one of which is by using controllers. Go to APIs Overview if you're having trouble deciding between a minimal API and a controller-based API.
If you are looking to develop ASP.NET Core Application using Angular then read our >blog 1 and >blog 2.
Overview
In this ASP.Net Core tutorial, you will get the below-mentioned API. The core produces responseType API which helps you analyze the type of data included in the response.
API | Description | Request body | Response body |
GET /todoitems/complete | Get a completed to-do items | None | Array of to-do items |
POST /todoitems | Add a new item | To-do item | To-do item |
GET /todoitems | Receive all to-do items | None | Array of to-do items |
GET /todoitems/{id} | Receive an item by ID | None | To-do item |
DELETE /todoitems/{id} | Delete an item | None | None |
PUT /todoitems/{id} | Updating an existing item | To-do item | None |
Prerequisite
Install> Visual Studio 2022 for web application and ASP.Net workload.

Source: learn.microsoft.com
Step 1: Build an API Project
Open Visual Studio 2022, then create a new project.
Access the 'New Project' dialog box.
In the "Search for templates" box, enter "Empty."
After selecting "ASP.Net Core Empty," click the "Next" button.

Source: learn.microsoft.com
After naming your project TodoApi, click the "Next" button. This is the new web API from Dot Net.
Proceed to the dialog box for additional information.
Select ".NET 7.0."
Uncheck the "Use top-level statements" box.
Choose the 'Create' menu item.
Step 2: Examine the code
Below is the code of the Program.cs file includes. Right, the C# code for minimal API.
C# |
var builder = WebApplication.CreateBuilder(args); var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
|
Source: learn.microsoft.com
Here is the previous code. Create a Web API in ASP.Net using C# code.
Make a "WebApplication" and "WebApplicationBuilder" with default settings that are already set.
Construct an HTTP Obtain endpoints "/" that return "Hello World!"
Step 3: Launch the program
If you want to run without the debugger, press Ctrl+F5.
This is the message that Visual Studio will show.

Source: learn.microsoft.com
If you are confident in the IIS Express SSL Certificate, click the "Yes" option.
It will show the dialog box that follows.

Source: learn.microsoft.com
Now, select "Yes" if you believe the development certificate to be reliable.
The Hello World! a message appeared in the browser. The Program.cs file is a full application with very few dependencies.
Step 4: Add NuGet packages
It is necessary to add these NuGet packages because they support the database and diagnostics.
Select "NuGet Package Manager" from the "Tools" menu, followed by "Manage NuGet Packages for Solution."
Opt for the "Browse" tab.
Choose "Microsoft.EntityFrameworkCore.InMemory" after entering "Microsoft.EntityFrameworkCore.InMemory" in the search box.
Select "Install" after selecting the "Project" checkbox on the pane's right.
Now add the "Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" package by following the instructions above.
Step 5: The database and model context classes
C# |
class Todo { public int Id { get; set; } public string? Name { get; set; } public bool IsComplete { get; set; } } |
The aforementioned code builds the model for your app.
Create a TodoDB.cs file name using the below-mentioned code.
C# |
using Microsoft.EntityFrameworkCore;
class TodoDb : DbContext { public TodoDb(DbContextOptions<TodoDb> options) : base(options) { }
public DbSet<Todo> Todos => Set<Todo>(); } |
The above code describes the database context, a main class that coordinates functionality like Entity Framework for a data model.
Adding the API Code
Use the following code and replace the content in the Program.cs file.
C# |
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args); builder.Services.AddDbContext<TodoDb>(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.Ok(todo); }
return Results.NotFound(); });
app.Run(); |
The code that follows gives the dependency injection (DI) container access to the database context and enables the display of exceptions pertaining to databases.
C# |
var builder = WebApplication.CreateBuilder(args); builder.Services.AddDbContext<TodoDb>(opt => opt.UseInMemoryDatabase("TodoList")); builder.Services.AddDatabaseDeveloperPageExceptionFilter(); var app = builder.Build(); |
Test your app by installing Postman
Set up Postman.
Launch the web application.
Turn off SSL certificate verification and launch Postman.
Select File > Settings (General tab) > Disable SSL certificate verification in Windows.
Test data posting
The code in Program.cs that follows is an HTTP POST endpoint called /todoitems that adds data to the database in-memory.
C# |
app.MapPost("/todoitems", async (Todo todo, TodoDb db) => { db.Todos.Add(todo); await db.SaveChangesAsync();
return Results.Created($"/todoitems/{todo.Id}", todo); }); |
Now, run the application. The browser will display an error 404 because it does not have a ‘/’ endpoint.
Use the endpoint of POST to add the data to your application.
Create an HTTP request
HTTP method needs to be set to Post
Set the URL to ‘>https://localhost:<port>/todoitems’. For instance:> https://localhost:5001/todoitems
Choose the Body tab
Select raw
Choose the type to ‘JSON.’
Type JSON in the to-do item in the request body.
JSON |
{ "name":"walk dog", "isComplete":true } |
Choose the ‘Send’ option at the top right.
Analyze the GET endpoints
The following API you will get by calling ‘MapGet’.
API | Description | Request body | Request response |
GET /todoitems/complete | Get all completed to-do items | None | Array of to-do items |
GET /todoitems/{id} | Get an item by ID | None | To-do item |
GET /todoitems | Get all to-do items | None | Array of to-do items |
Use the MapGroup API
A common URL prefix is frequently shared by groups of API endpoints. With MapGroup, you can arrange these groups in an orderly fashion. With just a single call to methods like >WithMetadata and >RequireAuthorization, it can customize entire groups of endpoints.
Replace the Program.cs content with the following code.
C# |
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args); builder.Services.AddDbContext<TodoDb>(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.Ok(todo); }
return Results.NotFound(); });
app.Run(); |
Test the TypedResults API
Call route handler methods with Map<HttpVerb> rather than using lambdas.
C# |
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args); builder.Services.AddDbContext<TodoDb>(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<IResult> GetAllTodos(TodoDb db) { return TypedResults.Ok(await db.Todos.ToArrayAsync()); }
static async Task<IResult> GetCompleteTodos(TodoDb db) { return TypedResults.Ok(await db.Todos.Where(t => t.IsComplete).ToListAsync()); }
static async Task<IResult> GetTodo(int id, TodoDb db) { return await db.Todos.FindAsync(id) is Todo todo ? TypedResults.Ok(todo) : TypedResults.NotFound(); }
static async Task<IResult> CreateTodo(Todo todo, TodoDb db) { db.Todos.Add(todo); await db.SaveChangesAsync();
return TypedResults.Created($"/todoitems/{todo.Id}", todo); }
static async Task<IResult> 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<IResult> DeleteTodo(int id, TodoDb db) { if (await db.Todos.FindAsync(id) is Todo todo) { db.Todos.Remove(todo); await db.SaveChangesAsync(); return TypedResults.Ok(todo); }
return TypedResults.NotFound(); } |
Now, the Map<HttpVerb> code calls methods rather than lambdas.
C# |
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); |
The aforementioned methods implement IResult and are described by TypedResults.
C# |
static async Task<IResult> GetAllTodos(TodoDb db) { return TypedResults.Ok(await db.Todos.ToArrayAsync()); }
static async Task<IResult> GetCompleteTodos(TodoDb db) { return TypedResults.Ok(await db.Todos.Where(t => t.IsComplete).ToListAsync()); }
static async Task<IResult> GetTodo(int id, TodoDb db) { return await db.Todos.FindAsync(id) is Todo todo ? TypedResults.Ok(todo) : TypedResults.NotFound(); }
static async Task<IResult> CreateTodo(Todo todo, TodoDb db) { db.Todos.Add(todo); await db.SaveChangesAsync();
return TypedResults.Created($"/todoitems/{todo.Id}", todo); }
static async Task<IResult> 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<IResult> DeleteTodo(int id, TodoDb db) { if (await db.Todos.FindAsync(id) is Todo todo) { db.Todos.Remove(todo); await db.SaveChangesAsync(); return TypedResults.Ok(todo); }
return TypedResults.NotFound(); } |
Handler method return of Type OK<Todo[]> can be verified by the test code.
C# |
public async Task GetAllTodos_ReturnsOkOfTodosResult() { // Arrange var db = CreateDbContext();
// Act var result = await TodosApi.GetAllTodos(db);
// Assert: Check for the correct returned type Assert.IsType<Ok<Todo[]>>(result); } |
Step:6 JSON serialization option configuration
If you need more information, navigate to> Configure JSON serialization option.
Follow the above steps to create ASP.Net Core API without hustling much.
Suggested blogs:
>Use Firebase Realtime Database with ASP.NET MVC App
>Built Web API using ASP.NET (C#)
>CRUD Operations In ASP.NET Core Using Entity Framework Core Code First with Angularjs
>Changing main page as Identity's Login page in ASP.NET Core 7
>How can I get the original type of a Mock after the Mock has been cast to an object
>How to show value on a second razor page passed from the first?
>Fix ASP.NET Core Model Binding Not Working issue