Merge branch 'master' of github.com:mono/mono
[mono.git] / mcs / class / System.Web / System.Web.UI / PageParser.cs
1 //      
2 // System.Web.UI.PageParser
3 //
4 // Authors:
5 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //
7 // (C) 2002,2003 Ximian, Inc (http://www.ximian.com)
8 // Copyright (C) 2005-2010 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 using System.Collections;
31 using System.Collections.Specialized;
32 using System.Globalization;
33 using System.Security.Permissions;
34 using System.Text;
35 using System.Web.Compilation;
36 using System.Web.Configuration;
37 using System.Web.Hosting;
38 using System.Web.Util;
39 using System.IO;
40
41 namespace System.Web.UI
42 {
43         // CAS - no InheritanceDemand here as the class is sealed
44         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
45         public sealed class PageParser : TemplateControlParser
46         {
47 #if NET_4_0
48                 static Type defaultPageBaseType;
49                 static Type defaultApplicationBaseType;
50                 static Type defaultPageParserFilterType;
51                 static Type defaultUserControlBaseType;
52                 static bool enableLongStringsAsResources = true;
53 #endif
54                 PagesEnableSessionState enableSessionState = PagesEnableSessionState.True;
55                 bool enableViewStateMac;
56                 bool enableViewStateMacSet;
57                 bool smartNavigation;
58                 bool haveTrace;
59                 bool trace;
60                 bool notBuffer;
61                 TraceMode tracemode = TraceMode.Default;
62                 string contentType;
63                 MainDirectiveAttribute <int> codepage;
64                 MainDirectiveAttribute <string> responseEncoding;
65                 MainDirectiveAttribute <int> lcid;
66                 MainDirectiveAttribute <string> clientTarget;
67                 MainDirectiveAttribute <string> masterPage;
68                 MainDirectiveAttribute <string> title;
69                 MainDirectiveAttribute <string> theme;
70 #if NET_4_0
71                 MainDirectiveAttribute <string> metaDescription;
72                 MainDirectiveAttribute <string> metaKeywords;
73 #endif
74                 string culture;
75                 string uiculture;
76                 string errorPage;
77                 bool validateRequest;
78                 bool async;
79                 int asyncTimeout = -1;
80                 Type masterType;
81                 string masterVirtualPath;
82                 string styleSheetTheme;
83                 bool enable_event_validation;
84                 bool maintainScrollPositionOnPostBack;
85                 int maxPageStateFieldLength = -1;
86                 Type previousPageType;
87                 string previousPageVirtualPath;
88 #if NET_4_0
89                 public static bool EnableLongStringsAsResources {
90                         get { return enableLongStringsAsResources; }
91                         set {
92                                 BuildManager.AssertPreStartMethodsRunning ();
93                                 enableLongStringsAsResources = value;
94                         }
95                 }
96                 
97                 public static Type DefaultPageBaseType {
98                         get { return defaultPageBaseType; }
99                         set {
100                                 BuildManager.AssertPreStartMethodsRunning ();
101                                 if (value != null && !typeof (Page).IsAssignableFrom (value))
102                                         throw new ArgumentException (String.Format ("The value assigned to property '{0}' is invalid.", "DefaultPageBaseType"));
103                                 
104                                 defaultPageBaseType = value;
105                         }
106                 }
107
108                 public static Type DefaultApplicationBaseType {
109                         get { return defaultApplicationBaseType; }
110                         set {
111                                 BuildManager.AssertPreStartMethodsRunning ();
112                                 if (value != null && !typeof (HttpApplication).IsAssignableFrom (value))
113                                         throw new ArgumentException (String.Format ("The value assigned to property '{0}' is invalid.", "DefaultApplicationBaseType"));
114                                 defaultApplicationBaseType = value;
115                         }
116                 }
117
118                 public static Type DefaultPageParserFilterType {
119                         get { return defaultPageParserFilterType; }
120                         set {
121                                 BuildManager.AssertPreStartMethodsRunning ();
122                                 if (value != null && !typeof (PageParserFilter).IsAssignableFrom (value))
123                                         throw new ArgumentException (String.Format ("The value assigned to property '{0}' is invalid.", "DefaultPageParserFilterType"));
124                                 defaultPageParserFilterType = value;
125                         }
126                 }
127
128                 public static Type DefaultUserControlBaseType {
129                         get { return defaultUserControlBaseType; }
130                         set {
131                                 if (value != null && !typeof (UserControl).IsAssignableFrom (value))
132                                         throw new ArgumentException (String.Format ("The value assigned to property '{0}' is invalid.", "DefaultUserControlBaseType"));
133                                 BuildManager.AssertPreStartMethodsRunning ();
134                                 defaultUserControlBaseType = value;
135                         }
136                 }
137 #endif
138                 public PageParser ()
139                 {
140                         LoadConfigDefaults ();
141                 }
142                 
143                 internal PageParser (string virtualPath, string inputFile, HttpContext context)
144                 {
145                         this.VirtualPath = new VirtualPath (virtualPath);
146                         Context = context;
147                         BaseVirtualDir = VirtualPathUtility.GetDirectory (virtualPath, false);
148                         InputFile = inputFile;
149                         SetBaseType (null);
150                         AddApplicationAssembly ();
151                         LoadConfigDefaults ();
152                 }
153
154                 internal PageParser (VirtualPath virtualPath, TextReader reader, HttpContext context)
155                         : this (virtualPath, null, reader, context)
156                 {
157                 }
158                 
159                 internal PageParser (VirtualPath virtualPath, string inputFile, TextReader reader, HttpContext context)
160                 {
161                         this.VirtualPath = virtualPath;
162                         Context = context;
163                         BaseVirtualDir = virtualPath.DirectoryNoNormalize;
164                         Reader = reader;
165                         if (String.IsNullOrEmpty (inputFile))
166                                 InputFile = virtualPath.PhysicalPath;
167                         else
168                                 InputFile = inputFile;
169                         SetBaseType (null);
170                         AddApplicationAssembly ();
171                         LoadConfigDefaults ();
172                 }
173
174                 internal override void LoadConfigDefaults ()
175                 {
176                         base.LoadConfigDefaults ();
177                         PagesSection ps = PagesConfig;
178
179                         notBuffer = !ps.Buffer;
180                         enableSessionState = ps.EnableSessionState;
181                         enableViewStateMac = ps.EnableViewStateMac;
182                         smartNavigation = ps.SmartNavigation;
183                         validateRequest = ps.ValidateRequest;
184
185                         string value = ps.MasterPageFile;
186                         if (value.Length > 0)
187                                 masterPage = new MainDirectiveAttribute <string> (value, true);
188                         
189                         enable_event_validation = ps.EnableEventValidation;
190                         maxPageStateFieldLength = ps.MaxPageStateFieldLength;
191                         value = ps.Theme;
192                         if (value.Length > 0)
193                                 theme = new MainDirectiveAttribute <string> (value, true);
194                         
195                         styleSheetTheme = ps.StyleSheetTheme;
196                         if (styleSheetTheme.Length == 0)
197                                 styleSheetTheme = null;
198                         maintainScrollPositionOnPostBack = ps.MaintainScrollPositionOnPostBack;
199                 }
200                 
201                 public static IHttpHandler GetCompiledPageInstance (string virtualPath, string inputFile, HttpContext context)
202                 {
203                         bool isFake = false;
204
205                         if (!String.IsNullOrEmpty (inputFile))
206                                 isFake = !inputFile.StartsWith (HttpRuntime.AppDomainAppPath);
207                         
208                         return BuildManager.CreateInstanceFromVirtualPath (new VirtualPath (virtualPath, inputFile, isFake), typeof (IHttpHandler)) as IHttpHandler;
209                 }
210
211                 internal override void ProcessMainAttributes (IDictionary atts)
212                 {
213                         // note: the 'enableSessionState' configuration property is
214                         // processed in a case-sensitive manner while the page-level
215                         // attribute is processed case-insensitive
216                         string enabless = GetString (atts, "EnableSessionState", null);
217                         if (enabless != null) {
218                                 if (String.Compare (enabless, "readonly", true, Helpers.InvariantCulture) == 0)
219                                         enableSessionState = PagesEnableSessionState.ReadOnly;
220                                 else if (String.Compare (enabless, "true", true, Helpers.InvariantCulture) == 0)
221                                         enableSessionState = PagesEnableSessionState.True;
222                                 else if (String.Compare (enabless, "false", true, Helpers.InvariantCulture) == 0)
223                                         enableSessionState = PagesEnableSessionState.False;
224                                 else
225                                         ThrowParseException ("Invalid value for enableSessionState: " + enabless);
226                         }
227
228                         string value = GetString (atts, "CodePage", null);
229                         if (value != null) {
230                                 if (responseEncoding != null)
231                                         ThrowParseException ("CodePage and ResponseEncoding are mutually exclusive.");
232                                 
233                                 if (!BaseParser.IsExpression (value)) {
234                                         int cpval = -1;
235
236                                         try {
237                                                 cpval = (int) UInt32.Parse (value);
238                                         } catch {
239                                                 ThrowParseException ("Invalid value for CodePage: " + value);
240                                         }
241
242                                         try {
243                                                 Encoding.GetEncoding (cpval);
244                                         } catch {
245                                                 ThrowParseException ("Unsupported codepage: " + value);
246                                         }
247                                         codepage = new MainDirectiveAttribute <int> (cpval, true);
248                                 } else
249                                         codepage = new MainDirectiveAttribute <int> (value);
250                         }
251                         
252                         value = GetString (atts, "ResponseEncoding", null);
253                         if (value != null) {
254                                 if (codepage != null)
255                                         ThrowParseException ("CodePage and ResponseEncoding are mutually exclusive.");
256
257                                 if (!BaseParser.IsExpression (value)) {
258                                         try {
259                                                 Encoding.GetEncoding (value);
260                                         } catch {
261                                                 ThrowParseException ("Unsupported encoding: " + value);
262                                         }
263                                         responseEncoding = new MainDirectiveAttribute <string> (value, true);
264                                 } else
265                                         responseEncoding = new MainDirectiveAttribute <string> (value);
266                         }
267                         
268                         contentType = GetString (atts, "ContentType", null);
269
270                         value = GetString (atts, "LCID", null);
271                         if (value != null) {
272                                 if (!BaseParser.IsExpression (value)) {
273                                         int parsedLcid = -1;
274                                         try {
275                                                 parsedLcid = (int) UInt32.Parse (value);
276                                         } catch {
277                                                 ThrowParseException ("Invalid value for LCID: " + value);
278                                         }
279
280                                         CultureInfo ci = null;
281                                         try {
282                                                 ci = new CultureInfo (parsedLcid);
283                                         } catch {
284                                                 ThrowParseException ("Unsupported LCID: " + value);
285                                         }
286
287                                         if (ci.IsNeutralCulture) {
288                                                 string suggestedCulture = SuggestCulture (ci.Name);
289                                                 string fmt = "LCID attribute must be set to a non-neutral Culture.";
290                                                 if (suggestedCulture != null) {
291                                                         ThrowParseException (fmt + " Please try one of these: " +
292                                                                              suggestedCulture);
293                                                 } else {
294                                                         ThrowParseException (fmt);
295                                                 }
296                                         }
297                                         lcid = new MainDirectiveAttribute <int> (parsedLcid, true);
298                                 } else
299                                         lcid = new MainDirectiveAttribute <int> (value);
300                         }
301
302                         culture = GetString (atts, "Culture", null);
303                         if (culture != null) {
304                                 if (lcid != null) 
305                                         ThrowParseException ("Culture and LCID are mutually exclusive.");
306                                 
307                                 CultureInfo ci = null;
308                                 try {
309                                         if (!culture.StartsWith ("auto"))
310                                                 ci = new CultureInfo (culture);
311                                 } catch {
312                                         ThrowParseException ("Unsupported Culture: " + culture);
313                                 }
314
315                                 if (ci != null && ci.IsNeutralCulture) {
316                                         string suggestedCulture = SuggestCulture (culture);
317                                         string fmt = "Culture attribute must be set to a non-neutral Culture.";
318                                         if (suggestedCulture != null)
319                                                 ThrowParseException (fmt +
320                                                                 " Please try one of these: " + suggestedCulture);
321                                         else
322                                                 ThrowParseException (fmt);
323                                 }
324                         }
325
326                         uiculture = GetString (atts, "UICulture", null);
327                         if (uiculture != null) {
328                                 CultureInfo ci = null;
329                                 try {
330                                         if (!uiculture.StartsWith ("auto"))
331                                                 ci = new CultureInfo (uiculture);
332                                 } catch {
333                                         ThrowParseException ("Unsupported Culture: " + uiculture);
334                                 }
335
336                                 if (ci != null && ci.IsNeutralCulture) {
337                                         string suggestedCulture = SuggestCulture (uiculture);
338                                         string fmt = "UICulture attribute must be set to a non-neutral Culture.";
339                                         if (suggestedCulture != null)
340                                                 ThrowParseException (fmt +
341                                                                 " Please try one of these: " + suggestedCulture);
342                                         else
343                                                 ThrowParseException (fmt);
344                                 }
345                         }
346
347                         string tracestr = GetString (atts, "Trace", null);
348                         if (tracestr != null) {
349                                 haveTrace = true;
350                                 atts ["Trace"] = tracestr;
351                                 trace = GetBool (atts, "Trace", false);
352                         }
353
354                         string tracemodes = GetString (atts, "TraceMode", null);
355                         if (tracemodes != null) {
356                                 bool valid = true;
357                                 try {
358                                         tracemode = (TraceMode) Enum.Parse (typeof (TraceMode), tracemodes, false);
359                                 } catch {
360                                         valid = false;
361                                 }
362
363                                 if (!valid || tracemode == TraceMode.Default)
364                                         ThrowParseException ("The 'tracemode' attribute is case sensitive and must be " +
365                                                         "one of the following values: SortByTime, SortByCategory.");
366                         }
367
368                         errorPage = GetString (atts, "ErrorPage", null);
369                         validateRequest = GetBool (atts, "ValidateRequest", validateRequest);
370                         value = GetString (atts, "ClientTarget", null);
371                         if (value != null) {                            
372                                 if (!BaseParser.IsExpression (value)) {
373                                         value = value.Trim ();
374                                         
375                                         ClientTargetSection sec = GetConfigSection <ClientTargetSection> ("system.web/clientTarget");
376                                         ClientTarget ct = null;
377                                 
378                                         if ((ct = sec.ClientTargets [value]) == null)
379                                                 value = value.ToLowerInvariant ();
380                                 
381                                         if (ct == null && (ct = sec.ClientTargets [value]) == null) {
382                                                 ThrowParseException (String.Format (
383                                                                              "ClientTarget '{0}' is an invalid alias. See the " +
384                                                                              "documentation for <clientTarget> config. section.",
385                                                                              clientTarget));
386                                         }
387                                         value = ct.UserAgent;
388                                         clientTarget = new MainDirectiveAttribute <string> (value, true);
389                                 } else
390                                         clientTarget = new MainDirectiveAttribute <string> (value);
391                         }
392
393                         notBuffer = !GetBool (atts, "Buffer", true);
394                         async = GetBool (atts, "Async", false);
395                         string asyncTimeoutVal = GetString (atts, "AsyncTimeout", null);
396                         if (asyncTimeoutVal != null) {
397                                 try {
398                                         asyncTimeout = Int32.Parse (asyncTimeoutVal);
399                                 } catch (Exception) {
400                                         ThrowParseException ("AsyncTimeout must be an integer value");
401                                 }
402                         }
403                         
404                         value = GetString (atts, "MasterPageFile", masterPage != null ? masterPage.Value : null);
405                         if (!String.IsNullOrEmpty (value)) {
406                                 if (!BaseParser.IsExpression (value)) {
407                                         value = System.Web.VirtualPathUtility.Combine(BaseVirtualDir, value);
408                                         var vpp = HostingEnvironment.VirtualPathProvider;
409                                         if (!vpp.FileExists (value))
410                                                 ThrowParseFileNotFound (value);
411                                         value = vpp.CombineVirtualPaths (VirtualPath.Absolute, VirtualPathUtility.ToAbsolute (value));
412                                         AddDependency (value, false);
413                                         masterPage = new MainDirectiveAttribute <string> (value, true);
414                                 } else
415                                         masterPage = new MainDirectiveAttribute <string> (value);
416                         }
417                         
418                         value = GetString(atts, "Title", null);
419                         if (value != null) {
420                                 if (!BaseParser.IsExpression (value))
421                                         title = new MainDirectiveAttribute <string> (value, true);
422                                 else
423                                         title = new MainDirectiveAttribute <string> (value);
424                         }
425                         
426                         value = GetString (atts, "Theme", theme != null ? theme.Value : null);
427                         if (value != null) {
428                                 if (!BaseParser.IsExpression (value))
429                                         theme = new MainDirectiveAttribute <string> (value, true);
430                                 else
431                                         theme = new MainDirectiveAttribute <string> (value);
432                         }
433                         
434                         styleSheetTheme = GetString (atts, "StyleSheetTheme", styleSheetTheme);
435                         enable_event_validation = GetBool (atts, "EnableEventValidation", enable_event_validation);
436                         maintainScrollPositionOnPostBack = GetBool (atts, "MaintainScrollPositionOnPostBack", maintainScrollPositionOnPostBack);
437
438                         if (atts.Contains ("EnableViewStateMac")) {
439                                 enableViewStateMac = GetBool (atts, "EnableViewStateMac", enableViewStateMac);
440                                 enableViewStateMacSet = true;
441                         }
442 #if NET_4_0
443                         value = GetString (atts, "MetaDescription", null);
444                         if (value != null) {
445                                 if (!BaseParser.IsExpression (value))
446                                         metaDescription = new MainDirectiveAttribute <string> (value, true);
447                                 else
448                                         metaDescription = new MainDirectiveAttribute <string> (value);
449                         }
450
451                         value = GetString (atts, "MetaKeywords", null);
452                         if (value != null) {
453                                 if (!BaseParser.IsExpression (value))
454                                         metaKeywords = new MainDirectiveAttribute <string> (value, true);
455                                 else
456                                         metaKeywords = new MainDirectiveAttribute <string> (value);
457                         }
458 #endif
459                         // Ignored by now
460                         GetString (atts, "SmartNavigation", null);
461
462                         base.ProcessMainAttributes (atts);
463                 }
464                 
465                 internal override void AddDirective (string directive, IDictionary atts)
466                 {
467                         bool isMasterType = String.Compare ("MasterType", directive, StringComparison.OrdinalIgnoreCase) == 0;
468                         bool isPreviousPageType = isMasterType ? false : String.Compare ("PreviousPageType", directive,
469                                                                                          StringComparison.OrdinalIgnoreCase) == 0;
470
471                         string typeName = null;
472                         string virtualPath = null;
473                         Type type = null;
474                         
475                         if (isMasterType || isPreviousPageType) {
476                                 PageParserFilter pfilter = PageParserFilter;
477                                 if (pfilter != null)
478                                         pfilter.PreprocessDirective (directive.ToLowerInvariant (), atts);
479                                 
480                                 typeName = GetString (atts, "TypeName", null);
481                                 virtualPath = GetString (atts, "VirtualPath", null);
482
483                                 if (typeName != null && virtualPath != null)
484                                         ThrowParseException (
485                                                 String.Format ("The '{0}' directive must have exactly one attribute: TypeName or VirtualPath", directive));
486                                 if (typeName != null) {
487                                         type = LoadType (typeName);
488                                         if (type == null)
489                                                 ThrowParseException (String.Format ("Could not load type '{0}'.", typeName));
490                                         if (isMasterType)
491                                                 masterType = type;
492                                         else
493                                                 previousPageType = type;
494                                 } else if (!String.IsNullOrEmpty (virtualPath)) {
495                                         if (!HostingEnvironment.VirtualPathProvider.FileExists (virtualPath))
496                                                 ThrowParseFileNotFound (virtualPath);
497
498                                         AddDependency (virtualPath, true);
499                                         if (isMasterType)
500                                                 masterVirtualPath = virtualPath;
501                                         else
502                                                 previousPageVirtualPath = virtualPath;
503                                 } else
504                                         ThrowParseException (String.Format ("The {0} directive must have either a TypeName or a VirtualPath attribute.", directive));
505
506                                 if (type != null)
507                                         AddAssembly (type.Assembly, true);
508                         } else
509                                 base.AddDirective (directive, atts);
510                 }
511                 
512                 static string SuggestCulture (string culture)
513                 {
514                         string retval = null;
515                         foreach (CultureInfo ci in CultureInfo.GetCultures (CultureTypes.SpecificCultures)) {
516                                 if (ci.Name.StartsWith (culture))
517                                         retval += ci.Name + " ";
518                         }
519                         return retval;
520                 }
521
522                 internal Type GetCompiledPageType (string virtualPath, string inputFile, HttpContext context)
523                 {
524                         return BuildManager.GetCompiledType (virtualPath);
525                 }
526                 
527                 internal override Type CompileIntoType ()
528                 {
529                         AspGenerator generator = new AspGenerator (this);
530                         return generator.GetCompiledType ();
531                 }
532
533                 internal bool EnableSessionState {
534                         get {
535                                 return enableSessionState == PagesEnableSessionState.True ||
536                                         ReadOnlySessionState;
537                         }
538                 }
539
540                 internal bool EnableViewStateMac {
541                         get { return enableViewStateMac; }
542                 }
543
544                 internal bool EnableViewStateMacSet {
545                         get { return enableViewStateMacSet; }
546                 }
547                 
548                 internal bool SmartNavigation {
549                         get { return smartNavigation; }
550                 }
551                 
552                 internal bool ReadOnlySessionState {
553                         get {
554                                 return enableSessionState == PagesEnableSessionState.ReadOnly;
555                         }
556                 }
557
558                 internal bool HaveTrace {
559                         get { return haveTrace; }
560                 }
561
562                 internal bool Trace {
563                         get { return trace; }
564                 }
565
566                 internal TraceMode TraceMode {
567                         get { return tracemode; }
568                 }               
569 #if NET_4_0
570                 internal override Type DefaultBaseType {
571                         get {
572                                 Type ret = DefaultPageBaseType;
573                                 if (ret == null)
574                                         return base.DefaultBaseType;
575
576                                 return ret;
577                         }
578                 }
579 #endif
580                 internal override string DefaultBaseTypeName {
581                         get { return PagesConfig.PageBaseType; }
582                 }
583                 
584                 internal override string DefaultDirectiveName {
585                         get { return "page"; }
586                 }
587
588                 internal string ContentType {
589                         get { return contentType; }
590                 }
591
592                 internal MainDirectiveAttribute <string> ResponseEncoding {
593                         get { return responseEncoding; }
594                 }
595                 
596                 internal MainDirectiveAttribute <int> CodePage {
597                         get { return codepage; }
598                 }
599
600                 internal MainDirectiveAttribute <int> LCID {
601                         get { return lcid; }
602                 }
603
604                 internal MainDirectiveAttribute <string> ClientTarget {
605                         get { return clientTarget; }
606                 }
607
608                 internal MainDirectiveAttribute <string> MasterPageFile {
609                         get { return masterPage; }
610                 }
611
612                 internal MainDirectiveAttribute <string> Title {
613                         get { return title; }
614                 }
615
616                 internal MainDirectiveAttribute <string> Theme {
617                         get { return theme; }
618                 }
619 #if NET_4_0
620                 internal MainDirectiveAttribute <string> MetaDescription {
621                         get { return metaDescription; }
622                 }
623
624                 internal MainDirectiveAttribute <string> MetaKeywords {
625                         get { return metaKeywords; }
626                 }
627 #endif
628                 internal string Culture {
629                         get { return culture; }
630                 }
631
632                 internal string UICulture {
633                         get { return uiculture; }
634                 }
635
636                 internal string ErrorPage {
637                         get { return errorPage; }
638                 }
639
640                 internal bool ValidateRequest {
641                         get { return validateRequest; }
642                 }
643
644                 internal bool NotBuffer {
645                         get { return notBuffer; }
646                 }
647
648                 internal bool Async {
649                         get { return async; }
650                 }
651
652                 internal int AsyncTimeout {
653                         get { return asyncTimeout; }
654                 }
655
656                 internal string StyleSheetTheme {
657                         get { return styleSheetTheme; }
658                 }
659                 
660                 internal Type MasterType {
661                         get {
662                                 if (masterType == null && !String.IsNullOrEmpty (masterVirtualPath))
663                                         masterType = BuildManager.GetCompiledType (masterVirtualPath);
664                                 
665                                 return masterType;
666                         }
667                 }
668
669                 internal bool EnableEventValidation {
670                         get { return enable_event_validation; }
671                 }
672
673                 internal bool MaintainScrollPositionOnPostBack {
674                         get { return maintainScrollPositionOnPostBack; }
675                 }
676
677                 internal int MaxPageStateFieldLength {
678                         get { return maxPageStateFieldLength; }
679                 }
680
681                 internal Type PreviousPageType {
682                         get {
683                                 if (previousPageType == null && !String.IsNullOrEmpty (previousPageVirtualPath)) {
684                                         string mappedPath = MapPath (previousPageVirtualPath);
685                                         previousPageType = GetCompiledPageType (previousPageVirtualPath, mappedPath, HttpContext.Current);
686                                 }
687                                 
688                                 return previousPageType;
689                         }
690                 }
691         }
692 }
693