C# 如何将自定义对象的集合存储到user.config文件中?

C# 如何将自定义对象的集合存储到user.config文件中?,c#,configuration,collections,app-config,C#,Configuration,Collections,App Config,我希望将自定义对象的集合存储在user.config文件中,并希望以编程方式从集合中添加和删除项,然后将修改后的列表保存回配置文件 我的项目采用以下简单形式: class UserInfo { public string FirstName { get; set; } public string LastName { get; set; } public string Email { get; set; } } 在我的app.config中,我已经创建了

我希望将自定义对象的集合存储在user.config文件中,并希望以编程方式从集合中添加和删除项,然后将修改后的列表保存回配置文件

我的项目采用以下简单形式:

class UserInfo
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }        
}
在我的app.config中,我已经创建了一个自定义节:

<configuration>
  <configSections>
    <section name="userInfo" type="UserInfoConfigurationHandler, MyProgram"/>

  </configSections>
  <userInfo>
    <User firstName="John" lastName="Doe" email="john@example.com" />
    <User firstName="Jane" lastName="Doe" email="jane@example.com" />
  </userInfo>

</configuration>
这一切都是我做的。但是,使用这种方法,我只能将app.config中的设置读入
列表
集合,但我还需要写回修改后的列表


我搜索文档时没有成功,现在我有点卡住了。我遗漏了什么?

我不会将此类数据存储在app.config中,至少如果它是以编程方式更新的话。从概念上讲,它用于配置设置,而不是应用程序数据,因此您可能希望将用户名和密码信息存储在单独的XML文件中(假设您不能或不想使用数据库)


话虽如此,我认为最好的办法是将app.config作为标准XML文件读入,对其进行解析,添加所需的节点并将其写回。内置的ConfigurationManager API不提供写回新设置的方法(我想这会提示Microsoft的预期用途)

从.Net Framework2使用新的系统配置API。 (程序集:System.Configuration)IConfigurationSectionHandler已过时

你可以在网站上找到很多非常好的样品和说明

还有一个代码示例,介绍如何修改和保存值


编辑:codeproject中文档的相关部分

如果存在任何更改,则仅保存修改后的值

Configuration.Save() 
Configuration.Save(ConfigurationSaveMode) 
保存指定级别的更改(如果存在任何更改)

Configuration.Save() 
Configuration.Save(ConfigurationSaveMode) 
保存指定级别的更改,如果第二个参数为true,则强制执行保存

Configuration.Save(ConfigurationSaveMode, bool)
ConfigurationSaveMode枚举具有以下值:

  • Full-保存所有配置属性,无论它们是否已更改
  • Modified-保存已修改的属性,即使当前值与原始值相同
  • 最小值-仅保存已修改且值与原始值不同的属性

您应该创建一个类,如:

public class MySettings : ConfigurationSection 
{
    public MySettings Settings = (MySettings)WebConfigurationManager.GetSection("MySettings");

    [ConfigurationProperty("MyConfigSetting1")]
    public string DefaultConnectionStringName
    {
        get { return (string)base["MyConfigSetting1"]; }
        set { base["MyConfigSetting1"] = value; }
    }
}
之后,在web.config中使用:

<section name="MySettings" type="MyNamespace.MySettings"/>
<MySettings MyConfigSetting1="myValue">

就是这样)
如果您不想使用attibutes,而想使用properties,只需创建从ConfigurationElement派生的类,并将其包含到您的ConfigurationSettings定义的类中。

添加自定义配置(如果您需要的不仅仅是简单类型)的方法是使用ConfigurationSection,在您定义的架构中,您需要一个ConfigurationElementCollection(设置为默认集合,没有名称),其中包含一个ConfigurationElement,如下所示:

public class UserElement : ConfigurationElement
{
    [ConfigurationProperty( "firstName", IsRequired = true )]
    public string FirstName
    {
        get { return (string) base[ "firstName" ]; }
        set { base[ "firstName" ] = value;}
    }

    [ConfigurationProperty( "lastName", IsRequired = true )]
    public string LastName
    {
        get { return (string) base[ "lastName" ]; }
        set { base[ "lastName" ] = value; }
    }

    [ConfigurationProperty( "email", IsRequired = true )]
    public string Email
    {
        get { return (string) base[ "email" ]; }
        set { base[ "email" ] = value; }
    }

    internal string Key
    {
        get { return string.Format( "{0}|{1}|{2}", FirstName, LastName, Email ); }
    }
}

[ConfigurationCollection( typeof(UserElement), AddItemName = "user", CollectionType = ConfigurationElementCollectionType.BasicMap )]
public class UserElementCollection : ConfigurationElementCollection
{
    protected override ConfigurationElement CreateNewElement()
    {
        return new UserElement();
    }

    protected override object GetElementKey( ConfigurationElement element )
    {
        return ( (UserElement) element ).Key;
    }

    public void Add( UserElement element )
    {
        BaseAdd( element );
    }

    public void Clear()
    {
        BaseClear();
    }

    public int IndexOf( UserElement element )
    {
        return BaseIndexOf( element );
    }

    public void Remove( UserElement element )
    {
        if( BaseIndexOf( element ) >= 0 )
        {
            BaseRemove( element.Key );
        }
    }

    public void RemoveAt( int index )
    {
        BaseRemoveAt( index );
    }

    public UserElement this[ int index ]
    {
        get { return (UserElement) BaseGet( index ); }
        set
        {
            if( BaseGet( index ) != null )
            {
                BaseRemoveAt( index );
            }
            BaseAdd( index, value );
        }
    }
}

public class UserInfoSection : ConfigurationSection
{
    private static readonly ConfigurationProperty _propUserInfo = new ConfigurationProperty(
            null,
            typeof(UserElementCollection),
            null,
            ConfigurationPropertyOptions.IsDefaultCollection
    );

    private static ConfigurationPropertyCollection _properties = new ConfigurationPropertyCollection();

    static UserInfoSection()
    {
        _properties.Add( _propUserInfo );
    }

    [ConfigurationProperty( "", Options = ConfigurationPropertyOptions.IsDefaultCollection )]
    public UserElementCollection Users
    {
        get { return (UserElementCollection) base[ _propUserInfo ]; }
    }
}
我保持了UserElement类的简单性,尽管它实际上应该遵循中描述的完全声明每个属性的模式。正如您所见,它表示您提供的配置中的“用户”元素

UserElementCollection类只支持拥有多个“user”元素,包括在运行时修改集合时从集合中添加/删除/清除项的功能

最后是UserInfoSection,它只是统计它有一个默认的“用户”元素集合

接下来是App.config文件的示例:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup>
      <section
        name="userInfo"
        type="ConsoleApplication1.UserInfoSection, ConsoleApplication1"
        allowDefinition="Everywhere"
        allowExeDefinition="MachineToLocalUser"
      />
    </sectionGroup>
  </configSections>

  <userInfo>
    <user firstName="John" lastName="Doe" email="John.Doe@company.com" />
    <user firstName="Jane" lastName="Doe" email="Jane.Doe@company.com" />
  </userInfo>
</configuration>
如果需要,上面的代码将创建一个新的user.config文件,该文件将被深埋在用户的“Local Settings\Application Data”文件夹中

如果您希望将新用户添加到app.config文件中,只需将OpenExeConfiguration()方法的参数更改为ConfigurationUserLevel.None

正如您所见,它相当简单,尽管查找此信息需要一些挖掘。

private void frmLocalFileTransfer\u Load(对象发送方,事件参数e)
 private void frmLocalFileTransfer_Load(object sender, EventArgs e)
    {
        try
        {
            dt.Columns.Add("Provider");
            dt.Columns.Add("DestinationPath");
            string[] folders = null;
            dt.Columns.Add("SourcePath");

            for (int i = 1; i < System.Configuration.ConfigurationManager.ConnectionStrings.Count; i++)
            {
                string key = System.Configuration.ConfigurationManager.ConnectionStrings[i].Name;
                string constr = System.Configuration.ConfigurationManager.ConnectionStrings[i].ConnectionString;
                DataGridViewTextBoxColumn column = new DataGridViewTextBoxColumn();
                folders = constr.Split('\\');
                string newstr = (folders[folders.Length - 2]);
                if (!newstr.Contains("BackUp"))
                {
                    DataRow row = dt.NewRow();
                    row[dt.Columns[0].ToString()] = key;
                    row[dt.Columns[1].ToString()] = constr;
                    row[dt.Columns[2].ToString()] = constr;
                    dt.Rows.InsertAt(row, i - 1);
                }
            }

            foreach (DataColumn dc in dt.Columns)
            {
                DataGridViewTextBoxColumn column = new DataGridViewTextBoxColumn();
                column.DataPropertyName = dc.ColumnName;
                column.HeaderText = dc.ColumnName;
                column.Name = dc.ColumnName;
                column.SortMode = DataGridViewColumnSortMode.Automatic;
                column.ValueType = dc.DataType;
                GVCheckbox();

                gevsearch.Columns.Add(column);
            }
            if (gevsearch.ColumnCount == 4)
            {
                DataGridViewButtonColumn btnColoumn = new DataGridViewButtonColumn();
                btnColoumn.Width = 150;
                btnColoumn.HeaderText = "Change SourcePath";
                btnColoumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
                gevsearch.Columns.Insert(4, btnColoumn);


            }
             gevsearch.DataSource = dt;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
    }

private void btnAddProvider_Click(object sender, EventArgs e)
    {
        try
        {
            System.Xml.XmlDocument xDoc = new System.Xml.XmlDocument();
            path = "D:\\Pandurang\\Jitendra\\LocalFileTransfer\\LocalFileTransfer
            xDoc.Load(path);
            System.Xml.XmlElement element = xDoc.CreateElement("add");
            element.SetAttribute("name", txtProviderName.Text.Trim());
            element.SetAttribute("connectionString", txtNewPath.Text.Trim());
            System.Xml.XmlElement elementBackup = xDoc.CreateElement("add");
            elementBackup.SetAttribute("name", BackUpName);
            elementBackup.SetAttribute("connectionString", txtBackupPath.Text.Trim());
            System.Xml.XmlNode node= xDoc.ChildNodes[1].ChildNodes[0];
            node.AppendChild(element);
            node.AppendChild(elementBackup);
            xDoc.Save(path);
          }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
    }
{ 尝试 { dt.列。添加(“提供方”); dt.Columns.Add(“DestinationPath”); 字符串[]文件夹=null; 添加(“源路径”); 对于(int i=1;i