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

ASP.NET Core集成测试中如何配置IHttpActivityFeature?

解决ASP.NET Core测试服务器中IHttpActivityFeature空引用问题

我正在编写一个使用IHttpActivityFeature的ASP.NET Core 8中间件,在集成测试中用WebHostBuilder创建独立测试服务器,但WebHostBuilder默认未配置IHttpActivityFeature,从HttpContext获取该特性时会抛出空引用异常,找不到启用或添加它的方法。

中间件代码

public class TraceIdMiddleware
{
    private const string TraceIdHeader = "X-Trace-Id";
    private readonly RequestDelegate _next;

    public TraceIdMiddleware(RequestDelegate next)
    {
        _next = next;
    }
        
    public Task Invoke(HttpContext context)
    {
        context.Response.OnStarting(() => {

            var activityFeature = context.Features.Get<IHttpActivityFeature>();
            var traceId = activityFeature.Activity.TraceId.ToString();
            context.Response.Headers.TryAdd(TraceIdHeader, traceId);
            return Task.CompletedTask;
        });
            
        return _next(context);
    }
}

测试代码

public class WhenMakingAnHttpRequest
{
    [Fact]
    public async Task ItShouldAddTheTraceIdHeader()
    {
        var builder = new WebHostBuilder()
            .Configure(applicationBuilder => {
                applicationBuilder
                    .UseTraceId()
                    .Map("/trace-id", app => {
                        app.Run(async context => {
                            await context.Response.WriteAsync("Testing TraceId Middleware");
                        });
                    });
            });

        using var server = new TestServer(builder);
        using var client = server.CreateClient();

        var response = await client.GetAsync("/trace-id");
        response.Headers
            .Should().ContainKey("X-Trace-Id").WhoseValue
            .Should().NotBeNullOrEmpty();
    }
}

解决方案

IHttpActivityFeature由ASP.NET Core的诊断系统提供,默认极简配置的WebHostBuilder未包含相关服务和中间件,需要手动添加:

1. 配置测试服务器的服务与中间件

修改测试代码中的WebHostBuilder,添加诊断服务和路由中间件(路由中间件会触发Activity创建,自动注入IHttpActivityFeature):

public class WhenMakingAnHttpRequest
{
    [Fact]
    public async Task ItShouldAddTheTraceIdHeader()
    {
        var builder = new WebHostBuilder()
            .ConfigureServices(services =>
            {
                // 注册诊断相关服务
                services.AddDiagnostics();
                services.AddHttpContextAccessor();
            })
            .Configure(applicationBuilder => {
                applicationBuilder
                    // 添加路由中间件,触发Activity创建
                    .UseRouting()
                    .UseTraceId()
                    .Map("/trace-id", app => {
                        app.Run(async context => {
                            await context.Response.WriteAsync("Testing TraceId Middleware");
                        });
                    })
                    // 启用端点路由完成配置
                    .UseEndpoints(endpoints => {});
            });

        using var server = new TestServer(builder);
        using var client = server.CreateClient();

        var response = await client.GetAsync("/trace-id");
        response.Headers
            .Should().ContainKey("X-Trace-Id").WhoseValue
            .Should().NotBeNullOrEmpty();
    }
}

2. 优化中间件健壮性(可选但推荐)

为避免生产环境中因缺失IHttpActivityFeature导致崩溃,在中间件中添加空值判断,并提供默认TraceId生成逻辑:

public class TraceIdMiddleware
{
    private const string TraceIdHeader = "X-Trace-Id";
    private readonly RequestDelegate _next;

    public TraceIdMiddleware(RequestDelegate next)
    {
        _next = next;
    }
        
    public Task Invoke(HttpContext context)
    {
        context.Response.OnStarting(() => {
            var activityFeature = context.Features.Get<IHttpActivityFeature>();
            string traceId;

            if (activityFeature?.Activity != null)
            {
                traceId = activityFeature.Activity.TraceId.ToString();
            }
            else
            {
                // 生成默认TraceId
                traceId = Guid.NewGuid().ToString("N");
            }

            context.Response.Headers.TryAdd(TraceIdHeader, traceId);
            return Task.CompletedTask;
        });
            
        return _next(context);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 19:53:12