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

时间:2010-12-17 14:51:55

标签: c# .net windows

我正在使用CustomSettingProvider,可在此处找到:http://www.codeproject.com/KB/vb/CustomSettingsProvider.aspx

在某些机器上,抛出了一个空引用异常:

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;
    }

}

2 个答案:

答案 0 :(得分:2)

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

这会让你感到困难,因为你吞咽了这个问题的可能原因。

你应该删除它们,然后看看抛出的异常是什么。只有在异常情况下才能捕获异常,您可以实际执行某些操作(将空值转换为默认值)。即便如此,它应该是特定的异常,而不是System.Exception

答案 1 :(得分:2)

问题的原因:

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