Skip to content

IApiFilter丢失AsyncLocal值 #261

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;
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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