2 // System.Web.UI.TemplateParser
5 // Duncan Mak (duncan@ximian.com)
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 // (C) 2002,2003 Ximian, Inc. (http://www.ximian.com)
9 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.CodeDom.Compiler;
32 using System.Collections;
33 using System.ComponentModel;
34 using System.Globalization;
36 using System.Reflection;
37 using System.Security.Permissions;
38 using System.Web.Compilation;
39 using System.Web.Configuration;
40 using System.Web.Util;
43 using System.Collections.Generic;
46 namespace System.Web.UI {
47 internal class ServerSideScript
49 public readonly string Script;
50 public readonly ILocation Location;
52 public ServerSideScript (string script, ILocation location)
60 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
61 [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
62 public abstract class TemplateParser : BaseParser
66 string privateBinPath;
67 Hashtable mainAttributes;
68 ArrayList dependencies;
75 bool baseTypeIsGlobal = true;
77 RootBuilder rootBuilder;
79 string compilerOptions;
81 bool implicitLanguage;
82 bool strictOn = false;
83 bool explicitOn = false;
84 bool linePragmasOn = false;
87 string oc_header, oc_custom, oc_param, oc_controls;
89 string oc_content_encodings;
92 OutputCacheLocation oc_location;
93 CultureInfo invariantCulture = CultureInfo.InvariantCulture;
97 string partialClassName;
98 string codeFileBaseClass;
99 string metaResourceKey;
100 Type codeFileBaseClassType;
101 List <UnknownAttributeDescriptor> unknownMainAttributes;
103 ILocation directiveLocation;
105 Assembly srcAssembly;
106 int appAssemblyIndex = -1;
108 internal TemplateParser ()
110 LoadConfigDefaults ();
112 imports = new ArrayList ();
114 AddNamespaces (imports);
116 imports.Add ("System");
117 imports.Add ("System.Collections");
118 imports.Add ("System.Collections.Specialized");
119 imports.Add ("System.Configuration");
120 imports.Add ("System.Text");
121 imports.Add ("System.Text.RegularExpressions");
122 imports.Add ("System.Web");
123 imports.Add ("System.Web.Caching");
124 imports.Add ("System.Web.Security");
125 imports.Add ("System.Web.SessionState");
126 imports.Add ("System.Web.UI");
127 imports.Add ("System.Web.UI.WebControls");
128 imports.Add ("System.Web.UI.HtmlControls");
131 assemblies = new ArrayList ();
133 CompilationSection compConfig = CompilationConfig;
135 bool addAssembliesInBin = false;
136 foreach (AssemblyInfo info in compConfig.Assemblies) {
137 if (info.Assembly == "*")
138 addAssembliesInBin = true;
140 AddAssemblyByName (info.Assembly);
142 if (addAssembliesInBin)
143 AddAssembliesInBin ();
145 foreach (NamespaceInfo info in PagesConfig.Namespaces) {
146 imports.Add (info.Namespace);
149 CompilationConfiguration compConfig = CompilationConfig;
151 foreach (string a in compConfig.Assemblies)
152 AddAssemblyByName (a);
153 if (compConfig.AssembliesInBin)
154 AddAssembliesInBin ();
157 language = compConfig.DefaultLanguage;
158 implicitLanguage = true;
161 internal virtual void LoadConfigDefaults ()
163 debug = CompilationConfig.Debug;
166 internal void AddApplicationAssembly ()
168 if (Context.ApplicationInstance == null)
169 return; // this may happen if we have Global.asax and have
170 // controls registered from Web.Config
171 string location = Context.ApplicationInstance.AssemblyLocation;
172 if (location != typeof (TemplateParser).Assembly.Location) {
173 appAssemblyIndex = assemblies.Add (location);
177 protected abstract Type CompileIntoType ();
180 void AddNamespaces (ArrayList imports)
182 if (BuildManager.HaveResources)
183 imports.Add ("System.Resources");
185 PagesSection pages = WebConfigurationManager.GetSection ("system.web/pages") as PagesSection;
189 NamespaceCollection namespaces = pages.Namespaces;
190 if (namespaces == null || namespaces.Count == 0)
193 foreach (NamespaceInfo nsi in namespaces)
194 imports.Add (nsi.Namespace);
198 internal void RegisterCustomControl (string tagPrefix, string tagName, string src)
200 string realpath = MapPath (src);
201 if (String.Compare (realpath, inputFile, false, invariantCulture) == 0)
204 if (!File.Exists (realpath))
205 throw new ParseException (Location, "Could not find file \"" + realpath + "\".");
206 string vpath = VirtualPathUtility.Combine (BaseVirtualDir, src);
207 if (VirtualPathUtility.IsAbsolute (vpath))
208 vpath = VirtualPathUtility.ToAppRelative (vpath);
211 AddDependency (vpath);
214 type = BuildManager.GetCompiledType (vpath);
216 throw new ParseException (Location, "Error compiling user control '" + vpath + "'.");
218 if (!(typeof (UserControl).IsAssignableFrom (type)))
219 throw new ParseException (Location, "Type '" + type.ToString () + "' does not derive from 'System.Web.UI.UserControl'.");
221 ArrayList other_deps = new ArrayList ();
222 type = UserControlParser.GetCompiledType (vpath, realpath, other_deps, Context);
223 foreach (string s in other_deps)
226 } catch (ParseException pe) {
227 if (this is UserControlParser)
228 throw new ParseException (Location, pe.Message, pe);
232 AddAssembly (type.Assembly, true);
233 RootBuilder.Foundry.RegisterFoundry (tagPrefix, tagName, type);
236 internal void RegisterNamespace (string tagPrefix, string ns, string assembly)
241 if (assembly != null && assembly.Length > 0)
242 ass = AddAssemblyByName (assembly);
244 RootBuilder.Foundry.RegisterFoundry (tagPrefix, ass, ns);
247 internal virtual void HandleOptions (object obj)
251 internal static string GetOneKey (Hashtable tbl)
253 foreach (object key in tbl.Keys)
254 return key.ToString ();
259 internal virtual void AddDirective (string directive, Hashtable atts)
261 if (String.Compare (directive, DefaultDirectiveName, true) == 0) {
262 if (mainAttributes != null)
263 ThrowParseException ("Only 1 " + DefaultDirectiveName + " is allowed");
265 mainAttributes = atts;
266 ProcessMainAttributes (mainAttributes);
270 int cmp = String.Compare ("Assembly", directive, true);
272 string name = GetString (atts, "Name", null);
273 string src = GetString (atts, "Src", null);
276 ThrowParseException ("Attribute " + GetOneKey (atts) + " unknown.");
278 if (name == null && src == null)
279 ThrowParseException ("You gotta specify Src or Name");
281 if (name != null && src != null)
282 ThrowParseException ("Src and Name cannot be used together");
285 AddAssemblyByName (name);
287 GetAssemblyFromSource (src);
293 cmp = String.Compare ("Import", directive, true);
295 string namesp = GetString (atts, "Namespace", null);
297 ThrowParseException ("Attribute " + GetOneKey (atts) + " unknown.");
299 if (namesp != null && namesp != "")
304 cmp = String.Compare ("Implements", directive, true);
306 string ifacename = GetString (atts, "Interface", "");
309 ThrowParseException ("Attribute " + GetOneKey (atts) + " unknown.");
311 Type iface = LoadType (ifacename);
313 ThrowParseException ("Cannot find type " + ifacename);
315 if (!iface.IsInterface)
316 ThrowParseException (iface + " is not an interface");
318 AddInterface (iface.FullName);
322 cmp = String.Compare ("OutputCache", directive, true);
324 HttpResponse response = HttpContext.Current.Response;
325 if (response != null)
326 response.Cache.SetValidUntilExpires (true);
330 if (atts ["Duration"] == null)
331 ThrowParseException ("The directive is missing a 'duration' attribute.");
332 if (atts ["VaryByParam"] == null && atts ["VaryByControl"] == null)
333 ThrowParseException ("This directive is missing 'VaryByParam' " +
334 "or 'VaryByControl' attribute, which should be set to \"none\", \"*\", " +
335 "or a list of name/value pairs.");
337 foreach (DictionaryEntry entry in atts) {
338 string key = (string) entry.Key;
339 switch (key.ToLower ()) {
341 oc_duration = Int32.Parse ((string) entry.Value);
343 ThrowParseException ("The 'duration' attribute must be set " +
344 "to a positive integer value");
347 case "varybycontentencodings":
348 oc_content_encodings = (string) entry.Value;
352 oc_param = (string) entry.Value;
353 if (String.Compare (oc_param, "none") == 0)
357 oc_header = (string) entry.Value;
360 oc_custom = (string) entry.Value;
363 if (!(this is PageParser))
367 oc_location = (OutputCacheLocation) Enum.Parse (
368 typeof (OutputCacheLocation), (string) entry.Value, true);
370 ThrowParseException ("The 'location' attribute is case sensitive and " +
371 "must be one of the following values: Any, Client, " +
372 "Downstream, Server, None, ServerAndClient.");
375 case "varybycontrol":
377 if (this is PageParser)
380 oc_controls = (string) entry.Value;
383 if (this is PageParser)
387 oc_shared = Boolean.Parse ((string) entry.Value);
389 ThrowParseException ("The 'shared' attribute is case sensitive" +
390 " and must be set to 'true' or 'false'.");
394 ThrowParseException ("The '" + key + "' attribute is not " +
395 "supported by the 'Outputcache' directive.");
404 ThrowParseException ("Unknown directive: " + directive);
407 internal Type LoadType (string typeName)
409 Type type = HttpApplication.LoadType (typeName);
412 Assembly asm = type.Assembly;
413 string location = asm.Location;
415 string dirname = Path.GetDirectoryName (location);
416 bool doAddAssembly = true;
417 if (dirname == HttpApplication.BinDirectory)
418 doAddAssembly = false;
421 AddAssembly (asm, true);
426 void AddAssembliesInBin ()
428 foreach (string s in HttpApplication.BinDirectoryAssemblies)
432 internal virtual void AddInterface (string iface)
434 if (interfaces == null)
435 interfaces = new ArrayList ();
437 if (!interfaces.Contains (iface))
438 interfaces.Add (iface);
441 internal virtual void AddImport (string namesp)
444 imports = new ArrayList ();
446 if (!imports.Contains (namesp))
447 imports.Add (namesp);
450 internal virtual void AddSourceDependency (string filename)
452 if (dependencies != null && dependencies.Contains (filename))
453 ThrowParseException ("Circular file references are not allowed. File: " + filename);
455 AddDependency (filename);
458 internal virtual void AddDependency (string filename)
463 if (dependencies == null)
464 dependencies = new ArrayList ();
466 if (!dependencies.Contains (filename))
467 dependencies.Add (filename);
470 internal virtual void AddAssembly (Assembly assembly, bool fullPath)
472 if (assembly.Location == "")
476 anames = new Hashtable ();
478 string name = assembly.GetName ().Name;
479 string loc = assembly.Location;
481 if (!assemblies.Contains (loc)) {
482 assemblies.Add (loc);
486 anames [loc] = assembly;
488 if (!assemblies.Contains (name)) {
489 assemblies.Add (name);
492 anames [name] = assembly;
496 internal virtual Assembly AddAssemblyByFileName (string filename)
498 Assembly assembly = null;
499 Exception error = null;
502 assembly = Assembly.LoadFrom (filename);
503 } catch (Exception e) { error = e; }
505 if (assembly == null)
506 ThrowParseException ("Assembly " + filename + " not found", error);
508 AddAssembly (assembly, true);
512 internal virtual Assembly AddAssemblyByName (string name)
515 anames = new Hashtable ();
517 if (anames.Contains (name)) {
518 object o = anames [name];
525 Assembly assembly = null;
526 Exception error = null;
528 assembly = Assembly.Load (name);
529 } catch (Exception e) { error = e; }
531 if (assembly == null) {
533 assembly = Assembly.LoadWithPartialName (name);
534 } catch (Exception e) { error = e; }
537 if (assembly == null)
538 ThrowParseException ("Assembly " + name + " not found", error);
540 AddAssembly (assembly, true);
544 internal virtual void ProcessMainAttributes (Hashtable atts)
546 directiveLocation = new System.Web.Compilation.Location (Location);
549 CompilationSection compConfig;
551 CompilationConfiguration compConfig;
554 compConfig = CompilationConfig;
556 atts.Remove ("Description"); // ignored
558 atts.Remove ("CodeBehind"); // ignored
560 atts.Remove ("AspCompat"); // ignored
562 debug = GetBool (atts, "Debug", compConfig.Debug);
563 compilerOptions = GetString (atts, "CompilerOptions", "");
564 language = GetString (atts, "Language", "");
565 if (language.Length != 0)
566 implicitLanguage = false;
568 language = compConfig.DefaultLanguage;
570 strictOn = GetBool (atts, "Strict", compConfig.Strict);
571 explicitOn = GetBool (atts, "Explicit", compConfig.Explicit);
572 linePragmasOn = GetBool (atts, "LinePragmas", false);
574 string inherits = GetString (atts, "Inherits", null);
575 string srcRealPath = null;
578 // In ASP 2, the source file is actually integrated with
579 // the generated file via the use of partial classes. This
580 // means that the code file has to be confirmed, but not
581 // used at this point.
582 src = GetString (atts, "CodeFile", null);
583 codeFileBaseClass = GetString (atts, "CodeFileBaseClass", null);
585 if (src == null && codeFileBaseClass != null)
586 ThrowParseException ("The 'CodeFileBaseClass' attribute cannot be used without a 'CodeFile' attribute");
588 string legacySrc = GetString (atts, "Src", null);
589 if (legacySrc != null) {
590 legacySrc = UrlUtils.Combine (BaseVirtualDir, legacySrc);
591 GetAssemblyFromSource (legacySrc);
595 legacySrc = MapPath (legacySrc, false);
596 srcRealPath = legacySrc;
597 if (!File.Exists (srcRealPath))
598 ThrowParseException ("File " + src + " not found");
602 legacySrc = MapPath (legacySrc, false);
604 AddDependency (legacySrc);
607 if (!srcIsLegacy && src != null && inherits != null) {
608 // Make sure the source exists
609 src = UrlUtils.Combine (BaseVirtualDir, src);
610 srcRealPath = MapPath (src, false);
612 if (!File.Exists (srcRealPath))
613 ThrowParseException ("File " + src + " not found");
615 // We are going to create a partial class that shares
616 // the same name as the inherits tag, so reset the
617 // name. The base type is changed because it is the
618 // code file's responsibilty to extend the classes
620 partialClassName = inherits;
622 // Add the code file as an option to the
623 // compiler. This lets both files be compiled at once.
624 compilerOptions += " \"" + srcRealPath + "\"";
626 if (codeFileBaseClass != null) {
628 codeFileBaseClassType = LoadType (codeFileBaseClass);
629 } catch (Exception) {
632 if (codeFileBaseClassType == null)
633 ThrowParseException ("Could not load type '{0}'", codeFileBaseClass);
635 } else if (inherits != null) {
636 // We just set the inherits directly because this is a
637 // Single-Page model.
638 SetBaseType (inherits);
641 string src = GetString (atts, "Src", null);
644 srcRealPath = MapPath (src, false);
645 srcAssembly = GetAssemblyFromSource (src);
648 if (inherits != null)
649 SetBaseType (inherits);
652 if (VirtualPathUtility.IsAbsolute (src))
653 src = VirtualPathUtility.ToAppRelative (src);
657 className = GetString (atts, "ClassName", null);
658 if (className != null) {
660 string [] identifiers = className.Split ('.');
661 for (int i = 0; i < identifiers.Length; i++)
662 if (!CodeGenerator.IsValidLanguageIndependentIdentifier (identifiers [i]))
663 ThrowParseException (String.Format ("'{0}' is not a valid "
664 + "value for attribute 'classname'.", className));
666 if (!CodeGenerator.IsValidLanguageIndependentIdentifier (className))
667 ThrowParseException (String.Format ("'{0}' is not a valid "
668 + "value for attribute 'classname'.", className));
673 if (this is TemplateControlParser)
674 metaResourceKey = GetString (atts, "meta:resourcekey", null);
676 if (inherits != null && (this is PageParser || this is UserControlParser) && atts.Count > 0) {
677 if (unknownMainAttributes == null)
678 unknownMainAttributes = new List <UnknownAttributeDescriptor> ();
681 foreach (DictionaryEntry de in atts) {
682 key = de.Key as string;
683 val = de.Value as string;
685 if (String.IsNullOrEmpty (key) || String.IsNullOrEmpty (val))
687 CheckUnknownAttribute (key, val, inherits);
693 ThrowParseException ("Unknown attribute: " + GetOneKey (atts));
697 void CheckUnknownAttribute (string name, string val, string inherits)
699 MemberInfo mi = null;
700 bool missing = false;
701 string memberName = name.Trim ().ToLower (CultureInfo.InvariantCulture);
702 Type parent = codeFileBaseClassType;
708 MemberInfo[] infos = parent.GetMember (memberName,
709 MemberTypes.Field | MemberTypes.Property,
710 BindingFlags.Public | BindingFlags.Instance |
711 BindingFlags.IgnoreCase | BindingFlags.Static);
712 if (infos.Length != 0) {
713 // prefer public properties to public methods (it's what MS.NET does)
714 foreach (MemberInfo tmp in infos) {
715 if (tmp is PropertyInfo) {
724 } catch (Exception) {
728 ThrowParseException (
729 "Error parsing attribute '{0}': Type '{1}' does not have a public property named '{0}'",
730 memberName, inherits);
732 Type memberType = null;
733 if (mi is PropertyInfo) {
734 PropertyInfo pi = mi as PropertyInfo;
737 ThrowParseException (
738 "Error parsing attribute '{0}': The '{0}' property is read-only and cannot be set.",
740 memberType = pi.PropertyType;
741 } else if (mi is FieldInfo) {
742 memberType = ((FieldInfo)mi).FieldType;
744 ThrowParseException ("Could not determine member the kind of '{0}' in base type '{1}",
745 memberName, inherits);
746 TypeConverter converter = TypeDescriptor.GetConverter (memberType);
747 bool convertible = true;
750 if (converter == null || !converter.CanConvertFrom (typeof (string)))
755 value = converter.ConvertFromInvariantString (val);
756 } catch (Exception) {
762 ThrowParseException ("Error parsing attribute '{0}': Cannot create an object of type '{1}' from its string representation '{2}' for the '{3}' property.",
763 memberName, memberType, val, mi.Name);
765 UnknownAttributeDescriptor desc = new UnknownAttributeDescriptor (mi, value);
766 unknownMainAttributes.Add (desc);
770 internal void SetBaseType (string type)
772 if (type == null || type == DefaultBaseTypeName) {
773 baseType = DefaultBaseType;
778 if (srcAssembly != null)
779 parent = srcAssembly.GetType (type);
782 parent = LoadType (type);
785 ThrowParseException ("Cannot find type " + type);
787 if (!DefaultBaseType.IsAssignableFrom (parent))
788 ThrowParseException ("The parent type '" + type + "' does not derive from " + DefaultBaseType);
793 internal void SetLanguage (string language)
795 this.language = language;
796 implicitLanguage = false;
799 Assembly GetAssemblyFromSource (string vpath)
801 vpath = UrlUtils.Combine (BaseVirtualDir, vpath);
802 string realPath = MapPath (vpath, false);
803 if (!File.Exists (realPath))
804 ThrowParseException ("File " + vpath + " not found");
806 AddSourceDependency (vpath);
808 CompilerResults result;
812 CompilerParameters parameters;
813 CodeDomProvider provider = BaseCompiler.CreateProvider (HttpContext.Current, language, out parameters, out tmp);
814 if (provider == null)
815 throw new HttpException ("Cannot find provider for language '" + language + "'.");
817 AssemblyBuilder abuilder = new AssemblyBuilder (provider);
818 abuilder.CompilerOptions = parameters;
819 abuilder.AddAssemblyReference (BuildManager.GetReferencedAssemblies () as List <Assembly>);
820 abuilder.AddCodeFile (realPath);
821 result = abuilder.BuildAssembly (vpath);
823 result = CachingCompiler.Compile (language, realPath, realPath, assemblies, Debug);
825 if (result.NativeCompilerReturnValue != 0) {
826 StreamReader reader = new StreamReader (realPath);
827 throw new CompilationException (realPath, result.Errors, reader.ReadToEnd ());
830 AddAssembly (result.CompiledAssembly, true);
831 return result.CompiledAssembly;
834 internal abstract string DefaultBaseTypeName { get; }
835 internal abstract string DefaultDirectiveName { get; }
837 internal Type DefaultBaseType {
839 Type type = Type.GetType (DefaultBaseTypeName, true);
845 internal ILocation DirectiveLocation {
846 get { return directiveLocation; }
849 internal string InputFile
851 get { return inputFile; }
852 set { inputFile = value; }
856 internal bool IsPartial {
857 get { return (!srcIsLegacy && src != null); }
860 internal string CodeBehindSource {
869 internal string PartialClassName {
870 get { return partialClassName; }
873 internal string CodeFileBaseClass {
874 get { return codeFileBaseClass; }
877 internal string MetaResourceKey {
878 get { return metaResourceKey; }
881 internal Type CodeFileBaseClassType
883 get { return codeFileBaseClassType; }
886 internal List <UnknownAttributeDescriptor> UnknownMainAttributes
888 get { return unknownMainAttributes; }
892 internal string Text {
894 set { text = value; }
897 internal Type BaseType {
899 if (baseType == null)
900 SetBaseType (DefaultBaseTypeName);
906 internal bool BaseTypeIsGlobal {
907 get { return baseTypeIsGlobal; }
908 set { baseTypeIsGlobal = value; }
911 internal string ClassName {
913 if (className != null)
917 string physPath = HttpContext.Current.Request.PhysicalApplicationPath;
920 if (String.IsNullOrEmpty (inputFile)) {
922 StreamReader sr = Reader as StreamReader;
925 FileStream fr = sr.BaseStream as FileStream;
932 if (String.IsNullOrEmpty (inFile))
933 throw new HttpException ("Unable to determine class name - no input file found.");
935 if (StrUtils.StartsWith (inFile, physPath)) {
936 className = inputFile.Substring (physPath.Length).ToLower (CultureInfo.InvariantCulture);
937 className = className.Replace ('.', '_');
938 className = className.Replace ('/', '_').Replace ('\\', '_');
941 className = Path.GetFileName (inputFile).Replace ('.', '_');
942 className = className.Replace ('-', '_');
943 className = className.Replace (' ', '_');
945 if (Char.IsDigit(className[0])) {
946 className = "_" + className;
953 internal ArrayList Scripts {
956 scripts = new ArrayList ();
962 internal ArrayList Imports {
963 get { return imports; }
966 internal ArrayList Assemblies {
968 if (appAssemblyIndex != -1) {
969 object o = assemblies [appAssemblyIndex];
970 assemblies.RemoveAt (appAssemblyIndex);
972 appAssemblyIndex = -1;
979 internal ArrayList Interfaces {
980 get { return interfaces; }
983 internal RootBuilder RootBuilder {
984 get { return rootBuilder; }
985 set { rootBuilder = value; }
988 internal ArrayList Dependencies {
989 get { return dependencies; }
990 set { dependencies = value; }
993 internal string CompilerOptions {
994 get { return compilerOptions; }
997 internal string Language {
998 get { return language; }
1001 internal bool ImplicitLanguage {
1002 get { return implicitLanguage; }
1005 internal bool StrictOn {
1006 get { return strictOn; }
1009 internal bool ExplicitOn {
1010 get { return explicitOn; }
1013 internal bool Debug {
1014 get { return debug; }
1017 internal bool OutputCache {
1018 get { return output_cache; }
1021 internal int OutputCacheDuration {
1022 get { return oc_duration; }
1026 internal string OutputCacheVaryByContentEncodings {
1027 get { return oc_content_encodings; }
1030 internal virtual TextReader Reader {
1031 get { return null; }
1036 internal string OutputCacheVaryByHeader {
1037 get { return oc_header; }
1040 internal string OutputCacheVaryByCustom {
1041 get { return oc_custom; }
1044 internal string OutputCacheVaryByControls {
1045 get { return oc_controls; }
1048 internal bool OutputCacheShared {
1049 get { return oc_shared; }
1052 internal OutputCacheLocation OutputCacheLocation {
1053 get { return oc_location; }
1056 internal string OutputCacheVaryByParam {
1057 get { return oc_param; }
1061 internal PagesSection PagesConfig {
1063 return WebConfigurationManager.GetSection ("system.web/pages") as PagesSection;
1067 internal PagesConfiguration PagesConfig {
1068 get { return PagesConfiguration.GetInstance (Context); }