Vivek points out some surprising behavior with master pages.
Let's say we want to disable ViewState for all pages by default. All we need is an entry in web.config:
When the ASP.NET runtime generates code for a web form, it will disable ViewState using generated code. The code in the Temporary ASP.NET Files directory for an .aspx will contain a snippet like the following:
At some point, we may run into a page that requires ViewState. Arguably, we could say that something on the page should be re-written to use ControlState (required) instead of ViewState (optional), but it's easy to override the default configuration on a page by page basis in the @ Page directive:
This works - the @ Page directive overrides web.config and EnableViewState=true appears in the generated code….
… but there is a catch.
From what I can tell - some of the same goo responsible for the parsing and code generation of .aspx files also parses and generates the code for .ascx, and .master files. This goo will read the web.config setting and place EnableViewState=false in the code generated for master pages (and user controls, too).
For ViewState to be available to a control, it's parent must have ViewState enabled. Since a master page injects itself as the direct child of the Page object, having ViewState disabled in the master page shuts off ViewState for everything inside the Page.
With ViewState effectively disabled, it appears as if the @ Page directive isn't overriding web.config. It turns out that the @ Page directive does work as we expect. What we don't expect is that the MasterPage would pick up a configuration settings from the <pages> section of web.config and kill ViewState. But should we? The documentation for the <pages> element says:
"Globally defines page-specific configuration settings, such as ASP.NET directives for pages and controls that are within the scope of the configuration file."
Perhaps ASP.NET is working as designed, but I'd say the behavior is not intuitive in this case.