ASP.NET Core面试精讲系列一

B站影视 港台电影 2025-09-26 09:39 1

摘要:处理请求,将请求传递给下一个中间件,或者中断管道(短路)。中间件可以在下一个中间件执行前后执行操作,如日志、认证、错误处理等。中间件按照在 Program.cs 中添加的顺序执行。

中间件是 HTTP 请求管道中的一个组件,可以:

处理请求,

将请求传递给下一个中间件,

或者中断管道(短路)。

中间件可以在下一个中间件执行前后执行操作,如日志、认证、错误处理等。

中间件按照在 Program.cs 中添加的顺序执行。

2. 如何配置中间件管道(在 Program.cs / Startup.cs 中)?

在 ASP.NET Core 6+(最小主机模型)中,中间件在 Program.cs 中添加:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build;
app.UseMiddleware
app.UseRouting;
app.UseEndpoints(endpoints => { endpoints.MapControllers; });
app.Run;

- 在旧版本(例如 .NET Core 3.1)中,使用 Startup.cs:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseMiddleware
app.UseRouting;

}

3. app.Use、app.UseMiddleware、app.Run 和 app.Map 的区别**

方法

说明

app.Use 添加可以调用 next 的中间件 app.UseMiddleware 添加自定义中间件类 app.Run 终止中间件,不调用 next,结束管道 app.Map 根据 URL 路径分支管道(如 /api)

示例:

app.Use(async (context, next) => {
await next; // 调用下一个中间件
});
app.Run(async context => {
await context.Response.WriteAsync("Hello World"); // 终止管道
});

创建一个类,构造函数接收 RequestDelegate,包含 Invoke 或 InvokeAsync 方法。

public class MyCustomMiddleware
{
private readonly RequestDelegate _next;
public MyCustomMiddleware(RequestDelegate next) => _next = next;
public async Task InvokeAsync(HttpContext context)
{
// 前置逻辑
await _next(context);
// 后置逻辑
}
}

RequestDelegate 是一个委托,表示管道中的下一个中间件。

public delegate Task RequestDelegate(HttpContext context);

中间件按添加顺序执行,顺序会影响行为。

例如: app.UseAuthentication必须在授权之前。

日志、错误处理、安全中间件应放在管道前面。

if (!context.User.Identity.IsAuthenticated)
{
context.Response.StatusCode = 401;
return; // 短路
}
await next; // 仅认证通过时调用
app.UseStaticFiles用于从 wwwroot 提供静态文件。

必须在路由或 endpoints 之前添加,否则静态文件会被控制器逻辑处理。

9. 如何使用中间件处理异常(UseExceptionHandler, UseDeveloperExceptionPage)

UseDeveloperExceptionPage:开发环境显示详细错误。

UseExceptionHandler("/Error"):生产环境自定义错误页面。

也可内联处理:

app.UseExceptionHandler(errorApp => {
errorApp.Run(async context => {
context.Response.StatusCode = 500;
await context.Response.WriteAsync("An error occurred");
});
});
app.UseHttpsRedirection;将 HTTP 请求重定向到 HTTPS。

应在认证或路由之前添加。

HTTPS 端口可在 launchSettings.json 或 appsettings.json 配置。

11. 如何使用自定义文件提供程序或选项(如缓存、目录浏览)提供静态文件?**

app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "MyFiles")),
RequestPath = "/Files",
OnPrepareResponse = ctx => {
ctx.Context.Response.Headers.Append("Cache-Control", "public,max-age=600");
}
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = new PhysicalFileProvider("path"),
RequestPath = "/browse"
});

类型

说明

终止(Terminal) 结束管道,不调用 next,如 app.Run 非终止(Non-Terminal) 调用 next,允许后续中间件执行,如 app.Use app.UseAuthentication;验证用户身份app.UseAuthorization;应用策略/角色

顺序:路由后,endpoints 前

builder.Services.AddCors(options => {
options.AddPolicy("MyPolicy", policy => {
policy.WithOrigins("https://example.com")
.AllowAnyHeader
.AllowAnyMethod;
});
});
使用中间件: app.UseCors("MyPolicy");,应在路由/endpoints 之前public class TimingMiddleware
{
private readonly RequestDelegate _next;
public TimingMiddleware(RequestDelegate next) => _next = next;
public async Task InvokeAsync(HttpContext context)
{
var sw = Stopwatch.StartNew;
await _next(context);
sw.Stop;
Console.WriteLine($"Request took {sw.ElapsedMilliseconds} ms");
}
}

欢迎各位票友补充。下一节我们来中间件。

来源:opendotnet

相关推荐