Skip to content

IApiFilter丢失AsyncLocal值 #261

Open
@pengweiqhca

Description

@pengweiqhca
private sealed class TestFilter : IApiFilter
{
    private static readonly AsyncLocal<bool> V = new();

    public Task OnRequestAsync(ApiRequestContext context)
    {
        V.Value = true;

        return Task.CompletedTask;
    }

    public Task OnResponseAsync(ApiResponseContext context)
    {
        Assert.True(V.Value); // 此处将失败,应该成功

        return Task.CompletedTask;
    }
}

解决办法需要重构ApiRequestExecuter

下面是可能的解决办法(未验证,仅限参考):

private static Func<ApiRequestContext, Task<ApiResponseContext>> BuildFilterPipe(ApiRequestContext context)
{
    Func<ApiRequestContext, Task<ApiResponseContext>> executor = static async request =>
    {
        using var requestAbortedLinker = new CancellationTokenLinker(request.HttpContext.CancellationTokens);

        return await ApiRequestSender.SendAsync(request, requestAbortedLinker.Token).ConfigureAwait(false);
    };

    executor = context.ActionDescriptor.FilterAttributes.Reverse()
        .Aggregate(executor, (current, filter) => Build(filter, current));

    executor = context.HttpContext.HttpApiOptions.GlobalFilters.Reverse()
        .Aggregate(executor, (current, filter) => Build(filter, current));

    static Func<ApiRequestContext, Task<ApiResponseContext>> Build(IApiFilter filter,
        Func<ApiRequestContext, Task<ApiResponseContext>> next)
    {
        return async context =>
        {
            await filter.OnRequestAsync(context).ConfigureAwait(false);

            var response = await next(context);

            await filter.OnResponseAsync(response).ConfigureAwait(false);

            return response;
        };
    }

    return executor;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions