Why you shouldn't expose public properties from your pages

We often have users asking us how they can access some variable that's in their page class from their user or custom controls.
The answer is that your page class can expose public properties, and then any control can cast its Page property to your specific Page-inherited class and gain access to the new properties.
But the second half of the answer is that you should really not do that even though it's possible.
There is a double reason for that.
The first is that it's your page that should orchestrate your controls (by accessing their properties and methods), not your controls orchestrating your page.
And the second, which is very close, is that your controls should not depend on your page implementing special properties or methods or containing specific controls. Otherwise, you're breaking one of the most important qualities of WebControls, that is their reusability. Any control should have the ability to be dropped on any page and just work.
Your user and custom controls should be components, that is, they should be independant, encapsulated and reusable entities. It's your page (or containing controls) only that should orchestrate the controls and glue them together. The glue should stay outside and should never ooze inside.
A consequence of that is that your Page generally has no good reason to expose new public properties, because no one should have to consume them.

3 Comments

  • I'd make one counter argument to this, though I agree with you for the most part. I wouldn't be opposed to a web framework in which controls could access certain properties of the page.



    Bat only through a known interface and if the control degrades gracefully if the Page class didn't support the interface.



    For example (inside the control):



    IFrameworkPage specialPage = Page as IFrameworkPage;

    if(specialPage != null)

    //... Access properties of the page specific to this framework

    else

    //... degrade gracefully

  • One reason to expose properties on the page is if you want to access them after a Server.Transfer, or in Whidbey, after a cross-post. However, I forget whether those have to be public. Also, I suppose, a reason that people do that is to get access to control properties that are children of the page.

  • You understand correctly -- my point was only that I believe that people sometimes use public page properties to expose control values. (Such an example appears in the docs, I see.) I just checked, and it seems you can use FindControl on the page B to get values out of A -- it still (kind of) breaks encapsulation, since it requires the target page to know the ID of the control to get, but at least it doesn't also require the container page (page A) to add a property to expose the control value(s).

Comments have been disabled for this content.