tags:

views:

204

answers:

2

Hi Guys

I'm doing an ASP.NET MVC application and some of my Action Methods and other Extension Methods need access to User data. The code I'm using to get the user is:

this.currentUser = (CurrentUser)HttpContext.Session["CurrentUser"];

//and in the extension methods it's:

CurrentUser user = (CurrentUser)HttpContext.Current.Session["CurrentUser"];

This same line is scattered among a lot of my Action Methods in a lot of my Controllers. The problem is this makes it difficult to test, and it doesn't appear to be very 'elegant'.

can anyone suggest a good SOLID approach to this solution?

Thanks

Dave

+1  A: 

Yes. Don't use sessions (there are several reasons why not).

Asp.Net has a very good mechanism called Forms Authentication for authenticationg and accessing user data.

I have answered a similar question which might help.

Maxwell Troy Milton King
I read your response to the other question and I also read the REST intro article (very good and informative!), and I would tent to agree with all the points that were made. I hadn't considered maintaining user data as a violation of RESTful principles until now. I can't guarantee that I'll adopt these principles for this particular application (though I will research it as a possibility) but I will definitely work to conform more closely with RESTful principles in the future.
DaveDev
+2  A: 

You shouldn't store user in Session, but if you really need to use it, you could do it like that:

First we define interface:

public interface ISessionWrapper
{
    int SomeInteger { get; set; }
}

Then we make HttpContext implementation:

public class HttpContextSessionWrapper : ISessionWrapper
{
    private T GetFromSession<T>(string key)
    {
        return (T) HttpContext.Current.Session[key];
    }

    private void SetInSession(string key, object value)
    {
        HttpContext.Current.Session[key] = value;
    }

    public int SomeInteger
    {
        get { return GetFromSession<int>("SomeInteger"); }
        set { SetInSession("SomeInteger", value); }
    }
}

Then we define our base controller:

public class BaseController : Controller
{
    public ISessionWrapper SessionWrapper { get; set; }

    public BaseController()
    {
        SessionWrapper = new HttpContextSessionWrapper();
    }
}

Finally:

public ActionResult SomeAction(int myNum)
{           
    SessionWrapper.SomeInteger
}

This will make testing easy, because you can replace ISessionWrapper with mock in controller tests.

LukLed