可怜的Config
前些天开发了一个用于web的组件,出于模拟和测试的考虑,将组件做成winform和web通用组件,在winform程序中程序运行良好,但放到web项目中就会出错,出错的地方是无法载入配置文件,Properties.Settings初始化就会出错。
百思不得其解中,认为是我的dll版本拷贝错误了,用Reflector打开出错的dll,看是不是什么版本或什么莫名的问题,看来dll非常正常,莫非是什么cache的问题?将所有相关dll更新之后发现程序依然不能工作,重启Visual Studio,好像不行,重启机器,还是不行。
事实上,一共写了几个dll,其他几个dll工作完全正常(至少表现上完全正常),OK,退回去,看看出错的地方,查看异常信息:"当前配置系统不支持用户范围的设置",查看调用堆栈
在 System.Configuration.LocalFileSettingsProvider.GetPropertyValues(SettingsContext context, SettingsPropertyCollection properties)
在 System.Configuration.SettingsBase.GetPropertiesFromProvider(SettingsProvider provider)
在 System.Configuration.SettingsBase.GetPropertyValueByName(String propertyName)
在 System.Configuration.SettingsBase.get_Item(String propertyName)
在 System.Configuration.ApplicationSettingsBase.GetPropertyValue(String propertyName)
在 System.Configuration.ApplicationSettingsBase.get_Item(String propertyName)
直接进入LocalFileSettingsProvider.GetPropertyValues看看,异常是这样抛出的,应该是使用了UserSetting的问题,回头看看dll的设置,出错的dll里面用到了User范围的Setting,未出错的dll里面用的Setting都是Application范围的。
Ok,好像事情就应该到此为止了,但好奇心驱使我继续跟下去看个究竟。
bool flag2 = this.IsUserSetting(property);
if (flag2 && !ConfigurationManagerInternalFactory.Instance.SupportsUserConfig)
{
throw new ConfigurationErrorsException(SR.GetString("UserSettingsNotSupported"));
}
跟踪ConfigurationManagerInternalFactory.Instance
发现Instance是这样被赋值的
if (s_instance == null)
{
s_instance = (IConfigurationManagerInternal) TypeUtil.CreateInstanceWithReflectionPermission("System.Configuration.Internal.ConfigurationManagerInternal, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
}
一路跟踪下去,跟踪到IinternalConfigSystem接口,该接口有一个SupportsUserConfig只读属性,查看实现该接口的类,有两个:
ClientConfigurationSystem
HttpConfigurationSystem
查看两个类的SupportsUserConfig属性:
ClientConfigurationSystem
bool IInternalConfigSystem.SupportsUserConfig
{
get
{
return true;
}
}
-------------------------
HttpConfigurationSystem
bool IInternalConfigSystem.SupportsUserConfig
{
get
{
return false;
}
}
Ok,真相大白,在Web程序里是无法使用User范围的Setting信息的,我只有将说要存到Setting的信息设置为Application范围。
结论:在开发组件的时候,我们经常需要配置一些信息,这些信息可以是Application范围的,也可以是User范围的,至于什么是Application范围的,什么是User范围的,可以看一下MSDN,当在Web项目中使用到的组件需要读取一些配置的时候,这些信息只能设置为Application范围的。