using System.Collections;
using System.Collections.Specialized;
using System.Reflection;
+using System.Web.Util;
using System.Xml;
using System.Configuration;
using System.Configuration.Internal;
{
#if !TARGET_J2EE
static IInternalConfigConfigurationFactory configFactory;
- static Hashtable configurations = new Hashtable ();
+ static Hashtable configurations = Hashtable.Synchronized (new Hashtable ());
+ static Hashtable sectionCache = new Hashtable (StringComparer.OrdinalIgnoreCase);
#else
+ const string AppSettingsKey = "WebConfigurationManager.AppSettings";
static internal IInternalConfigConfigurationFactory configFactory
{
get{
lock (AppDomain.CurrentDomain){
object initialized = AppDomain.CurrentDomain.GetData("WebConfigurationManager.configurations.initialized");
if (initialized == null){
- table = new Hashtable();
+ table = Hashtable.Synchronized (new Hashtable (StringComparer.OrdinalIgnoreCase));
configurations = table;
}
}
AppDomain.CurrentDomain.SetData("WebConfigurationManager.configurations.initialized", true);
}
}
+
+ static Hashtable sectionCache
+ {
+ get
+ {
+ Hashtable sectionCache = (Hashtable) AppDomain.CurrentDomain.GetData ("sectionCache");
+ if (sectionCache == null) {
+ sectionCache = new Hashtable (StringComparer.OrdinalIgnoreCase);
+ AppDomain.CurrentDomain.SetData ("sectionCache", sectionCache);
+ }
+ return sectionCache;
+ }
+ set
+ {
+ AppDomain.CurrentDomain.SetData ("sectionCache", value);
+ }
+ }
#endif
- static internal ArrayList extra_assemblies = null;
+ static ArrayList extra_assemblies = null;
static internal ArrayList ExtraAssemblies {
get {
if (extra_assemblies == null)
return extra_assemblies;
}
}
+
+ static bool hasConfigErrors = false;
+ static object hasConfigErrorsLock = new object ();
+ static internal bool HasConfigErrors {
+ get {
+ lock (hasConfigErrorsLock) {
+ return hasConfigErrors;
+ }
+ }
+ }
static WebConfigurationManager ()
{
return ConfigurationManager.OpenMachineConfiguration ();
}
- [MonoTODO ("need to handle locationSubPath")]
+ [MonoLimitation ("locationSubPath is not handled")]
public static _Configuration OpenMachineConfiguration (string locationSubPath)
{
return OpenMachineConfiguration ();
}
- [MonoTODO("Mono does not support remote configuration")]
+ [MonoLimitation("Mono does not support remote configuration")]
public static _Configuration OpenMachineConfiguration (string locationSubPath,
string server)
{
throw new NotSupportedException ("Mono doesn't support remote configuration");
}
- [MonoTODO("Mono does not support remote configuration")]
+ [MonoLimitation("Mono does not support remote configuration")]
public static _Configuration OpenMachineConfiguration (string locationSubPath,
string server,
IntPtr userToken)
throw new NotSupportedException ("Mono doesn't support remote configuration");
}
- [MonoTODO("Mono does not support remote configuration")]
+ [MonoLimitation("Mono does not support remote configuration")]
public static _Configuration OpenMachineConfiguration (string locationSubPath,
string server,
string userName,
conf = (_Configuration) configurations [path];
if (conf == null) {
- lock (configurations) {
- conf = (_Configuration) configurations [path];
- if (conf == null) {
- conf = ConfigurationFactory.Create (typeof (WebConfigurationHost), null, path, site, locationSubPath, server, userName, password);
- configurations [path] = conf;
+ try {
+ conf = ConfigurationFactory.Create (typeof (WebConfigurationHost), null, path, site, locationSubPath, server, userName, password);
+ configurations [path] = conf;
+ } catch (Exception ex) {
+ lock (hasConfigErrorsLock) {
+ hasConfigErrors = true;
}
+ throw ex;
}
}
return conf;
return OpenMappedMachineConfiguration (fileMap);
}
- public static object GetSection (string sectionName)
+ internal static object SafeGetSection (string sectionName, Type configSectionType)
+ {
+ try {
+ return GetSection (sectionName);
+ } catch (Exception) {
+ if (configSectionType != null)
+ return Activator.CreateInstance (configSectionType);
+ return null;
+ }
+ }
+
+ internal static object SafeGetSection (string sectionName, string path, Type configSectionType)
{
- string path = (HttpContext.Current != null
- && HttpContext.Current.Request != null) ?
- HttpContext.Current.Request.Path : HttpRuntime.AppDomainAppVirtualPath;
+ try {
+ return GetSection (sectionName, path);
+ } catch (Exception) {
+ if (configSectionType != null)
+ return Activator.CreateInstance (configSectionType);
+ return null;
+ }
+ }
- return GetSection (sectionName, path);
+ public static object GetSection (string sectionName)
+ {
+ return GetSection (sectionName, GetCurrentPath (HttpContext.Current));
}
public static object GetSection (string sectionName, string path)
{
+ object cachedSection = sectionCache [GetSectionCacheKey (sectionName, path)];
+ if (cachedSection != null)
+ return cachedSection;
+
_Configuration c = OpenWebConfiguration (path);
ConfigurationSection section = c.GetSection (sectionName);
if (section == null)
return null;
- return get_runtime_object.Invoke (section, new object [0]);
+#if TARGET_J2EE
+ object value = get_runtime_object.Invoke (section, new object [0]);
+ if (String.CompareOrdinal ("appSettings", sectionName) == 0) {
+ NameValueCollection collection;
+ collection = new KeyValueMergedCollection (HttpContext.Current, (NameValueCollection) value);
+ value = collection;
+ }
+
+ AddSectionToCache (GetSectionCacheKey (sectionName, path), value);
+ return value;
+#else
+ object value = SettingsMappingManager.MapSection (get_runtime_object.Invoke (section, new object [0]));
+ AddSectionToCache (GetSectionCacheKey (sectionName, path), value);
+ return value;
+#endif
+ }
+
+ static string GetCurrentPath (HttpContext ctx)
+ {
+ return (ctx != null && ctx.Request != null) ? ctx.Request.Path : HttpRuntime.AppDomainAppVirtualPath;
+ }
+
+ internal static void RemoveConfigurationFromCache (HttpContext ctx)
+ {
+ configurations.Remove (GetCurrentPath (ctx));
}
readonly static MethodInfo get_runtime_object = typeof (ConfigurationSection).GetMethod ("GetRuntimeObject", BindingFlags.NonPublic | BindingFlags.Instance);
internal static IInternalConfigConfigurationFactory ConfigurationFactory {
get { return configFactory; }
}
+
+ static void AddSectionToCache (string key, object section)
+ {
+ if (sectionCache [key] != null)
+ return;
+
+ Hashtable tmpTable = (Hashtable) sectionCache.Clone ();
+ if (tmpTable.Contains (key))
+ return;
+
+ tmpTable.Add (key, section);
+ sectionCache = tmpTable;
+ }
+
+ static string GetSectionCacheKey (string sectionName, string path)
+ {
+ return string.Concat (path, "/", sectionName);
+ }
+
#region stuff copied from WebConfigurationSettings
#if TARGET_J2EE