WebApi icon indicating copy to clipboard operation
WebApi copied to clipboard

IHttpContextAccessor.HttpContext returns null when executing within an odata batch call.

Open UmairB opened this issue 4 years ago • 12 comments

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.

UmairB avatar Sep 20 '20 16:09 UmairB

The same issue is reproduced on 7.4.1

newclaus avatar Sep 22 '20 08:09 newclaus

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?

xuzhg avatar Sep 22 '20 16:09 xuzhg

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)

?

UmairB avatar Sep 22 '20 16:09 UmairB

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 avatar Sep 29 '20 07:09 ThomasWendrock

@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.

NicholasNoise avatar Dec 18 '20 08:12 NicholasNoise

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 :)

GuillaumeBONHOMMEAU avatar Apr 27 '21 11:04 GuillaumeBONHOMMEAU

I've made a fix long ago, but it still has not been merged or no comments on how to rework it.

NicholasNoise avatar Apr 27 '21 13:04 NicholasNoise

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.

zjomzjom avatar Sep 02 '21 11:09 zjomzjom

Is this still not in?

HoecusPocus avatar Aug 23 '22 09:08 HoecusPocus

Problem stands still.

NicholasNoise avatar Aug 23 '22 09:08 NicholasNoise

A (simple) Workaround i found here https://stackoverflow.com/questions/71338662/ihttpcontextaccessor-httpcontext-is-null-after-execution-falls-out-of-the-useoda

GitHub-TC avatar Apr 19 '23 13:04 GitHub-TC

@xuzhg Any updates on this issue?

rahul7720 avatar Apr 01 '24 14:04 rahul7720