views:

78

answers:

6

Okay, this is a bit abstract, but here goes:

I'm creating a website and I want to have a field, "foo", that I can access from any page on the site. I figured the best way to do this would be to create a subclass of Page called "bar", add the protected field "foo" to it, and then have all my webpages inheret from "bar". Ta-da. Every page now has foo.

But now I add controls to my pages, and I want them to have access to "foo".

Well, now foo can't be protected, so it's public. Fine. But how do the controls know about "foo"? I can access foo by doing something like this in my control:

Foo foo = ((Bar)Page).foo;

This works, but strikes me as a bit ugly. I'd really like to just be able to use foo. I figure, hey, maybe I can do the same trick with my controls that I did for page. I create a new class, "blargh" that inherits from UserControl, and grab foo in there the ugly way. Then I have my controls inherit from blargh. Yay!

Except it doesn't work. When I start up the project it complains about the line trying to access ((Bar)Page).foo, because Page is null. Why? How could Page be null? When I look at the call stack I get no help.

Is there an easy, well understood way to do this? Am I barking up the wrong tree?

+2  A: 

If you need every user to have their own instance you can store it in the session.

 Session["foo"]=data;

Then on your other pages you can use:

 Control ctl = (Control) Session["foo"];

Keep in mind you will have to cast Session["foo"] to whatever type you want to work with. there is also a similar Application[] space which can be used if you only need one instance for every user of the website.

Ian Jacobs
+2  A: 

Another easy way to get started with this, before you decide which objects will need access and which won't, is to simply make a public static class to hold this and other global objects. Something like:

public static class Globals
{
    public static Foo foo = new Foo();
}
JoshJordan
I've started going this route too. I've heard it is the preferred method. I found a nice summary here: http://dotnetperls.com/Content/Global-Variables-ASPNET.aspx
Dillie-O
This answer is about the clearest answer to my unclear question that I could reasonably hope for, so you get the win.
Beska
+1  A: 

What do you need access to? If its data, why not put the value of foo in the Session? Then it can be accessed from anywhere.

Brian
+1  A: 

Is foo the same value shared globally, or does it vary for each page?

I see two possibilities you might like:

  1. Put it into the Application object of ASP.Net (I don't remember exactly where it hangs in asp.net, but with that name you can find doc on it). This would be for a global value that does not vary.

  2. Make it an extension method on Control. Page ultimately inherits from Control, so it will be available. Like this:

    public static class ControlExtensions { public static Foo foo(this Control self) { return foo; } }

Now UserControls and Pages should be able to get to it.

Charlie Flowers
+1  A: 

One option to look at is to extend the page class using extension methods

Then Page will have Foo available whenever there is an instance of Page. Depending on what Foo is doing you will probably still need to store the data in session.

As for why Page is not available in your control. The Page property is only populated once the control has been added to the page. If your control does not sit directly on the page, then it is when it's anscetor that does sit on the page is added to the page.

Daniel
+1  A: 

You have to determine if this [foo] is going to be the same for all users or if it is specific to a single user. If it is the same for all, a Static class with static variables will solve this for you.

public static class FooClass {
   public FooClass() {
   }
   public static string FooName = "TheFoo";
}

If you are looking at something that is going to be specific per user, I would recommend using the Session to store this. You could put your FooClass into the session as well, its really up to you as to what you're putting there.

FooClass myFoo = Session["CurrentFoo"] as FooClass;
RSolberg