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

ASP.NET Core中UriFormatException被异常处理器捕获的解决咨询

解决ASP.NET Core中爬虫引发的UriFormatException问题

问题背景

已为ASP.NET Core应用添加全局异常处理逻辑,但爬虫访问不存在的端点时,会触发未处理的UriFormatException(错误信息:Invalid URI: The hostname could not be parsed.),这类异常会污染遥测数据,需要修复或优雅屏蔽,同时忽略针对未定义端点的无效流量。

异常详情

记录的异常

Unhandled exception | UriString: https:///favicon.ico | Exception: System.UriFormatException: Invalid URI: The hostname could not be parsed.

堆栈跟踪

at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind, UriCreationOptions& creationOptions)
   at System.Uri..ctor(String uriString)
   at Microsoft.AspNet.OData.Routing.ODataPathRouteConstraint.Match(HttpContext httpContext, IRouter route, String routeKey, RouteValueDictionary values, RouteDirection routeDirection)
   at Microsoft.AspNetCore.Routing.RouteConstraintMatcher.Match(IDictionary`2 constraints, RouteValueDictionary routeValues, HttpContext httpContext, IRouter route, RouteDirection routeDirection, ILogger logger)
   at Microsoft.AspNetCore.Routing.RouteBase.RouteAsync(RouteContext context)
   at Microsoft.AspNetCore.Routing.RouteCollection.RouteAsync(RouteContext context)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)

现有异常处理器代码

app.UseExceptionHandler(exceptionHandlerApp =>
{
    exceptionHandlerApp.Run(async context =>
    {
        context.Response.StatusCode = StatusCodes.Status500InternalServerError;
        IExceptionHandlerPathFeature exceptionHandlerPathFeature = 
        context.Features.Get<IExceptionHandlerPathFeature>();

        string uriString = null;
        uriString = context.Request.GetEncodedUrl();
        
        Logger.EmitLog(
            "Unhandled exception",
            "UriString",
            uriString,
            "Exception",
            exceptionHandlerPathFeature?.Error);
    });
});

解决方案

1. 前置拦截无效请求

在路由中间件(包括OData路由)之前添加自定义中间件,提前拦截Host为空的无效请求,避免进入后续路由逻辑:

// 放在app.UseRouting()之前
app.Use(async (context, next) =>
{
    // 检查请求Host是否合法(比如爬虫构造的https:///favicon.ico这类无Host的URI)
    if (string.IsNullOrEmpty(context.Request.Host.Host))
    {
        context.Response.StatusCode = StatusCodes.Status400BadRequest;
        await context.Response.WriteAsync("Invalid request URI");
        return;
    }
    await next();
});

2. 在异常处理器中针对性忽略该异常

修改现有异常处理逻辑,识别并跳过来自OData路由约束的UriFormatException,避免记录到遥测数据:

app.UseExceptionHandler(exceptionHandlerApp =>
{
    exceptionHandlerApp.Run(async context =>
    {
        var exceptionFeature = context.Features.Get<IExceptionHandlerPathFeature>();
        var exception = exceptionFeature?.Error;

        // 过滤掉OData路由引发的UriFormatException
        if (exception is UriFormatException && 
            exception.StackTrace?.Contains("Microsoft.AspNet.OData.Routing.ODataPathRouteConstraint") == true)
        {
            context.Response.StatusCode = StatusCodes.Status400BadRequest;
            await context.Response.WriteAsync("Invalid request URI");
            return;
        }

        // 处理其他真正的未处理异常
        context.Response.StatusCode = StatusCodes.Status500InternalServerError;
        string uriString = context.Request.GetEncodedUrl();
        
        Logger.EmitLog(
            "Unhandled exception",
            "UriString",
            uriString,
            "Exception",
            exception);
    });
});

3. 配置全局404处理

为不存在的端点配置404响应,避免无效请求触发500异常:

// 放在路由中间件之后
app.UseStatusCodePages(async context =>
{
    var response = context.HttpContext.Response;
    if (response.StatusCode == StatusCodes.Status404NotFound)
    {
        await response.WriteAsync("Requested endpoint not found");
    }
});

4. 优化OData路由配置

如果应用使用OData,可以调整路由约束,避免对无效URI进行解析:

  • 确保OData路由仅针对合法的API前缀(比如/odata)
  • 在OData路由注册前添加路径检查,过滤非OData路径的请求

组合建议

优先使用前置拦截无效请求+全局404处理的组合,从源头减少无效请求进入后续逻辑;再用异常处理器作为兜底,确保漏网的UriFormatException不会污染遥测数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 21:15:37