Accessing HttpContext.Items from ViewComponent returns NULL

4k views Asked by At

We're following this official ASP.NET document: Managing Application State. In our one we controller we're setting a value for HttpContext.Items[...] and are trying to access that value from a ViewComponent that is called from corresponding View. But we are getting HttpContext.Items[...] as null inside ViewComponent.

Controller:

HttpContext.Items["TestVal"]= "some value";

View:

@await Component.InvokeAsync("myVC")

ViewComponent:

public class myVCViewComponent : ViewComponent
{
    public async Task<IViewComponentResult> InvokeAsync()
    {
        String myVal= Http.Items["TestVal"].ToString(); //issue: Http.Items["TestVal"] is null at this line
        return View(items);
    }
}

UPDATE:

In Controller section above, changed Http.Items to HttpContext.Items in the line at: HttpContext.Items["TestVal"]= "some value";

2

There are 2 answers

5
Lukasz Mk On BEST ANSWER

Final update:

I've tested simple case like as in your example, and this works well (on MVC Core v1.1.0).

So, it's hard to say why it's not working in your particular case.

However following our discussion in comments, you've found a source of the problem:

I realised the issue is not related to ViewComponent; it's rather related to scope of HttpContext


Orginal answer:

In the documentation you could read:

Its contents are discarded after each request. It is best used as a means of communicating between components or middleware that operate at different points in time during a request

and in section Working with HttpContext.Items:

This collection is available from the start of an HttpRequest and is discarded at the end of each request.

and in View Components documentation:

Are overloaded on the signature rather than any details of the current HTTP request

0
Dawid Rutkowski On

Getting HttpContext.Current isn't possible in ASP.NET Core. Accessing the current HTTP context from a separate class library is the type of messy architecture that ASP.NET Core tries to avoid.

But it's possible to get the context using IHttpContextAccessor from the ASP.NET Core dependency injection system like that:

public class SomeClass
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public SomeClass(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }
}

When the HttpContextAccessor will be injected then you can do something like that: var context = _httpContextAccessor.HttpContext;.