经过一段时间的工作,IIS / ASP.Net无法从WCF Web服务的web.config文件中读取设置

我们在IIS7上运行一个ASP.Net Web应用程序,与WCF Web服务进行通信,该服务处理来自此Web应用程序的请求.

经过一段时间的工作(可能是一周或几天),WCF Web服务开始无法读取其web.config文件中的设置,记录了以下异常:

System.NullReferenceException

ABC.Communication.DataContract.RefreshRequest System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Xml.XmlNode.RemoveChild(XmlNode oldChild)
   at System.Xml.XmlNode.RemoveAll()
   at System.Xml.XmlElement.set_InnerXml(String value)
   at System.Configuration.LocalFileSettingsProvider.XmlEscaper.Unescape(String escapedString)
   at System.Configuration.LocalFileSettingsProvider.GetPropertyValues(SettingsContext context, SettingsPropertyCollection properties)
   at System.Configuration.SettingsBase.GetPropertiesFromProvider(SettingsProvider provider)
   at System.Configuration.SettingsBase.GetPropertyValueByName(String propertyName)
   at System.Configuration.SettingsBase.get_Item(String propertyName)
   at System.Configuration.ApplicationSettingsBase.GetPropertyValue(String propertyName)
   at System.Configuration.ApplicationSettingsBase.get_Item(String propertyName)
   at ABC.Communication.DataContract.Request.ValidateIpAddress() in C:\Project\ABC.Server\ABC.Communication\DataContract\Request.Validation.cs:line 955
   at ABC.Communication.DataContract.RefreshRequestBase.Validate() in C:\Project\ABC.Server\ABC.Communication\DataContract\RefreshRequestBase.cs:line 46
   at ABC.Communication.DataContract.RefreshRequest.Validate() in C:\Project\ABC.Server\ABC.Communication\DataContract\RefreshRequest.cs:line 30
   at ABC.Communication.ClientCommunicationService.HandleRequest(Request request) in C:\Project\ABC.Server\ABC.Communication\ClientCommunicationService.cs:line 116

或System.ArgumentException

ABC.Communication.DataContract.RefreshRequest System.ArgumentException: The node to be removed is not a child of this node.
   at System.Xml.XmlNode.RemoveChild(XmlNode oldChild)
   at System.Xml.XmlNode.RemoveAll()
   at System.Xml.XmlElement.set_InnerXml(String value)
   at System.Configuration.LocalFileSettingsProvider.XmlEscaper.Unescape(String escapedString)
   at System.Configuration.LocalFileSettingsProvider.GetPropertyValues(SettingsContext context, SettingsPropertyCollection properties)
   at System.Configuration.SettingsBase.GetPropertiesFromProvider(SettingsProvider provider)
   at System.Configuration.SettingsBase.GetPropertyValueByName(String propertyName)
   at System.Configuration.SettingsBase.get_Item(String propertyName)
   at System.Configuration.ApplicationSettingsBase.GetPropertyValue(String propertyName)
   at System.Configuration.ApplicationSettingsBase.get_Item(String propertyName)
   at ABC.Communication.DataContract.Request.ValidateIpAddress() in C:\Project\ABC.Server\ABC.Communication\DataContract\Request.Validation.cs:line 955
   at ABC.Communication.DataContract.RefreshRequestBase.Validate() in C:\Project\ABC.Server\ABC.Communication\DataContract\RefreshRequestBase.cs:line 46
   at ABC.Communication.DataContract.DataContracts.RefreshRequest.Validate() in C:\Project\ABC.Server\ABC.Communication\DataContract\RefreshRequest.cs:line 30
   at ABC.Communication.ClientCommunicationService.HandleRequest(Request request) in C:\Project\ABC.Server\ABC.Communication\ClientCommunicationService.cs:line 116

或System.Configuration.SettingsPropertyNotFoundException:

ABC.Communication.DataContract.RefreshRequest System.Configuration.SettingsPropertyNotFoundException: The settings property 'ValidateIpConnections' was not found.
   at System.Configuration.SettingsBase.GetPropertyValueByName(String propertyName)
   at System.Configuration.SettingsBase.get_Item(String propertyName)
   at System.Configuration.ApplicationSettingsBase.GetPropertyValue(String propertyName)
   at System.Configuration.ApplicationSettingsBase.get_Item(String propertyName)
   at ABC.Communication.DataContract.Request.ValidateIpAddress() in C:\Project\ABC.Server\ABC.Communication\DataContract\Request.Validation.cs:line 955
   at ABC.Communication.DataContract.RefreshRequestBase.Validate() in C:\Project\ABC.Server\ABC.Communication\DataContract\RefreshRequestBase.cs:line 46
   at ABC.Communication.DataContract.RefreshRequest.Validate() in C:\Project\ABC.Server\ABC.Communication\DataContract\RefreshRequest.cs:line 30
   at ABC.Communication.ClientCommunicationService.HandleRequest(Request request) in C:\Project\ABC.Server\ABC.Communication\ClientCommunicationService.cs:line 116

抛出此异常的代码非常简单:

private void ValidateIpAddress() {
    // Load custom settings
    CustomSettings settings = GetCustomSettings();

    if (!settings.ValidateIpConnections)   // here the exception is thrown!
        return;

    // the rest of code never reached...
}

现在,在顶级父类Request中实现对自定义设置实例的访问,如下所示:

public abstract partial class Request
{
    /// <summary>
    /// Custom settings.
    /// </summary>
    private static readonly CustomSettings customSettings;

    /// <summary>
    /// .cctor().
    /// </summary>
    static Request()
    {
        customSettings = new CustomSettings();
    }

    /// <summary>
    /// Get custom settings.
    /// </summary>
    /// <returns>Custom settings.</returns>
    internal static CustomSettings GetCustomSettings()
    {
        return customSettings;
    }

    // ....
}

问题不仅发生在此特定设置ValidateIpConnections,还发生在WCF服务的web.config文件中的其他设置.

目前尚不清楚这种问题的原因是什么,它不能经常和稳定地再现.它似乎并不直接取决于负载/用户数/开放会话数.有时网站运行平稳数周,然后问题每周发生一次,然后连续几天发生.可能,它与应用程序池中的某些工作进程的回收有关.

我们曾经在Windows Server 2003(IIS 6.0)上遇到过它,现在可以在带有IIS 7.0的Windows Server 2008上使用它,因此它似乎与IIS的版本没有直接关系.

我怀疑通过只有初始化一次的所有子类的Request的readonly静态成员共享对CustomSettings类实例的访问可能存在问题.

任何帮助/建议将不胜感激.

最佳答案 我认为您可以避免使用自定义设置类,因为web.config在第一次访问时被缓存.看到

ASP.NET: Where/how is web.config cached?

因此,没有必要进行自己的缓存,然后你可以排除这一点.

我们在其中一台生产服务器上遇到了类似的问题,结果发现病毒扫描程序正在扫描web.config文件,导致应用程序池回收.

我会推荐

>删除静态类并直接使用.net配置类
>调整病毒扫描程序,使其不扫描应用程序所在的文件夹
>在异常发生的时候查看事件日志,看看是否还有其他奇怪的事情发生
>设置asp.net监控(ASP.NET计数器>应用程序重启):http://msdn.microsoft.com/en-us/library/ms972959.aspxhttp://blogs.msdn.com/b/johan/archive/2008/02/18/monitoring-application-pool-and-application-restarts.aspx

点赞