rksprst
rksprst

Reputation: 6631

How to share an object between controllers and viewpages?

At the moment I am overriding the OnLoad event of an ASP.NET ViewPage. So that an object can be shared with all the viewpages. But I now need to be able to access that object in the controller as well; what is the best way to do so?

Essentially, I want to share an object (that is unique for each user of the web app... so singleton is out) with the viewpages and controllers.

Thanks!

Upvotes: 0

Views: 621

Answers (4)

Mark
Mark

Reputation: 6081

i agree with Will. stick the object in a base controller class which your main controllers derive from.

look here to see what others say >> ViewModel-Best-Practices

Upvotes: 0

apiguy
apiguy

Reputation: 5362

I'm not sure if you are looking to maintain a reference to the object for an entire user's session or if you only want it for a single request. Either way, you can use the Global.asax to get the object into scope for your controllers and views to use:

First, A request scoped object:

Global.asax.cs:

protected void Application_BeginRequest(object sender, EventArgs e)
{
    var myObject = SomeMethodThatGetsMyObject();
    HttpContext.Current.Items.Add("MyObjectKey", myObject);
}

protected void Application_EndRequest(object sender, EventArgs e)
{
    HttpContext.Current.Items.Remove("MyObjectKey");
}

Then in controllers you can access this like so:

public ViewResult ThisAction()
{
    var myObject = HttpContext.Current.Items["MyObjectKey"] as MyObjectType;
    // placing this in view data provides easy access in the view.
    ViewData["MyObject"] = myObject;
    return View();
}

Then in views you can access this from the ViewData, or directly from the HttpContext

<% var myObject = ViewData["MyObject"] as MyObjectType; %>

<!-- If for some reason you don't want it in view data
 you can use the HttpContext directly instead -->

<% var myObject = HttpContext.Current.Items["MyObjectKey"] as MyObjectType; %>

Second, a session scoped object:

This method will keep the object in scope until the user's session ends.

Global.asax.cs

protected void Session_Start(object sender, EventArgs e)
{
    var myObject = SomeMethodThatGetsMyObject();
    Session["MyObjectKey"] = myObject;
}

protected void Session_End(object sender, EventArgs e)
{
    Session.Remove("MyObjectKey");
}

Then in controllers you can access this like so:

public ViewResult ThisAction()
{
    var myObject = Session["MyObjectKey"] as MyObjectType;
    // placing this in view data provides easy access in the view.
    ViewData["MyObject"] = myObject;
    return View();
}

Then in views you can access this from the ViewData, or directly from the HttpContext

<% var myObject = ViewData["MyObject"] as MyObjectType; %>

<!-- If for some reason you don't want it in view data
 you can use the Session directly instead -->

<% var myObject = Session["MyObjectKey"] as MyObjectType; %>

Best Practices

It's worth mentioning that some best practices could be applied to improve on this design a bit. For one, instead of passing and using an entire object in your view, it is usually better just to pass the values you need into the view data keeping the view free of assignment and casting code. (remember that if you are going to cast in your view you are going to have to handle the potential that the casting fails in your view too!)

Also, the desire to have a user scoped object that is always available "just in case" is a bit of an anti-pattern. It might be useful to know what the purpose of this object is so that perhaps an appropriate pattern could be suggested to help solve your problem according to known best practices.

I hope somewhere in this I was able to help a little bit.

Upvotes: 2

Paul Turner
Paul Turner

Reputation: 39625

It sounds like you want to pass some session variables to your views. Perhaps the best way to accomplish this is to create a base view model class which loads these pieces of information from the session object for you. This base object can then be used to construct the tailored view model classes for each view.

Upvotes: 0

user1228
user1228

Reputation:

Put it in a base class of your controllers?

Honestly, your design sounds flawed... some kind of "god object" has found its way into your design. If you ask about a better way to do what you're doing you might get some better answers...

Upvotes: 0

Related Questions