April 19, 2012
"Page" vs "PageData" objects in ASP.NET Web Pages
I was playing around with layout pages in ASP.NET Web Pages the other day and realized that there are actually two ways to pass data from the content page to the layout page: the
Page object and the
PageData object. You can do either of these in the content page:
Page.Title = "My Page";And then use either of these in the layout page:
PageData["Title"] = "My Page";
<title>@Page.Title</title>So what's the difference? Here's what I got from my usual sources.
First, they really are the same object, just with differences in accessors. To show this, you could do the following:
Page.Me = "Mike";and then get that value doing this:
<p>@PageData["me"]</p>Notice that the property/value names —
"me" — aren't even case sensitive.
Page is a dynamic object, meaning that the properties aren't fixed. You can make up your own properties for the object, like
Page.MyDogIsADoofus, and assign values to them.
Some folks consider syntax like
Page.Title to be cleaner than using something like
PageData["Title"]. However, this isn't really the same as normal property syntax (e.g.,
Request.Forms), because the dynamic property isn't getting compile-time type checking. And when you're using a dynamic property, some operations that look like they should work don't, like this:
Page.MyCount = "3";
// Fail with compiler error.
PageData["name"] is a normal dictionary of name/value pairs. This makes it easier to do two things: a) set the name of the value to pass at run time, and b) use names that would be illegal as property names, like a name that has a space in it.
A shorthand way to understand the difference is that it's essentially the same difference as between ViewBag and ViewData in MVC. Except that (as near as I can tell) you don't need to cast
PageData as you see with
ViewData in the MVC examples. At least, I haven't had to yet.
If you happen to be running Visual Basic,
Page can have issues because Visual Basic has issues with dynamic objects unless you're running in full trust, which you don't in web apps. In that case, use