dotnetcore / dotnetcore/WebApiClient

IApiFilter丢失AsyncLocal值

Open
#261 5 comments 0 reactions 0 assignees View on GitHub
new idea
Dominant language
C#
Stars
2.1k
Forks
445
PR merge metrics
No merged PRs in 30d

Description

``` C#
private sealed class TestFilter : IApiFilter
{
private static readonly AsyncLocal 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](https://github.com/dotnetcore/WebApiClient/blob/05c68f3d1bef8111f914634baaec36f4fb9dce5a/WebApiClientCore/Implementations/ApiRequestExecuter.cs#L19)

下面是可能的解决办法(未验证,仅限参考):
```
private static Func> BuildFilterPipe(ApiRequestContext context)
{
Func> 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> Build(IApiFilter filter,
Func> 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;
}
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.