Luke Vo
Luke Vo

Reputation: 20668

Store an object that is accessible within a Server Request?

I am developing an ASP.NET MVC project, and I would like to lazy-load a database DataContext object that is used across Classes within a server Request (that is, it only live through a Request, and for each Request, I have an unique object).

Currently I can obtain the Request using HttpContext.Current or HttpContext.Current.Request, but the Request only stores string values.

Is there something like the Session object, but for the Request only? Something like the ViewBag or ViewData, but accessible from the HttpContext object?

EDIT: Here is what I am trying to achieve: I have a AccountBusiness class, that might be instantiated multiple times in a request. It has LoggedInUser property (note: this is not the AspNetUser object of ASP.NET Identity) that is lazy-loaded. Normally I would do something like this:

    private UserProfile loggedInProfile;
    public UserProfile LoggedInProfile
    {
        get
        {
            if (this.loggedInProfile == null)
            {
                var userId = HttpContext.Current.User.Identity.GetUserId();
                this.loggedInProfile = this.Context.UserProfiles.FirstOrDefault(q => q.ID == userId);
            }

            return this.loggedInProfile;
        }
    }

However, as I stated before, this property might be instantiated multiple times in a request, it will access the database multiple time for just a same UserProfile object. This is just an example, I have much more objects similar to this, and would like to change so that it only access the database once, then save it for using for the current Request, like this:

    public UserProfile LoggedInProfile
    {
        get
        {
            if (this.loggedInProfile == null)
            {
                var dataTokens = HttpContext.Current.Request.RequestContext.RouteData.DataTokens;
                object o;
                if (!dataTokens.TryGetValue("CurrentUserProfile", out o))
                {
                    var userId = HttpContext.Current.User.Identity.GetUserId();
                    dataTokens["CurrentUserProfile"] = o = this.Context.UserProfiles
                        .FirstOrDefault(q => q.ID == userId);
                }
                this.loggedInProfile = o as UserProfile;
            }

            return this.loggedInProfile;
        }
    }

Is there any bad thing in my solution?

P.s: I just discover RouteValues and DataTokens may contain a key-object pair, but I wonder if it is okay to use it?

Upvotes: 1

Views: 1695

Answers (4)

Niels V
Niels V

Reputation: 995

Use the HttpContext.Items collection to share objects during the lifetime of the request.

Upvotes: 5

Maess
Maess

Reputation: 4146

Use dependency injection and Inversion of Control. Most IOC tools, like Castle Windsor, will allow you to have your context persisted for the life of a request.

If you are not familiar with DI, here is a simple example:

Mycontroller
{
   IMyContext _contex;
   public Mycontroller(IMyContext context)
   {
      _context = context;
   }
}

Upvotes: 0

Chris Pratt
Chris Pratt

Reputation: 239300

I would like to lazy-load a database DataContext object that is used across the Request only.

That bit troubles me. Perhaps it's just worded awkwardly, but it sounds as if you're somehow trying to persist your context across requests, which would be a very bad idea.

If, however, you're just talking about persisting the results of a query or similar, I'd recommend using the in-memory caching provided by ASP.NET. Using session or cookies involves relying on the client to store information, and that's both unnecessary and inappropriate for this kind of thing.

Upvotes: 1

Varun Vasishtha
Varun Vasishtha

Reputation: 461

You can use Cache or Cookie both are accessible with HttpContext and after using you can make empty them.

Upvotes: 0

Related Questions