本文介绍了仅在某些机器上的 CustomSettingProvider 中的 null 引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using the CustomSettingProvider as can be found here : http://www.codeproject.com/KB/vb/CustomSettingsProvider.aspx

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

On some machines, a null reference exception is thrown :

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 方法..

cx.a() is either the getvalue or setvalue method ..

有什么想法吗?

......... 编辑 .....

........... EDIT ...............................

此 GetValue 方法返回 XPathException:执行时表达式必须计算为节点集(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;
    }

}

推荐答案

问题原因:

一些机器名称以数字开头.IE.965GDF5".不过,XML 标签不能以数字开头,因此会出现所有错误.

some machine names start with numbers. ie. "965GDF5". XML Tags cannot start with numbers though, hence all the errors.

这篇关于仅在某些机器上的 CustomSettingProvider 中的 null 引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-25 10:08