仅在某些机器上的 CustomSettingProvider 中的 null 引用 [英] null reference in CustomSettingProvider only on some machines

查看:28
本文介绍了仅在某些机器上的 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 引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆