You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET8中ASP.NET Core错误处理:如何获取请求URL等信息

解决ASP.NET Core 8异常处理器中获取原始请求信息的问题

核心逻辑

当启用app.UseExceptionHandler("/Home/Error")时,异常触发后会触发内部重定向,此时当前HttpContext指向的是错误页面的请求,而非原始出错请求。原始请求的所有信息需要从异常处理特性对象中提取,不能直接使用当前上下文。


具体解决方案

1. 获取原始请求URL

通过IExceptionHandlerPathFeature获取原始请求上下文,拼接完整URL:

public class ErrorHandler : IExceptionHandler
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    private readonly ILogger<ErrorHandler> _logger;

    public ErrorHandler(IHttpContextAccessor httpContextAccessor, ILogger<ErrorHandler> logger)
    {
        _httpContextAccessor = httpContextAccessor;
        _logger = logger;
    }

    public async ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)
    {
        // 提取原始请求特性
        var exceptionPathFeature = httpContext.Features.Get<IExceptionHandlerPathFeature>();
        if (exceptionPathFeature != null)
        {
            var originalReq = exceptionPathFeature.HttpContext.Request;
            // 拼接完整原始URL
            var originalFullUrl = $"{originalReq.Scheme}://{originalReq.Host}{originalReq.Path}{originalReq.QueryString}";
            _logger.LogError("原始请求URL: {Url}", originalFullUrl);
        }

        // 后续异常处理逻辑
        return true;
    }
}

2. 读取原始表单数据

原始请求的表单流默认只能读取一次,直接读取会导致崩溃,需要提前缓存请求流:

第一步:添加请求体缓存中间件

public class RequestBodyCacheMiddleware
{
    private readonly RequestDelegate _next;

    public RequestBodyCacheMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        // 启用请求流缓存,允许多次读取
        context.Request.EnableBuffering();
        await _next(context);
    }
}

第二步:在Program.cs中注册中间件(必须在UseExceptionHandler之前)

var builder = WebApplication.CreateBuilder(args);

// 注册必要服务
builder.Services.AddHttpContextAccessor();
builder.Services.AddExceptionHandler<ErrorHandler>();

var app = builder.Build();

// 注册缓存中间件,确保在异常处理器之前执行
app.UseMiddleware<RequestBodyCacheMiddleware>();

app.UseExceptionHandler("/Home/Error");
// 其他中间件配置...

app.Run();

第三步:在ErrorHandler中读取表单数据

var originalReq = exceptionPathFeature.HttpContext.Request;
if (originalReq.HasFormContentType)
{
    // 重置流位置到起始点
    originalReq.Body.Position = 0;
    var formData = await originalReq.ReadFormAsync(cancellationToken);
    // 遍历记录表单字段
    foreach (var key in formData.Keys)
    {
        _logger.LogError("表单字段: {Key}, 值: {Value}", key, formData[key]);
    }
}

3. 获取原始Referrer请求头

同样通过IExceptionHandlerPathFeature中的原始请求上下文获取:

var originalReq = exceptionPathFeature.HttpContext.Request;
var referrer = originalReq.Headers.Referer.ToString();
if (!string.IsNullOrWhiteSpace(referrer))
{
    _logger.LogError("Referrer: {Referrer}", referrer);
}

注意事项

  • 中间件顺序不可颠倒:RequestBodyCacheMiddleware必须在UseExceptionHandler之前注册,才能确保原始请求流被缓存。
  • 若API接收JSON请求体,同样可以用EnableBuffering()缓存流,之后读取RequestBody获取原始JSON内容。
  • 生产环境需对日志中的敏感表单数据进行脱敏处理,避免信息泄露。

内容的提问来源于stack exchange,提问作者Leo Muller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 15:33:17