1 //------------------------------------------------------------------------------ 2 // <copyright file="HandlerBase.cs" company="Microsoft"> 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // </copyright> 5 //------------------------------------------------------------------------------ 6 7 /* 8 * HandlerBase contains static helper functions for consistent XML parsing 9 * behavior and error messages. 10 * 11 * Copyright (c) 1998 Microsoft Corporation 12 */ 13 14 namespace System.Web.Configuration { 15 16 using System.Collections; 17 using System.Collections.Specialized; 18 using System.Configuration; 19 using System.Globalization; 20 using System.Text; 21 using System.Web.Hosting; 22 using System.Web.Util; 23 using System.Xml; 24 using System.Web.Compilation; 25 26 static internal class HandlerBase { 27 28 29 // 30 // XML Attribute Helpers 31 // 32 GetAndRemoveAttribute(XmlNode node, string attrib, bool fRequired)33 private static XmlNode GetAndRemoveAttribute(XmlNode node, string attrib, bool fRequired) { 34 XmlNode a = node.Attributes.RemoveNamedItem(attrib); 35 36 // If the attribute is required and was not present, throw 37 if (fRequired && a == null) { 38 throw new ConfigurationErrorsException( 39 SR.GetString(SR.Missing_required_attribute, attrib, node.Name), 40 node); 41 } 42 43 return a; 44 } 45 GetAndRemoveStringAttributeInternal(XmlNode node, string attrib, bool fRequired, ref string val)46 private static XmlNode GetAndRemoveStringAttributeInternal(XmlNode node, string attrib, bool fRequired, ref string val) { 47 XmlNode a = GetAndRemoveAttribute(node, attrib, fRequired); 48 if (a != null) { 49 val = a.Value; 50 } 51 52 return a; 53 } 54 GetAndRemoveStringAttribute(XmlNode node, string attrib, ref string val)55 internal static XmlNode GetAndRemoveStringAttribute(XmlNode node, string attrib, ref string val) { 56 return GetAndRemoveStringAttributeInternal(node, attrib, false /*fRequired*/, ref val); 57 } 58 GetAndRemoveRequiredStringAttribute(XmlNode node, string attrib, ref string val)59 internal static XmlNode GetAndRemoveRequiredStringAttribute(XmlNode node, string attrib, ref string val) { 60 return GetAndRemoveStringAttributeInternal(node, attrib, true /*fRequired*/, ref val); 61 } 62 GetAndRemoveNonEmptyStringAttribute(XmlNode node, string attrib, ref string val)63 internal static XmlNode GetAndRemoveNonEmptyStringAttribute(XmlNode node, string attrib, ref string val) { 64 return GetAndRemoveNonEmptyStringAttributeInternal(node, attrib, false /*fRequired*/, ref val); 65 } 66 GetAndRemoveRequiredNonEmptyStringAttribute(XmlNode node, string attrib, ref string val)67 internal static XmlNode GetAndRemoveRequiredNonEmptyStringAttribute(XmlNode node, string attrib, ref string val) { 68 return GetAndRemoveNonEmptyStringAttributeInternal(node, attrib, true /*fRequired*/, ref val); 69 } 70 GetAndRemoveNonEmptyStringAttributeInternal(XmlNode node, string attrib, bool fRequired, ref string val)71 private static XmlNode GetAndRemoveNonEmptyStringAttributeInternal(XmlNode node, string attrib, bool fRequired, ref string val) { 72 XmlNode a = GetAndRemoveStringAttributeInternal(node, attrib, fRequired, ref val); 73 if (a != null && val.Length == 0) { 74 throw new ConfigurationErrorsException( 75 SR.GetString(SR.Empty_attribute, attrib), 76 a); 77 } 78 79 return a; 80 } 81 82 // input.Xml cursor must be at a true/false XML attribute GetAndRemoveBooleanAttributeInternal(XmlNode node, string attrib, bool fRequired, ref bool val)83 private static XmlNode GetAndRemoveBooleanAttributeInternal(XmlNode node, string attrib, bool fRequired, ref bool val) { 84 XmlNode a = GetAndRemoveAttribute(node, attrib, fRequired); 85 if (a != null) { 86 if (a.Value == "true") { 87 val = true; 88 } 89 else if (a.Value == "false") { 90 val = false; 91 } 92 else { 93 throw new ConfigurationErrorsException( 94 SR.GetString(SR.Invalid_boolean_attribute, a.Name), 95 a); 96 } 97 } 98 99 return a; 100 } 101 GetAndRemoveBooleanAttribute(XmlNode node, string attrib, ref bool val)102 internal static XmlNode GetAndRemoveBooleanAttribute(XmlNode node, string attrib, ref bool val) { 103 return GetAndRemoveBooleanAttributeInternal(node, attrib, false /*fRequired*/, ref val); 104 } 105 GetAndRemoveIntegerAttributeInternal(XmlNode node, string attrib, bool fRequired, ref int val)106 private static XmlNode GetAndRemoveIntegerAttributeInternal(XmlNode node, string attrib, bool fRequired, ref int val) { 107 XmlNode a = GetAndRemoveAttribute(node, attrib, fRequired); 108 if (a != null) { 109 if (a.Value.Trim() != a.Value) { 110 throw new ConfigurationErrorsException( 111 SR.GetString(SR.Invalid_integer_attribute, a.Name), 112 a); 113 } 114 115 try { 116 val = int.Parse(a.Value, CultureInfo.InvariantCulture); 117 } 118 catch (Exception e) { 119 throw new ConfigurationErrorsException( 120 SR.GetString(SR.Invalid_integer_attribute, a.Name), 121 e, a); 122 } 123 } 124 125 return a; 126 } 127 GetAndRemovePositiveAttributeInternal(XmlNode node, string attrib, bool fRequired, ref int val)128 private static XmlNode GetAndRemovePositiveAttributeInternal(XmlNode node, string attrib, bool fRequired, ref int val) { 129 XmlNode a = GetAndRemoveIntegerAttributeInternal(node, attrib, fRequired, ref val); 130 131 if (a != null && val <= 0) { 132 throw new ConfigurationErrorsException( 133 SR.GetString(SR.Invalid_positive_integer_attribute, attrib), 134 a); 135 } 136 137 return a; 138 } 139 140 GetAndRemovePositiveIntegerAttribute(XmlNode node, string attrib, ref int val)141 internal static XmlNode GetAndRemovePositiveIntegerAttribute(XmlNode node, string attrib, ref int val) { 142 return GetAndRemovePositiveAttributeInternal(node, attrib, false /*fRequired*/, ref val); 143 } 144 145 GetAndRemoveTypeAttributeInternal(XmlNode node, string attrib, bool fRequired, ref Type val)146 private static XmlNode GetAndRemoveTypeAttributeInternal(XmlNode node, string attrib, bool fRequired, ref Type val) { 147 XmlNode a = GetAndRemoveAttribute(node, attrib, fRequired); 148 149 if (a != null) { 150 val = ConfigUtil.GetType(a.Value, a); 151 } 152 153 return a; 154 } 155 GetAndRemoveTypeAttribute(XmlNode node, string attrib, ref Type val)156 internal static XmlNode GetAndRemoveTypeAttribute(XmlNode node, string attrib, ref Type val) { 157 return GetAndRemoveTypeAttributeInternal(node, attrib, false /*fRequired*/, ref val); 158 } 159 CheckForbiddenAttribute(XmlNode node, string attrib)160 internal static void CheckForbiddenAttribute(XmlNode node, string attrib) { 161 XmlAttribute attr = node.Attributes[attrib]; 162 if (attr != null) { 163 throw new ConfigurationErrorsException( 164 SR.GetString(SR.Config_base_unrecognized_attribute, attrib), 165 attr); 166 } 167 } 168 CheckForUnrecognizedAttributes(XmlNode node)169 internal static void CheckForUnrecognizedAttributes(XmlNode node) { 170 if (node.Attributes.Count != 0) { 171 throw new ConfigurationErrorsException( 172 SR.GetString(SR.Config_base_unrecognized_attribute, node.Attributes[0].Name), 173 node.Attributes[0]); 174 } 175 } 176 177 178 // 179 // Obsolete XML Attribute Helpers 180 // 181 182 // if attribute not found return null RemoveAttribute(XmlNode node, string name)183 internal static string RemoveAttribute(XmlNode node, string name) { 184 185 XmlNode attribute = node.Attributes.RemoveNamedItem(name); 186 187 if (attribute != null) { 188 return attribute.Value; 189 } 190 191 return null; 192 } 193 194 // if attr not found throw standard message - "attribute x required" RemoveRequiredAttribute(XmlNode node, string name)195 internal static string RemoveRequiredAttribute(XmlNode node, string name) { 196 return RemoveRequiredAttribute(node, name, false); 197 } 198 RemoveRequiredAttribute(XmlNode node, string name, bool allowEmpty)199 internal static string RemoveRequiredAttribute(XmlNode node, string name, bool allowEmpty) { 200 XmlNode attribute = node.Attributes.RemoveNamedItem(name); 201 202 if (attribute == null) { 203 throw new ConfigurationErrorsException( 204 SR.GetString(SR.Config_base_required_attribute_missing, name), 205 node); 206 } 207 208 if (attribute.Value.Length == 0 && !allowEmpty) { 209 throw new ConfigurationErrorsException( 210 SR.GetString(SR.Config_base_required_attribute_empty, name), 211 node); 212 } 213 214 return attribute.Value; 215 } 216 217 218 219 // 220 // XML Element Helpers 221 // 222 223 CheckForNonCommentChildNodes(XmlNode node)224 internal static void CheckForNonCommentChildNodes(XmlNode node) { 225 foreach (XmlNode childNode in node.ChildNodes) { 226 if (childNode.NodeType != XmlNodeType.Comment) { 227 throw new ConfigurationErrorsException( 228 SR.GetString(SR.Config_base_no_child_nodes), 229 childNode); 230 } 231 } 232 } 233 ThrowUnrecognizedElement(XmlNode node)234 internal static void ThrowUnrecognizedElement(XmlNode node) { 235 throw new ConfigurationErrorsException( 236 SR.GetString(SR.Config_base_unrecognized_element), 237 node); 238 } 239 240 CheckAssignableType(XmlNode node, Type baseType, Type type)241 internal static void CheckAssignableType(XmlNode node, Type baseType, Type type) { 242 if (!baseType.IsAssignableFrom(type)) { 243 throw new ConfigurationErrorsException( 244 SR.GetString(SR.Type_doesnt_inherit_from_type, type.FullName, baseType.FullName), 245 node); 246 } 247 } 248 CheckAssignableType(string filename, int lineNumber, Type baseType, Type type)249 internal static void CheckAssignableType(string filename, int lineNumber, Type baseType, Type type) { 250 if (!baseType.IsAssignableFrom(type)) { 251 throw new ConfigurationErrorsException( 252 SR.GetString(SR.Type_doesnt_inherit_from_type, type.FullName, baseType.FullName), 253 filename, lineNumber); 254 } 255 } 256 257 // Section handlers can run in client mode through: 258 // ConfigurationManager.GetSection("sectionName") 259 // See ASURT 123738 IsServerConfiguration(object context)260 internal static bool IsServerConfiguration(object context) { 261 return context is HttpConfigurationContext; 262 } 263 CheckAndReadRegistryValue(ref string value, bool throwIfError)264 internal static bool CheckAndReadRegistryValue(ref string value, bool throwIfError) { 265 if (value == null) { 266 return true; 267 } 268 269 if (!StringUtil.StringStartsWithIgnoreCase(value, "registry:")) { 270 // Not a registry value. It's not an error. 271 return true; 272 } 273 274 const int size = 1024; 275 StringBuilder str = new StringBuilder(size); 276 int iRet = UnsafeNativeMethods.GetCredentialFromRegistry(value, str, size); 277 if (iRet == 0) { 278 value = str.ToString(); 279 return true; 280 } 281 else { 282 if (throwIfError) { 283 throw new ConfigurationErrorsException( 284 SR.GetString(SR.Invalid_registry_config)); 285 } 286 else { 287 return false; 288 } 289 } 290 } 291 CheckAndReadConnectionString(ref string connectionString, bool throwIfError)292 internal static bool CheckAndReadConnectionString(ref string connectionString, bool throwIfError) { 293 ConnectionStringSettings connObj = RuntimeConfig.GetConfig().ConnectionStrings.ConnectionStrings[connectionString]; 294 if (connObj != null && connObj.ConnectionString != null && connObj.ConnectionString.Length > 0) 295 connectionString = connObj.ConnectionString; 296 297 return CheckAndReadRegistryValue(ref connectionString, throwIfError); 298 } 299 } 300 } 301