У нас есть веб-приложение ASP.Net, работающее на IIS7, взаимодействующее с веб-службой WCF, которая обрабатывает запросы, поступающие из этого веб-приложения.
После некоторого времени работы (это может быть неделя или несколько дней) веб-сервису WCF не удается прочитать настройки в своем файле 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...
}
Доступ к экземпляру пользовательских настроек теперь реализован в верхнем родительском классе Запрос , как показано ниже:
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, но и для других параметров в файле web.config службы WCF.
Непонятно, в чем причина такой проблемы, она не воспроизводима постоянно и стабильно. Кажется, это не зависит напрямую от нагрузки / количества пользователей / открытых сеансов. Иногда сайт работает без сбоев в течение нескольких недель, затем проблема возникает один раз в неделю, а затем - несколько дней подряд. Возможно, это связано с переработкой какого-то рабочего процесса в пуле приложений.
Раньше мы сталкивались с этим в Windows Server 2003 (IIS 6.0), а теперь получаем его в Windows Server 2008 с IIS 7.0, так что, похоже, он не имеет прямого отношения к версии IIS.
Я подозреваю, что может быть проблема с общим доступом к экземпляру класса CustomSettings через только для чтения статический член Request для всех дочерних классов, который инициализируется только один раз.
Любая помощь / предложение будет принята с благодарностью.