1 // 2 // System.Web.UI.MasterPage.cs 3 // 4 // Authors: 5 // Lluis Sanchez Gual (lluis@novell.com) 6 // 7 // (C) 2005-2010 Novell, Inc. 8 // 9 10 // 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: 18 // 19 // The above copyright notice and this permission notice shall be 20 // included in all copies or substantial portions of the Software. 21 // 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. 29 // 30 31 using System; 32 using System.Collections; 33 using System.Collections.Generic; 34 using System.ComponentModel; 35 using System.Web.Compilation; 36 using System.Web.Hosting; 37 using System.Web.Util; 38 using System.Web.UI.WebControls; 39 using System.IO; 40 41 namespace System.Web.UI 42 { 43 [ParseChildren (false)] 44 #if notyet 45 [Designer (...)] 46 #endif 47 [ControlBuilder (typeof (MasterPageControlBuilder))] 48 public class MasterPage: UserControl 49 { 50 Hashtable definedContentTemplates = new Hashtable (); 51 Hashtable templates = new Hashtable (); 52 List <string> placeholders; 53 string parentMasterPageFile = null; 54 MasterPage parentMasterPage; 55 56 [EditorBrowsable (EditorBrowsableState.Advanced)] AddContentTemplate(string templateName, ITemplate template)57 protected internal void AddContentTemplate (string templateName, ITemplate template) 58 { 59 // LAMESPEC: should be ArgumentException 60 if (definedContentTemplates.ContainsKey (templateName)) 61 throw new HttpException ("Multiple contents applied to " + templateName); 62 63 definedContentTemplates [templateName] = template; 64 } 65 66 [Browsable (false)] 67 [EditorBrowsable (EditorBrowsableState.Advanced)] 68 protected internal IList ContentPlaceHolders { 69 get { 70 if (placeholders == null) 71 placeholders = new List <string> (); 72 return placeholders; 73 } 74 } 75 76 [Browsable (false)] 77 [EditorBrowsable (EditorBrowsableState.Advanced)] 78 protected internal IDictionary ContentTemplates { 79 get { return templates; } 80 } 81 82 [DefaultValueAttribute ("")] 83 public string MasterPageFile { 84 get { return parentMasterPageFile; } 85 set { 86 parentMasterPageFile = value; 87 parentMasterPage = null; 88 } 89 } 90 91 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] 92 [BrowsableAttribute (false)] 93 public MasterPage Master { 94 get { 95 if (parentMasterPage == null && parentMasterPageFile != null) 96 parentMasterPage = MasterPage.CreateMasterPage (this, Context, parentMasterPageFile, definedContentTemplates); 97 98 return parentMasterPage; 99 } 100 } InstantiateInContentPlaceHolder(Control contentPlaceHolder, ITemplate template)101 public void InstantiateInContentPlaceHolder (Control contentPlaceHolder, ITemplate template) 102 { 103 // .NET compatibility... 104 if (contentPlaceHolder == null || template == null) 105 throw new NullReferenceException (); 106 107 if (contentPlaceHolder != null && template != null) 108 template.InstantiateIn (contentPlaceHolder); 109 } CreateMasterPage(TemplateControl owner, HttpContext context, string masterPageFile, IDictionary contentTemplateCollection)110 internal static MasterPage CreateMasterPage (TemplateControl owner, HttpContext context, 111 string masterPageFile, IDictionary contentTemplateCollection) 112 { 113 var req = context.Request; 114 if (req != null) 115 masterPageFile = HostingEnvironment.VirtualPathProvider.CombineVirtualPaths (req.CurrentExecutionFilePath, masterPageFile); 116 MasterPage masterPage = BuildManager.CreateInstanceFromVirtualPath (masterPageFile, typeof (MasterPage)) as MasterPage; 117 if (masterPage == null) 118 throw new HttpException ("Failed to create MasterPage instance for '" + masterPageFile + "'."); 119 120 if (contentTemplateCollection != null) { 121 foreach (string templateName in contentTemplateCollection.Keys) { 122 if (masterPage.ContentTemplates [templateName] == null) 123 masterPage.ContentTemplates [templateName] = contentTemplateCollection[templateName]; 124 } 125 } 126 127 masterPage.Page = owner.Page; 128 masterPage.InitializeAsUserControlInternal (); 129 130 List <string> placeholders = masterPage.placeholders; 131 if (contentTemplateCollection != null && placeholders != null && placeholders.Count > 0) { 132 foreach (string templateName in contentTemplateCollection.Keys) { 133 if (!placeholders.Contains (templateName.ToLowerInvariant ())) { 134 throw new HttpException ( 135 String.Format ("Cannot find ContentPlaceHolder '{0}' in the master page '{1}'", 136 templateName, masterPageFile)); 137 } 138 } 139 } 140 141 return masterPage; 142 } 143 ApplyMasterPageRecursive(string currentFilePath, VirtualPathProvider vpp, MasterPage master, Dictionary <string, bool> appliedMasterPageFiles)144 internal static void ApplyMasterPageRecursive (string currentFilePath, VirtualPathProvider vpp, MasterPage master, Dictionary <string, bool> appliedMasterPageFiles) 145 { 146 /* XXX need to use virtual paths here? */ 147 string mpFile = master.MasterPageFile; 148 if (!String.IsNullOrEmpty (mpFile)) { 149 mpFile = vpp.CombineVirtualPaths (currentFilePath, mpFile); 150 if (appliedMasterPageFiles.ContainsKey (mpFile)) 151 throw new HttpException ("circular dependency in master page files detected"); 152 153 MasterPage innerMaster = master.Master; 154 if (innerMaster != null) { 155 master.Controls.Clear (); 156 master.Controls.Add (innerMaster); 157 appliedMasterPageFiles.Add (mpFile, true); 158 MasterPage.ApplyMasterPageRecursive (currentFilePath, vpp, innerMaster, appliedMasterPageFiles); 159 } 160 } 161 } 162 } 163 } 164