Nguon: Microsoft Learn · .NET 8.0

WebApplication và WebApplicationBuilder trong ứng dụng Minimal API

Nguồn: WebApplication and WebApplicationBuilder in Minimal API apps

WebApplication

Đoạn code sau được tạo bởi template ASP.NET Core:

csharp
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

Đoạn code trên có thể được tạo qua lệnh dotnet new web trên dòng lệnh hoặc chọn template Empty Web trong Visual Studio.

Đoạn code sau tạo một WebApplication (app) mà không cần tạo tường minh WebApplicationBuilder:

csharp
var app = WebApplication.Create(args);

app.MapGet("/", () => "Hello World!");

app.Run();

WebApplication.Create khởi tạo một instance mới của lớp WebApplication với các cài đặt mặc định đã được cấu hình sẵn.

Làm việc với Ports (cổng)

Khi tạo ứng dụng web bằng Visual Studio hoặc dotnet new, file Properties/launchSettings.json được tạo ra với các cổng mà ứng dụng lắng nghe. Khi chạy ứng dụng từ Visual Studio với các ví dụ thiết lập cổng bên dưới, Visual Studio sẽ trả về lỗi Unable to connect to web server 'AppName'. Hãy chạy các ví dụ thay đổi cổng từ dòng lệnh.

Các phần sau thiết lập cổng mà ứng dụng lắng nghe.

csharp
var app = WebApplication.Create(args);

app.MapGet("/", () => "Hello World!");

app.Run("http://localhost:3000");

Trong đoạn code trên, ứng dụng lắng nghe trên cổng 3000.

Nhiều cổng

Trong đoạn code sau, ứng dụng lắng nghe trên cổng 30004000.

csharp
var app = WebApplication.Create(args);

app.Urls.Add("http://localhost:3000");
app.Urls.Add("http://localhost:4000");

app.MapGet("/", () => "Hello World");

app.Run();

Thiết lập cổng từ dòng lệnh

Lệnh sau làm ứng dụng lắng nghe trên cổng 7777:

dotnetcli
dotnet run --urls="https://localhost:7777"

Đọc cổng từ môi trường

Đoạn code sau đọc cổng từ môi trường:

csharp
var app = WebApplication.Create(args);

var port = Environment.GetEnvironmentVariable("PORT") ?? "3000";

app.MapGet("/", () => "Hello World");

app.Run($"http://localhost:{port}");

Cách được khuyến nghị là dùng biến môi trường ASPNETCORE_URLS.

Thiết lập cổng qua biến môi trường ASPNETCORE\_URLS

code
ASPNETCORE_URLS=http://localhost:3000

Hỗ trợ nhiều URL:

code
ASPNETCORE_URLS=http://localhost:3000;https://localhost:5000

Lắng nghe trên tất cả các giao diện mạng

http://\*:3000

csharp
var app = WebApplication.Create(args);

app.Urls.Add("http://*:3000");

app.MapGet("/", () => "Hello World");

app.Run();

http://+:3000

csharp
var app = WebApplication.Create(args);

app.Urls.Add("http://+:3000");

app.MapGet("/", () => "Hello World");

app.Run();

http://0.0.0.0:3000

csharp
var app = WebApplication.Create(args);

app.Urls.Add("http://0.0.0.0:3000");

app.MapGet("/", () => "Hello World");

app.Run();

Lắng nghe trên tất cả giao diện mạng dùng ASPNETCORE\_URLS

code
ASPNETCORE_URLS=http://*:3000;https://+:5000;http://0.0.0.0:5005

Lắng nghe dùng ASPNETCORE\_HTTPS\_PORTS

code
ASPNETCORE_HTTP_PORTS=3000;5005
ASPNETCORE_HTTPS_PORTS=5000

Chỉ định HTTPS với certificate phát triển

csharp
var app = WebApplication.Create(args);

app.Urls.Add("https://localhost:3000");

app.MapGet("/", () => "Hello World");

app.Run();

Chỉ định HTTPS với certificate tùy chỉnh

Chỉ định certificate tùy chỉnh qua appsettings.json

json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Kestrel": {
    "Certificates": {
      "Default": {
        "Path": "cert.pem",
        "KeyPath": "key.pem"
      }
    }
  }
}

Chỉ định certificate tùy chỉnh qua cấu hình

csharp
var builder = WebApplication.CreateBuilder(args);

// Cấu hình cert và key
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 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 (cấu hình)

Đoạn code sau đọc từ hệ thống configuration:

csharp
var app = WebApplication.Create(args);

var message = app.Configuration["HelloKey"] ?? "Config failed!";

app.MapGet("/", () => message);

app.Run();

Logging (ghi log)

Đoạn code sau ghi một message vào log khi ứng dụng khởi động:

csharp
var app = WebApplication.Create(args);

app.Logger.LogInformation("The app started");

app.MapGet("/", () => "Hello World");

app.Run();

Truy cập DI container (vùng chứa Dependency Injection)

Đoạn code sau cho thấy cách lấy services từ DI container trong quá trình khởi động ứng dụng:

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();

Đoạn code sau cho thấy cách truy cập các keyed services (dịch vụ có khóa) từ DI container dùng attribute [FromKeyedServices]:

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();

public interface ICache
{
    object Get(string key);
}
public class BigCache : ICache
{
    public object Get(string key) => $"Resolving {key} from big cache.";
}

public class SmallCache : ICache
{
    public object Get(string key) => $"Resolving {key} from small cache.";
}

WebApplicationBuilder

Phần này chứa code mẫu dùng WebApplicationBuilder.

Thay đổi Content Root, Application Name và Environment

Đoạn code sau thiết lập content root, application name và environment:

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();

WebApplication.CreateBuilder khởi tạo một instance mới của lớp WebApplicationBuilder với các cài đặt mặc định đã được cấu hình sẵn.

Thay đổi Content Root, App Name và Environment qua biến môi trường hoặc dòng lệnh

Tính năngBiến môi trườngĐối số dòng lệnh
Application nameASPNETCORE\_APPLICATIONNAME--applicationName
Environment nameASPNETCORE\_ENVIRONMENT--environment
Content rootASPNETCORE\_CONTENTROOT--contentRoot

Thêm Configuration Providers

Ví dụ sau thêm INI configuration provider:

csharp
var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddIniFile("appsettings.ini");

var app = builder.Build();

Đọc Configuration

Theo mặc định WebApplicationBuilder đọc configuration từ nhiều nguồn, bao gồm:

Đoạn code sau đọc HelloKey từ configuration và hiển thị giá trị tại endpoint /. Nếu giá trị configuration là null, "Hello" được gán cho message:

csharp
var builder = WebApplication.CreateBuilder(args);

var message = builder.Configuration["HelloKey"] ?? "Hello";

var app = builder.Build();

app.MapGet("/", () => message);

app.Run();

Đọc 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

csharp
var builder = WebApplication.CreateBuilder(args);

// Cấu hình JSON logging ra console
builder.Logging.AddJsonConsole();

var app = builder.Build();

app.MapGet("/", () => "Hello JSON console!");

app.Run();

Thêm Services

csharp
var builder = WebApplication.CreateBuilder(args);

// Thêm memory cache services
builder.Services.AddMemoryCache();

// Thêm custom scoped service
builder.Services.AddScoped<ITodoRepository, TodoRepository>();
var app = builder.Build();

Tùy chỉnh IHostBuilder

Các extension method trên IHostBuilder có thể được truy cập qua thuộc tính Host:

csharp
var builder = WebApplication.CreateBuilder(args);

// Đợi 30 giây để graceful shutdown
builder.Host.ConfigureHostOptions(o => o.ShutdownTimeout = TimeSpan.FromSeconds(30));

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

Tùy chỉnh IWebHostBuilder

Extension methods trên IWebHostBuilder có thể được truy cập qua thuộc tính WebApplicationBuilder.WebHost.

csharp
var builder = WebApplication.CreateBuilder(args);

// Thay đổi cài đặt HTTP server thành HTTP.sys
builder.WebHost.UseHttpSys();

var app = builder.Build();

app.MapGet("/", () => "Hello HTTP.sys");

app.Run();

Thay đổi Web Root

Theo mặc định, web root là thư mục con wwwroot trong content root. Web root là nơi Static File Middleware (phần mềm trung gian file tĩnh) tìm kiếm file tĩnh. Web root có thể được thay đổi với WebHostOptions, dòng lệnh hoặc phương thức UseWebRoot:

csharp
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    Args = args,
    // Tìm file tĩnh trong thư mục webroot
    WebRootPath = "webroot"
});

var app = builder.Build();

app.Run();

DI Container tùy chỉnh

Ví dụ sau dùng Autofac:

csharp
var builder = WebApplication.CreateBuilder(args);

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());

// Đăng ký services trực tiếp với Autofac ở đây
// Không gọi builder.Populate(), điều đó xảy ra trong AutofacServiceProviderFactory
builder.Host.ConfigureContainer<ContainerBuilder>(builder => builder.RegisterModule(new MyApplicationModule()));

var app = builder.Build();

Thêm Middleware

Bất kỳ ASP.NET Core middleware hiện có nào cũng có thể được cấu hình trên WebApplication:

csharp
var app = WebApplication.Create(args);

// Cài đặt file server để phục vụ file tĩnh
app.UseFileServer();

app.MapGet("/", () => "Hello World!");

app.Run();

Developer Exception Page (trang ngoại lệ cho nhà phát triển)

WebApplication.CreateBuilder khởi tạo một instance mới của lớp WebApplicationBuilder với các cài đặt mặc định đã được cấu hình sẵn. Developer exception page được bật trong các cài đặt mặc định. Khi đoạn code sau chạy trong môi trường development, điều hướng đến / sẽ hiển thị trang thân thiện cho thấy exception.

csharp
var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.MapGet("/", () =>
{
    throw new InvalidOperationException("Oops, the '/' route has thrown an exception.");
});

app.Run();