Khởi động ứng dụng trong ASP.NET Core
Nguồn: App startup in ASP.NET Core
Các ứng dụng ASP.NET Core được tạo bằng các web template (mẫu web) chứa code khởi động ứng dụng trong file Program.cs.
Code khởi động ứng dụng sau đây hỗ trợ nhiều loại ứng dụng:
using WebAll.Components;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapGet("/hi", () => "Hello!");
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
app.UseAntiforgery();
app.Run();Mở rộng Startup với Startup Filters (bộ lọc khởi động)
Sử dụng IStartupFilter để:
- Cấu hình middleware (phần mềm trung gian) ở đầu hoặc cuối pipeline middleware của ứng dụng mà không cần lời gọi rõ ràng đến
Use{Middleware}. Sử dụngIStartupFilterđể thêm các middleware mặc định vào đầu pipeline mà không cần đăng ký tường minh middleware mặc định. - Tạo pipeline của các phương thức
Configure. IStartupFilter.Configure có thể đặt middleware chạy trước hoặc sau middleware được thêm bởi các thư viện.
Một triển khai IStartupFilter cung cấp phương thức Configure nhận và trả về một Action<IApplicationBuilder>. IApplicationBuilder định nghĩa một lớp để cấu hình pipeline request của ứng dụng.
Mỗi triển khai IStartupFilter có thể thêm một hoặc nhiều middleware vào request pipeline. Các filter (bộ lọc) được gọi theo thứ tự chúng được thêm vào service container. Filter có thể thêm middleware trước hoặc sau khi truyền điều khiển cho filter tiếp theo.
Ví dụ sau minh họa cách đăng ký middleware với IStartupFilter. Middleware RequestSetOptionsMiddleware đặt giá trị options từ tham số query string (chuỗi truy vấn):
public class RequestSetOptionsMiddleware
{
private readonly RequestDelegate _next;
public RequestSetOptionsMiddleware(RequestDelegate next)
{
_next = next;
}
// Test with https://localhost:5001/Privacy/?option=Hello
public async Task Invoke(HttpContext httpContext)
{
var option = httpContext.Request.Query["option"];
if (!string.IsNullOrWhiteSpace(option))
{
httpContext.Items["option"] = WebUtility.HtmlEncode(option);
}
await _next(httpContext);
}
}RequestSetOptionsMiddleware được cấu hình trong lớp RequestSetOptionsStartupFilter:
public class RequestSetOptionsStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return builder =>
{
builder.UseMiddleware<RequestSetOptionsMiddleware>();
next(builder);
};
}
}Triển khai IStartupFilter được đăng ký trong file Program.cs:
using WebStartup.Middleware;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddTransient<IStartupFilter,
RequestSetOptionsStartupFilter>();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();Khi một tham số query string cho option được cung cấp, middleware xử lý việc gán giá trị trước khi ASP.NET Core middleware render response (phản hồi):
@page
@model PrivacyModel
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p> Append query string ?option=hello</p>
Option String: @HttpContext.Items["option"];Thứ tự thực thi middleware được thiết lập bởi thứ tự đăng ký IStartupFilter:
- Nhiều triển khai
IStartupFiltercó thể tương tác với cùng các đối tượng. Nếu thứ tự quan trọng, hãy sắp xếp thứ tự đăng ký serviceIStartupFilterđể phù hợp với thứ tự mà middleware của chúng nên chạy. - Các thư viện có thể thêm middleware với một hoặc nhiều triển khai
IStartupFilterchạy trước hoặc sau middleware ứng dụng khác được đăng ký vớiIStartupFilter. Để gọi một middlewareIStartupFiltertrước một middleware được thêm bởiIStartupFiltercủa thư viện: - Đặt đăng ký service trước khi thư viện được thêm vào service container.
- Để gọi sau, đặt đăng ký service sau khi thư viện được thêm.
Thêm cấu hình khi khởi động từ assembly bên ngoài
Triển khai IHostingStartup cho phép thêm các tính năng nâng cao vào ứng dụng khi khởi động từ assembly bên ngoài, bên ngoài file Program.cs của ứng dụng.
Lớp Startup (dành cho ASP.NET Core 3.1 và 5.0)
Ứng dụng ASP.NET Core sử dụng lớp Startup, được đặt tên là Startup theo quy ước. Lớp Startup:
- Tùy chọn bao gồm phương thức ConfigureServices để cấu hình services của ứng dụng. Một service là một thành phần có thể tái sử dụng cung cấp chức năng ứng dụng. Services được đăng ký trong
ConfigureServicesvà sử dụng trong ứng dụng thông qua dependency injection (DI) (tiêm phụ thuộc). - Bao gồm phương thức Configure để tạo pipeline xử lý request của ứng dụng.
ConfigureServices và Configure được ASP.NET Core runtime gọi khi ứng dụng khởi động:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
}Lớp Startup được chỉ định khi host của ứng dụng được xây dựng. Lớp Startup thường được chỉ định bằng cách gọi phương thức WebHostBuilderExtensions.UseStartup<TStartup> trên host builder:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}Phương thức ConfigureServices
Phương thức ConfigureServices:
- Tùy chọn (optional).
- Được host gọi trước phương thức
Configuređể cấu hình services của ứng dụng. - Nơi các configuration options được đặt theo quy ước.
Đối với các tính năng cần thiết lập đáng kể, có các phương thức mở rộng Add{Service} trên IServiceCollection. Ví dụ: AddDbContext, AddDefaultIdentity, AddEntityFrameworkStores, và AddRazorPages:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>(
options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddRazorPages();
}Phương thức Configure
Phương thức Configure được sử dụng để chỉ định cách ứng dụng phản hồi các HTTP requests. Pipeline request được cấu hình bằng cách thêm các thành phần middleware vào một instance IApplicationBuilder.
Các ASP.NET Core templates cấu hình pipeline với hỗ trợ cho:
- Developer Exception Page
- Exception handler
- HTTP Strict Transport Security (HSTS)
- HTTPS redirection
- Static files
- ASP.NET Core MVC và Razor Pages
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}Mỗi phương thức mở rộng Use thêm một hoặc nhiều thành phần middleware vào request pipeline. Ví dụ, UseStaticFiles cấu hình middleware để phục vụ static files (các tập tin tĩnh).
Cấu hình services mà không có Startup
Để cấu hình services và request processing pipeline mà không sử dụng lớp Startup, hãy gọi các phương thức tiện ích ConfigureServices và Configure trên host builder:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureServices(services =>
{
services.AddControllersWithViews();
})
.Configure(app =>
{
var loggerFactory = app.ApplicationServices
.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger<Program>();
var env = app.ApplicationServices.GetRequiredService<IWebHostEnvironment>();
var config = app.ApplicationServices.GetRequiredService<IConfiguration>();
logger.LogInformation("Logged in Configure");
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
var configValue = config["MyConfigKey"];
});
});