CustomSettingProvider中的空引用仅在某些机器上

我使用的CustomSettingProvider可以在这里find: http : //www.codeproject.com/KB/vb/CustomSettingsProvider.aspx

在某些机器上,会引发空引用exception:

System.NullReferenceException: . bij cx.a(SettingsPropertyValue A_0) bij cx.a(SettingsContext A_0, SettingsPropertyValueCollection A_1) bij System.Configuration.SettingsBase.SaveCore() bij System.Configuration.SettingsBase.Save() bij System.Configuration.ApplicationSettingsBase.Save() 

cx.a()是getvalue或setvalue方法..

有任何想法吗 ?

………..编辑………………………….

此GetValue方法返回XPathException:expression式在执行时必须计算为节点集(SelectSingleNode方法)

  private string GetValue(SettingsProperty setting) { string ret = ""; if (setting == null) return ""; try { //Try to read setting ?? XmlNode foundNode = null; string nodeSelectStr = SETTINGSROOT + "/" + SystemInformation.ComputerName + "/" + setting.Name; if (IsRoaming(setting)) { nodeSelectStr = SETTINGSROOT + "/" + setting.Name; } foundNode = SettingsXML.SelectSingleNode(nodeSelectStr); if (foundNode != null) { ret = foundNode.InnerText; } else //Not found .. ? { if ((setting.DefaultValue != null)) { ret = setting.DefaultValue.ToString(); } else { ret = ""; } } } catch (Exception exc) { Errors.CatchError("ErrorHintObjectOrAction", exc); } return ret; } public class CustomSettingProvider : SettingsProvider { //XML Root Node const string SETTINGSROOT = "Settings"; public override void Initialize(string name, NameValueCollection col) { base.Initialize(this.ApplicationName, col); } public override string ApplicationName { get { if (Application.ProductName.Trim().Length > 0) { return Application.ProductName; } else { FileInfo fi = new FileInfo(Application.ExecutablePath); return fi.Name.Substring(0, fi.Name.Length - fi.Extension.Length); } } //Do nothing set { } } public virtual string GetAppSettingsPath() { return ApplicatiePaths.SettingsPath; //Used to determine where to store the settings //System.IO.FileInfo fi = new System.IO.FileInfo(Application.ExecutablePath); //return fi.DirectoryName; } public virtual string GetAppSettingsFilename() { //Used to determine the filename to store the settings return ApplicationName + ".settings"; } public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals) { //Iterate through the settings to be stored //Only dirty settings are included in propvals, and only ones relevant to this provider foreach (SettingsPropertyValue propval in propvals) { SetValue(propval); } try { SettingsXML.Save(Path.Combine(GetAppSettingsPath(), GetAppSettingsFilename())); } catch (Exception ex) { //Ignore if cant save, device been ejected } } public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection props) { //Create new collection of values SettingsPropertyValueCollection values = new SettingsPropertyValueCollection(); //Iterate through the settings to be retrieved foreach (SettingsProperty setting in props) { SettingsPropertyValue value = new SettingsPropertyValue(setting); value.IsDirty = false; value.SerializedValue = GetValue(setting); values.Add(value); } return values; } private XmlDocument m_SettingsXML = null; private XmlDocument SettingsXML { get { //If we dont hold an xml document, try opening one. //If it doesnt exist then create a new one ready. if (m_SettingsXML == null) { m_SettingsXML = new XmlDocument(); try { m_SettingsXML.Load(Path.Combine(GetAppSettingsPath(), GetAppSettingsFilename())); } catch (Exception ex) { //Create new document XmlDeclaration dec = m_SettingsXML.CreateXmlDeclaration("1.0", "utf-8", string.Empty); m_SettingsXML.AppendChild(dec); XmlNode nodeRoot = null; nodeRoot = m_SettingsXML.CreateNode(XmlNodeType.Element, SETTINGSROOT, ""); m_SettingsXML.AppendChild(nodeRoot); } } return m_SettingsXML; } } private string GetValue(SettingsProperty setting) { string ret = ""; //This method is throwing the null reference exception, //so 'setting' has got to be null ?? try { if (IsRoaming(setting)) { ret = SettingsXML.SelectSingleNode(SETTINGSROOT + "/" + setting.Name).InnerText; } else { ret = SettingsXML.SelectSingleNode(SETTINGSROOT + "/" + SystemInformation.ComputerName + "/" + setting.Name).InnerText; } } catch (Exception ex) { if ((setting.DefaultValue != null)) { ret = setting.DefaultValue.ToString(); } else { ret = ""; } } return ret; } private void SetValue(SettingsPropertyValue propVal) { XmlElement MachineNode = default(XmlElement); XmlElement SettingNode = default(XmlElement); //Determine if the setting is roaming. //If roaming then the value is stored as an element under the root //Otherwise it is stored under a machine name node try { if (IsRoaming(propVal.Property)) { SettingNode = (XmlElement)SettingsXML.SelectSingleNode(SETTINGSROOT + "/" + propVal.Name); } else { SettingNode = (XmlElement)SettingsXML.SelectSingleNode(SETTINGSROOT + "/" + SystemInformation.ComputerName + "/" + propVal.Name); } } catch (Exception ex) { SettingNode = null; } //Check to see if the node exists, if so then set its new value if ((SettingNode != null)) { SettingNode.InnerText = propVal.SerializedValue.ToString(); } else { if (IsRoaming(propVal.Property)) { //Store the value as an element of the Settings Root Node SettingNode = SettingsXML.CreateElement(propVal.Name); SettingNode.InnerText = propVal.SerializedValue.ToString(); SettingsXML.SelectSingleNode(SETTINGSROOT).AppendChild(SettingNode); } else { //Its machine specific, store as an element of the machine name node, //creating a new machine name node if one doesnt exist. try { MachineNode = (XmlElement)SettingsXML.SelectSingleNode(SETTINGSROOT + "/" + SystemInformation.ComputerName); } catch (Exception ex) { MachineNode = SettingsXML.CreateElement(SystemInformation.ComputerName); SettingsXML.SelectSingleNode(SETTINGSROOT).AppendChild(MachineNode); } if (MachineNode == null) { MachineNode = SettingsXML.CreateElement(SystemInformation.ComputerName); SettingsXML.SelectSingleNode(SETTINGSROOT).AppendChild(MachineNode); } SettingNode = SettingsXML.CreateElement(propVal.Name); SettingNode.InnerText = propVal.SerializedValue.ToString(); MachineNode.AppendChild(SettingNode); } } } private bool IsRoaming(SettingsProperty prop) { //Determine if the setting is marked as Roaming foreach (DictionaryEntry d in prop.Attributes) { Attribute a = (Attribute)d.Value; if (a is System.Configuration.SettingsManageabilityAttribute) { return true; } } return false; } } 

Solutions Collecting From Web of "CustomSettingProvider中的空引用仅在某些机器上"

我注意到你有几个catch (Exception ex)

这会让你很难,因为你吞下了问题的可能原因。

你可能应该删除它们,然后看看抛出的异常。 只有在发生异常时才能捕获异常,实际上可以做些什么(将空值转换为默认值)。 即使如此,它应该是一个特定的异常而不是System.Exception

问题的原因:

一些机器名称以数字开头。 即。 “965GDF5”。 XML标签不能以数字开头,因此所有的错误。