WebApi
WebApi copied to clipboard
IHttpContextAccessor.HttpContext returns null when executing within an odata batch call.
IHttpContextAccessor.HttpContext
returns null when executing within an odata batch call.
Assemblies affected
Microsoft.AspNetCore.OData 7.5.0
Reproduce steps
Simply setup a simple odata batch pipeline
var defaultBatchHandler = new DefaultODataBatchHandler();
defaultBatchHandler.MessageQuotas.MaxNestingDepth = 2;
defaultBatchHandler.MessageQuotas.MaxOperationsPerChangeset = 10;
and create an action that uses the http context accessor:
[ODataRoutePrefix("me")]
public class MeController : ODataController
{
private readonly IHttpContextAccessor httpContextAccessor;
public MeController(IHttpContextAccessor httpContextAccessor)
{
this.httpContextAccessor = httpContextAccessor;
}
[EnableQuery]
[HttpGet]
public User Get()
{
var user = this.httpContextAccessor.HttpContext.User;
// this.HttpContext is fine
return new User { Name = user.Identity.Name };
}
}
the following request
POST /$batch
Content-Type: application/json
{
"requests": [
{
"id": "1",
"method": "GET",
"url": "/me"
}
]
}
Produces the error
Expected result
In the example above HttpContextAccessor.HttpContext should be equal to this.HttpContext - the http context of the controller/action.
Actual result
HttpContextAccessor.HttpContext is null.
Additional detail
I realize from the simple example above I can simply use this.HttpContext but I need to access the httpcontext in a more deeper part of my code.
The same issue is reproduced on 7.4.1
do we need to add the new httpContext for the sub request at https://github.com/OData/WebApi/blob/master/src/Microsoft.AspNetCore.OData/Batch/ODataBatchReaderExtensions.cs#L251 into the IHttpContextAccessor?
do we need to add the new httpContext for the sub request at https://github.com/OData/WebApi/blob/master/src/Microsoft.AspNetCore.OData/Batch/ODataBatchReaderExtensions.cs#L251 into the IHttpContextAccessor?
Under which circumstances is IHttpContextFactory not available? Even if IHttpContextFactory was available (which sets the context on default implementation of IHttpContextAccessor as far as I remember), the same problem would occur due to AsyncLocal usage in the context accessor... (we are already deep in an async method chain)
?
We have faced the same issue and working with a workaround like this:
[ODataRoutePrefix("me")]
public class MeController : ODataController
{
private readonly ClaimsPrincipal user;
public MeController(IHttpContextAccessor httpContextAccessor, IActionContextAccessor actionContextAccessor)
{
var httpContext = httpContextAccessor.HttpContext;
if (httpContext == null)
{
// this occurs since .NET 3.1, when a batch request is running
httpContext = actionContextAccessor.ActionContext?.HttpContext;
}
this.user = httpContext?.User;
}
[EnableQuery]
[HttpGet]
public User Get()
{
return new User { Name = user.Identity.Name };
}
}
See also this thread on stackoverflow.
The ActionContextAccessor needn't to be put to DI manually. Maybe this works for you too.
@ThomasWendrock Your tip is quite useful to provide context for changesets, but does not cover every case, f.e. batch post-processing. I've investigated deep down and found out the reason: https://github.com/dotnet/aspnetcore/blob/master/src/Hosting/Hosting/src/Http/DefaultHttpContextFactory.cs#L73 We should not ever use factory for sub-requests.
Hi, any news on that subject ? :) We faced that issue too and used a similar workaround like Thomas mentionned. Still, it would be awesome to have this fix :)
I've made a fix long ago, but it still has not been merged or no comments on how to rework it.
Hey, when this fix will be released? The problem applies to our project as well. As far as I can see, the fix has been waiting for a year to be merged.
Is this still not in?
Problem stands still.
A (simple) Workaround i found here https://stackoverflow.com/questions/71338662/ihttpcontextaccessor-httpcontext-is-null-after-execution-falls-out-of-the-useoda
@xuzhg Any updates on this issue?