Piotrek
Piotrek

Reputation: 11221

How to use sessions outside Controller in ASP.net 5?

Here is what I have now:

public bool TokenCorrect()
    {
        var token = HttpContext.Session.GetInt32("Token");

        return false;
    }

Error:

an object reference is required for the nonstatic field method or property

It works in Controllers, but I want to use it in other class.

Upvotes: 1

Views: 3360

Answers (3)

David
David

Reputation: 218877

The HttpContext class has a static Current property which refers to the current context (if there is one, see below). So something like this:

HttpContext.Current.Session.GetInt32("Token")

However: Ideally you shouldn't rely on this outside of your UI objects. (You shouldn't even rely on it in your controllers, but that can be another story entirely depending on your needs.) Unless the class you're building is, itself, an interface-driven wrapper for the session to be used in controllers to make them more testable... other classes shouldn't rely on web contexts.


Update: It looks like this has changed a bit in MVC 6. Take a look at this link. Essentially there is now an HttpContext object available to controllers in the Context property. So within a controller you can use something like:

Context.Session.GetInt32("Token")

Testability is of course still a concern, though it's gotten a lot better.

For non-controller classes, you can inject a context object as an IHttpContextAccessor. Injecting it is a dependency injector concern, of course. I'm not entirely familiar with the changes in MVC 6 for that, but in general injecting it as a dependency is definitely the way to go. (In fact, if it's injectable into the controller as a dependency, then you don't need to create a wrapper class anymore because the framework is essentially already doing that for you.)

Upvotes: 1

Joe Audette
Joe Audette

Reputation: 36716

In ASP.NET 5 to get the HttpContext, you would take a constructor dependency on IHttpContextAccessor and have it injected into your component. Then you need to make sure session is available before using it. It would be important that your component is scoped per request if using an example like below

using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Features;

public class Foo
{

    public Foo(IHttpContextAccessor contextAccessor)
    {
        _context = contextAccessor.HttpContext;
    }

    private readonly HttpContext _context;

    public bool TokenCorrect()
    {
        ISessionFeature sessionFeature = _context.Features.Get<ISessionFeature>();
        if(sessionFeature != null)
        {
            int? token = sessionFeature.Session.GetInt32("Token");
            if(token.HasValue)
            {
                // do whatever check you are doing
            }
        }


        return false;
    }

}

Upvotes: 7

Darin Dimitrov
Darin Dimitrov

Reputation: 1038930

Completely not recommended to be doing it but you could use the HttpContext.Current static property to get hold of the current HTTP context:

var token = HttpContext.Current.Session.GetInt32("Token");

Bear in mind though that this leads to very difficult to unit test code in isolation and is very bad practice to be trying to depend on ASP.NET session in classes that are really not specific to an HTTP context. On the other hand you could perfectly fine have fetched this value from your ASP.NET MVC controller and passed it to this other class as parameter.

Upvotes: 1

Related Questions