Nguon: Microsoft Learn · .NET 8.0
Tài liệu tham khảo nhanh về Minimal APIs
Nguồn: Minimal APIs quick reference
WebApplication
Cài đặt cơ bản
csharp
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();Cách tạo thay thế
csharp
var app = WebApplication.Create(args);
app.MapGet("/", () => "Hello World!");
app.Run();Làm việc với Ports (cổng)
Một cổng
csharp
var app = WebApplication.Create(args);
app.MapGet("/", () => "Hello World!");
app.Run("http://localhost:3000");Nhiều cổng
csharp
var app = WebApplication.Create(args);
app.Urls.Add("http://localhost:3000");
app.Urls.Add("http://localhost:4000");
app.MapGet("/", () => "Hello World");
app.Run();Dòng lệnh
dotnetcli
dotnet run --urls="https://localhost:7777"
Biến môi trường
code
ASPNETCORE_URLS=http://localhost:3000 ASPNETCORE_URLS=http://localhost:3000;https://localhost:5000
Lắng nghe trên tất cả các giao diện mạng
csharp
// Dùng ký tự đại diện
app.Urls.Add("http://*:3000");
// Dùng dấu cộng
app.Urls.Add("http://+:3000");
// Dùng địa chỉ IP
app.Urls.Add("http://0.0.0.0:3000");Biến môi trường:
code
ASPNETCORE_URLS=http://*:3000;https://+:5000;http://0.0.0.0:5005 ASPNETCORE_HTTP_PORTS=3000;5005 ASPNETCORE_HTTPS_PORTS=5000
Cấu hình HTTPS
Certificate (chứng chỉ) phát triển
csharp
var app = WebApplication.Create(args);
app.Urls.Add("https://localhost:3000");
app.MapGet("/", () => "Hello World");
app.Run();Certificate tùy chỉnh qua appsettings.json
json
{
"Kestrel": {
"Certificates": {
"Default": {
"Path": "cert.pem",
"KeyPath": "key.pem"
}
}
}
}Certificate tùy chỉnh qua cấu hình code
csharp
var builder = WebApplication.CreateBuilder(args);
builder.Configuration["Kestrel:Certificates:Default:Path"] = "cert.pem";
builder.Configuration["Kestrel:Certificates:Default:KeyPath"] = "key.pem";
var app = builder.Build();
app.Urls.Add("https://localhost:3000");
app.MapGet("/", () => "Hello World");
app.Run();Dùng Certificate APIs
csharp
using System.Security.Cryptography.X509Certificates;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(options =>
{
options.ConfigureHttpsDefaults(httpsOptions =>
{
var certPath = Path.Combine(builder.Environment.ContentRootPath, "cert.pem");
var keyPath = Path.Combine(builder.Environment.ContentRootPath, "key.pem");
httpsOptions.ServerCertificate = X509Certificate2.CreateFromPemFile(certPath, keyPath);
});
});
var app = builder.Build();
app.Urls.Add("https://localhost:3000");
app.MapGet("/", () => "Hello World");
app.Run();Cấu hình WebApplicationBuilder
Thay đổi Content Root, Application Name và Environment (môi trường)
csharp
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
ApplicationName = typeof(Program).Assembly.FullName,
ContentRootPath = Directory.GetCurrentDirectory(),
EnvironmentName = Environments.Staging,
WebRootPath = "customwwwroot"
});
Console.WriteLine($"Application Name: {builder.Environment.ApplicationName}");
Console.WriteLine($"Environment Name: {builder.Environment.EnvironmentName}");
Console.WriteLine($"ContentRoot Path: {builder.Environment.ContentRootPath}");
Console.WriteLine($"WebRootPath: {builder.Environment.WebRootPath}");
var app = builder.Build();Biến môi trường và đối số dòng lệnh
| Tính năng | Biến môi trường | Đối số dòng lệnh |
|---|---|---|
| Application name | ASPNETCORE_APPLICATIONNAME | --applicationName |
| Environment name | ASPNETCORE_ENVIRONMENT | --environment |
| Content root | ASPNETCORE_CONTENTROOT | --contentRoot |
Thêm Configuration Providers (nhà cung cấp cấu hình)
csharp
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddIniFile("appsettings.ini");
var app = builder.Build();Đọc Configuration
csharp
var builder = WebApplication.CreateBuilder(args);
var message = builder.Configuration["HelloKey"] ?? "Hello";
var app = builder.Build();
app.MapGet("/", () => message);
app.Run();Kiểm tra Environment
csharp
var builder = WebApplication.CreateBuilder(args);
if (builder.Environment.IsDevelopment())
{
Console.WriteLine($"Running in development.");
}
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();Thêm Logging Providers (nhà cung cấp ghi log)
csharp
var builder = WebApplication.CreateBuilder(args);
builder.Logging.AddJsonConsole();
var app = builder.Build();
app.MapGet("/", () => "Hello JSON console!");
app.Run();Thêm Services (dịch vụ)
csharp
var builder = WebApplication.CreateBuilder(args); builder.Services.AddMemoryCache(); builder.Services.AddScoped<ITodoRepository, TodoRepository>(); var app = builder.Build();
Tùy chỉnh IHostBuilder
csharp
var builder = WebApplication.CreateBuilder(args);
builder.Host.ConfigureHostOptions(o => o.ShutdownTimeout = TimeSpan.FromSeconds(30));
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();Tùy chỉnh IWebHostBuilder
csharp
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseHttpSys();
var app = builder.Build();
app.MapGet("/", () => "Hello HTTP.sys");
app.Run();Thay đổi Web Root
csharp
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
WebRootPath = "webroot"
});
var app = builder.Build();
app.Run();DI Container (vùng chứa Dependency Injection) tùy chỉnh - ví dụ Autofac
csharp
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
builder.RegisterModule(new MyApplicationModule()));
var app = builder.Build();Middleware (phần mềm trung gian)
Các middleware phổ biến cho Minimal APIs:
| Middleware | Mô tả | API |
|---|---|---|
| Authentication (xác thực) | Hỗ trợ xác thực | UseAuthentication |
| Authorization (phân quyền) | Hỗ trợ phân quyền | UseAuthorization |
| CORS | Cấu hình Cross-Origin Resource Sharing | UseCors |
| Exception Handler | Xử lý exception toàn cục | UseExceptionHandler |
| Forwarded Headers | Chuyển tiếp các header được proxy | UseForwardedHeaders |
| HTTPS Redirection | Chuyển hướng HTTP sang HTTPS | UseHttpsRedirection |
| HSTS | HTTP Strict Transport Security | UseHsts |
| Request Logging | Ghi log HTTP request/response | UseHttpLogging |
| Request Timeouts | Cấu hình timeout cho request | UseRequestTimeouts |
| W3C Request Logging | Ghi log request định dạng W3C | UseW3CLogging |
| Response Caching | Cache (bộ nhớ đệm) response | UseResponseCaching |
| Response Compression | Nén response | UseResponseCompression |
| Session | Quản lý phiên người dùng | UseSession |
| Static Files | Phục vụ file tĩnh | UseStaticFiles, UseFileServer |
| WebSockets | Bật giao thức WebSockets | UseWebSockets |
Thêm Middleware
csharp
var app = WebApplication.Create(args);
app.UseFileServer();
app.MapGet("/", () => "Hello World!");
app.Run();Routing (định tuyến)
Các HTTP Verbs (phương thức HTTP)
csharp
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "This is a GET");
app.MapPost("/", () => "This is a POST");
app.MapPut("/", () => "This is a PUT");
app.MapDelete("/", () => "This is a DELETE");
app.MapMethods("/options-or-head", new[] { "OPTIONS", "HEAD" },
() => "This is an options or head request");
app.Run();Route Handlers (bộ xử lý route)
Lambda expression (biểu thức lambda)
csharp
app.MapGet("/inline", () => "This is an inline lambda");
var handler = () => "This is a lambda variable";
app.MapGet("/", handler);Local Function (hàm cục bộ)
csharp
string LocalFunction() => "This is local function";
app.MapGet("/", LocalFunction);Instance Method (phương thức của đối tượng)
csharp
var handler = new HelloHandler();
app.MapGet("/", handler.Hello);
class HelloHandler
{
public string Hello()
{
return "Hello Instance method";
}
}Static Method (phương thức tĩnh)
csharp
app.MapGet("/", HelloHandler.Hello);
class HelloHandler
{
public static string Hello()
{
return "Hello static method";
}
}Endpoint định nghĩa ngoài Program.cs
Program.cs
csharp
using MinAPISeparateFile; var builder = WebApplication.CreateSlimBuilder(args); var app = builder.Build(); TodoEndpoints.Map(app); app.Run();
TodoEndpoints.cs
csharp
namespace MinAPISeparateFile;
public static class TodoEndpoints
{
public static void Map(WebApplication app)
{
app.MapGet("/", async context =>
{
await context.Response.WriteAsJsonAsync(new { Message = "All todo items" });
});
app.MapGet("/{id}", async context =>
{
await context.Response.WriteAsJsonAsync(new { Message = "One todo item" });
});
}
}Named Endpoints (endpoint được đặt tên) và Link Generation (tạo liên kết)
csharp
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/hello", () => "Hello named route")
.WithName("hi");
app.MapGet("/", (LinkGenerator linker) =>
$"The link to the hello route is {linker.GetPathByName("hi", values: null)}");
app.Run();Tiêu chí đặt tên endpoint:
- Phân biệt chữ hoa/thường
- Phải là duy nhất toàn cục
- Được dùng làm OpenAPI operation ID
Route Parameters (tham số route)
csharp
app.MapGet("/users/{userId}/books/{bookId}",
(int userId, int bookId) => $"The user id is {userId} and book id is {bookId}");Wildcard và Catch-All Routes
csharp
app.MapGet("/posts/{*rest}", (string rest) => $"Routing to {rest}");Route Constraints (ràng buộc route)
csharp
app.MapGet("/todos/{id:int}", (int id) => db.Todos.Find(id));
app.MapGet("/todos/{text}", (string text) => db.Todos.Where(t => t.Text.Contains(text)));
app.MapGet("/posts/{slug:regex(^[a-z0-9_-]+$)}", (string slug) => $"Post {slug}");| Route Template | Ví dụ URI |
|---|---|
/todos/{id:int} | /todos/1 |
/todos/{text} | /todos/something |
/posts/{slug:regex(^[a-z0-9_-]+$)} | /posts/mypost |
Route Groups (nhóm route)
csharp
app.MapGroup("/public/todos")
.MapTodosApi()
.WithTags("Public");
app.MapGroup("/private/todos")
.MapTodosApi()
.WithTags("Private")
.AddEndpointFilterFactory(QueryPrivateTodos)
.RequireAuthorization();
public static RouteGroupBuilder MapTodosApi(this RouteGroupBuilder group)
{
group.MapGet("/", GetAllTodos);
group.MapGet("/{id}", GetTodo);
group.MapPost("/", CreateTodo);
group.MapPut("/{id}", UpdateTodo);
group.MapDelete("/{id}", DeleteTodo);
return group;
}Nested Route Groups (nhóm route lồng nhau)
csharp
var all = app.MapGroup("").WithOpenApi();
var org = all.MapGroup("{org}");
var user = org.MapGroup("{user}");
user.MapGet("", (string org, string user) => $"{org}/{user}");Parameter Binding (ràng buộc tham số)
Parameter binding chuyển đổi dữ liệu request thành các tham số strongly typed (kiểu mạnh).
Các nguồn binding được hỗ trợ:
- Giá trị route
- Query string (chuỗi truy vấn)
- Header (tiêu đề)
- Body (thân request, dạng JSON)
- Form values (giá trị form)
- Services từ DI
- Tùy chỉnh
csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<Service>();
var app = builder.Build();
app.MapGet("/{id}", (int id,
int page,
[FromHeader(Name = "X-CUSTOM-HEADER")] string customHeader,
Service service) => { });
class Service { }Các tính năng chính:
- Binding tường minh với các attribute (thuộc tính):
[FromRoute],[FromQuery],[FromHeader],[FromBody],[FromForm],[FromServices] - Form binding với
[FromForm]bao gồm hỗ trợIFormFile - Complex type binding (ràng buộc kiểu phức tạp) từ form, query và header
- Custom binding qua
TryParse,BindAsynchoặcIBindableFromHttpContext<T> - Tham số optional (tùy chọn) với kiểu nullable và giá trị mặc định
- Tự động DI injection
- Các kiểu đặc biệt:
HttpContext,HttpRequest,HttpResponse,CancellationToken,ClaimsPrincipal,Stream,PipeReader
Hỗ trợ Validation (kiểm tra hợp lệ) trong Minimal APIs
Bật validation bằng AddValidation:
csharp
builder.Services.AddValidation();
csharp
public record Product(
[Required] string Name,
[Range(1, 1000)] int Quantity);Tắt validation cho endpoint cụ thể:
csharp
app.MapPost("/products",
([EvenNumber(ErrorMessage = "Product ID must be even")] int productId, [Required] string name)
=> TypedResults.Ok(productId))
.DisableValidation();Responses (phản hồi)
Các kiểu giá trị trả về
| Kiểu trả về | Hành vi | Content-Type |
|---|---|---|
IResult | Framework gọi IResult.ExecuteAsync | Do implementation quyết định |
string | Ghi trực tiếp vào response | text/plain |
T (bất kỳ kiểu nào khác) | Serialize thành JSON | application/json |
Trả về String
csharp
app.MapGet("/hello", () => "Hello World");Trả về JSON
csharp
app.MapGet("/hello", () => new { Message = "Hello World" });TypedResults
csharp
app.MapGet("/hello", () => TypedResults.Ok(new Message() { Text = "Hello World!" }));IResult Return
csharp
app.MapGet("/hello", () => Results.Ok(new { Message = "Hello World" }));
app.MapGet("/api/todoitems/{id}", async (int id, TodoDb db) =>
await db.Todos.FindAsync(id)
is Todo todo
? Results.Ok(todo)
: Results.NotFound())
.Produces<Todo>(StatusCodes.Status200OK)
.Produces(StatusCodes.Status404NotFound);Các Results phổ biến
csharp
// JSON
app.MapGet("/hello", () => Results.Json(new { Message = "Hello World" }));
// Mã trạng thái tùy chỉnh
app.MapGet("/405", () => Results.StatusCode(405));
// Text
app.MapGet("/text", () => Results.Text("This is some text"));
// Stream
var proxyClient = new HttpClient();
app.MapGet("/pokemon", async () =>
{
var stream = await proxyClient.GetStreamAsync("http://contoso/pokedex.json");
return Results.Stream(stream, "application/json");
});
// Redirect (chuyển hướng)
app.MapGet("/old-path", () => Results.Redirect("/new-path"));
// File
app.MapGet("/download", () => Results.File("myfile.text"));Authorization (phân quyền)
csharp
using Microsoft.AspNetCore.Authorization;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthorization(o => o.AddPolicy("AdminsOnly",
b => b.RequireClaim("admin", "true")));
var app = builder.Build();
app.UseAuthorization();
app.MapGet("/auth", [Authorize] () => "This endpoint requires authorization.");
app.MapGet("/", () => "This endpoint doesn't require authorization.");
app.Run();Dùng RequireAuthorization
csharp
app.MapGet("/auth", () => "This endpoint requires authorization")
.RequireAuthorization();Authorization dựa trên Policy (chính sách)
csharp
app.MapGet("/admin", [Authorize("AdminsOnly")] () =>
"The /admin endpoint is for admins only.");
app.MapGet("/admin2", () => "The /admin2 endpoint is for admins only.")
.RequireAuthorization("AdminsOnly");Cho phép truy cập ẩn danh
csharp
app.MapGet("/login", [AllowAnonymous] () => "This endpoint is for all roles.");
app.MapGet("/login2", () => "This endpoint also for all roles.")
.AllowAnonymous();CORS (Cross-Origin Resource Sharing - Chia sẻ tài nguyên khác nguồn gốc)
csharp
const string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com");
});
});
var app = builder.Build();
app.UseCors();
app.MapGet("/", () => "Hello CORS!");
app.Run();Dùng Attributes
csharp
app.MapGet("/cors", [EnableCors(MyAllowSpecificOrigins)] () =>
"This endpoint allows cross origin requests!");
app.MapGet("/cors2", () => "This endpoint allows cross origin requests!")
.RequireCors(MyAllowSpecificOrigins);ValidateScopes và ValidateOnBuild
Được bật mặc định trong Development, tắt trong các môi trường khác để tăng hiệu suất.
Tắt Validation
csharp
var builder = WebApplication.CreateBuilder(args);
if (builder.Environment.IsDevelopment())
{
builder.Host.UseDefaultServiceProvider(options =>
{
options.ValidateScopes = false;
options.ValidateOnBuild = false;
});
}Truy cập Dependency Injection (DI)
csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddScoped<SampleService>();
var app = builder.Build();
app.MapControllers();
using (var scope = app.Services.CreateScope())
{
var sampleService = scope.ServiceProvider.GetRequiredService<SampleService>();
sampleService.DoSomething();
}
app.Run();Keyed Services (dịch vụ có khóa)
csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddKeyedSingleton<ICache, BigCache>("big");
builder.Services.AddKeyedSingleton<ICache, SmallCache>("small");
var app = builder.Build();
app.MapGet("/big", ([FromKeyedServices("big")] ICache bigCache) => bigCache.Get("date"));
app.MapGet("/small", ([FromKeyedServices("small")] ICache smallCache) => smallCache.Get("date"));
app.Run();Truy cập Environment và Configuration
Đọc Environment
csharp
var app = WebApplication.Create(args);
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/oops");
}
app.MapGet("/", () => "Hello World");
app.MapGet("/oops", () => "Oops! An error happened.");
app.Run();Configuration
csharp
var app = WebApplication.Create(args);
var message = app.Configuration["HelloKey"] ?? "Config failed!";
app.MapGet("/", () => message);
app.Run();Logging (ghi log)
csharp
var app = WebApplication.Create(args);
app.Logger.LogInformation("The app started");
app.MapGet("/", () => "Hello World");
app.Run();Developer Exception Page (trang ngoại lệ cho nhà phát triển)
csharp
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () =>
{
throw new InvalidOperationException("Oops, the '/' route has thrown an exception.");
});
app.Run();Trong chế độ development, trang này hiển thị thông tin lỗi thân thiện thay vì lỗi chung chung.