Click here to Skip to main content
15,891,607 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I'm developing an MVC3 application.

Being that during a typical request I must access the CurrentUser data multiple times, I thought it would be handy to define a Static Class as below

C#
public static class CurrentSession
{
  //get CurrentUser data from current context. If null, load data and set it
  public static User CurrentUser{
    var curUser = HttpContext.Current.Items["CurrentUser"];
    if (HttpContext.Current.Request.IsAuthenticated && curUser==null)
     {
       dbContext db = new dbContext();
       curUser = dbContext.find(HttpContext.Current.User.Identity.Name);
       HttpContext.Current.Irems["CurrentUser"] = curUser;       
     }

     return (User)curUser;
}
}


The above should check if the user is authenticated, get the UserData and put it on the current context items. If I'll need to access userdata again, it will already be in my context items, with no need to pull from db again.

Is this a bad idea? From what I understand (in theory) this way I can have an object shared across all my different functions, limited to current context (so on a per user request basis), loaded only once and only if needed.

It works (or at least it seems to work), I would like to know if this is a "good" solution or not.

But, this way I have a problem in an hypotetic method like this:

C#
public ActionResult create(model newObject){
  dbContext db = new dbContext();
  newObject.childcollection.add(CurrentSession.User.childEntity);
  db.add(newObject);// exception
  db.SaveChanges();
}


the above code throws an exception "An entity object cannot be referenced by multiple instances of IEntityChangeTracker", because the User.childEntity "references" a different dbContext, the one defined inside the get{} merthod of the static property..

in fact, I tried the following to be shure, and the exception is exactly the same:

C#
dbContext db = new dbContext();
dbContext db2 = new dbContext();
newObject.childcollection.add(db2.childEntity.find(id));
db.model.add(newObject);// exception
db.SaveChanges();


To "solve" this, I can do it this way:

C#
public ActionResult create(model newObject){
  dbContext db = new dbContext();
  newObject.childcollection.add(db.childEntity.find(CurrentSession.User.childEntity.id));
  db.add(newObject);// exception
  db.SaveChanges();
}



But I'll somewhat reduce the advantage of pulling out data from db only once.. IF I understand correctly how things works.

In any case, it is also to be considered how effectively faster is to reference an object from context.current.items or pull it from db.

Any suggestions to have a "global" object to be referenced different functions?
Or is it just better to get everytime the User object inside any function that needs it? This way, I suppose that it is (remotely) possible that the User actually changes during the course of the request..

Sorry for the quite long question an thank you in advance,

Alberto
Posted
Updated 15-Dec-11 5:03am
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900