manager - read keys from app config c#
¿Cómo almacenar una colección de objetos personalizados en un archivo user.config? (5)
La forma de agregar configuraciones personalizadas (si requiere más que tipos simples) es usar una Sección de configuración, dentro de eso, para el esquema que definió, necesita una ConfigurationElementCollection (establecida como colección predeterminada sin nombre), que contiene un ConfigurationElement, de la siguiente manera :
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 ]; }
}
}
Mantuve la clase UserElement simple, aunque debería seguir el patrón de declaración de cada propiedad como se describe en este excelente artículo de CodeProject . Como puede ver, representa los elementos de "usuario" en su configuración que proporcionó.
La clase UserElementCollection simplemente admite tener más de un elemento de "usuario", incluida la capacidad de agregar / eliminar / borrar elementos de la colección si desea modificarla en tiempo de ejecución.
Por último, está UserInfoSection, que simplemente indica que tiene una colección predeterminada de elementos de "usuario".
El siguiente es un ejemplo del archivo 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="[email protected]" />
<user firstName="Jane" lastName="Doe" email="[email protected]" />
</userInfo>
</configuration>
Como puede ver, en este ejemplo he incluido algunos elementos userInfo / user en App.config. También agregué configuraciones para decir que se pueden definir en los niveles máquina / aplicación / usuario / usuario itinerante.
A continuación, necesitamos saber cómo actualizarlos en tiempo de ejecución, el siguiente código muestra un ejemplo:
Configuration userConfig = ConfigurationManager.OpenExeConfiguration( ConfigurationUserLevel.PerUserRoamingAndLocal );
var userInfoSection = userConfig.GetSection( "userInfo" ) as UserInfoSection;
var userElement = new UserElement();
userElement.FirstName = "Sample";
userElement.LastName = "User";
userElement.Email = "[email protected]";
userInfoSection.Users.Add( userElement );
userConfig.Save();
El código anterior creará un nuevo archivo user.config si es necesario, enterrado en el interior de la carpeta "Configuración local / Datos de aplicación" para el usuario.
Si, en cambio, desea que el nuevo usuario se agregue al archivo app.config simplemente cambie el parámetro para el método OpenExeConfiguration () a ConfigurationUserLevel.None.
Como puede ver, es bastante simple, aunque encontrar esta información requirió un poco de excavación.
Me gustaría almacenar una colección de objetos personalizados en un archivo user.config y me gustaría agregar y eliminar elementos de la colección mediante programación y luego guardar la lista modificada nuevamente en el archivo de configuración.
Mis artículos tienen la siguiente forma simple:
class UserInfo
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
}
En mi app.config ya creé una sección personalizada:
<configuration>
<configSections>
<section name="userInfo" type="UserInfoConfigurationHandler, MyProgram"/>
</configSections>
<userInfo>
<User firstName="John" lastName="Doe" email="[email protected]" />
<User firstName="Jane" lastName="Doe" email="[email protected]" />
</userInfo>
</configuration>
También puedo leer en la configuración implementando IConfigurationSectionHandler
:
class UserInfoConfigurationHandler : IConfigurationSectionHandler
{
public UserInfoConfigurationHandler() { }
public object Create(object parent, object configContext, System.Xml.XmlNode section)
{
List<UserInfo> items = new List<UserInfo>();
System.Xml.XmlNodeList processesNodes = section.SelectNodes("User");
foreach (XmlNode processNode in processesNodes)
{
UserInfo item = new UserInfo();
item.FirstName = processNode.Attributes["firstName"].InnerText;
item.LastName = processNode.Attributes["lastName"].InnerText;
item.Email = processNode.Attributes["email"].InnerText;
items.Add(item);
}
return items;
}
}
Hice todo esto siguiendo este article . Sin embargo, al usar este enfoque, solo puedo leer la configuración de app.config en una colección List<UserInfo>
, pero también necesitaría escribir una lista modificada de nuevo.
Estaba buscando la documentación sin éxito y ahora estoy atascado. ¿Qué me estoy perdiendo?
No almacenaría ese tipo de datos en un app.config, al menos no si está destinado a ser actualizado programáticamente. Conceptualmente, es para configuraciones de configuración, no para datos de aplicaciones, así que quizás quiera almacenar su nombre de usuario y contraseña en un archivo XML separado (suponiendo que no puede o no quiere usar una base de datos).
Habiendo dicho eso, creo que lo mejor es leer en la aplicación.config como un archivo XML estándar, analizarlo, agregar los nodos que desee y volver a escribirlo. La API integrada de ConfigurationManager no ofrece una forma de volver a escribir configuraciones nuevas (lo que supongo da una pista sobre el uso previsto de Microsoft).
Utilice la nueva API System.Configuration de .Net Framework 2. (Ensamblaje: System.Configuration) IConfigurationSectionHandler está obsoleto.
Puede encontrar muchas muestras y descripciones muy buenas en http://www.codeproject.com/KB/dotnet/mysteriesofconfiguration.aspx
También hay un ejemplo de código sobre cómo puede modificar y guardar valores.
EDITAR: parte relevante de la documentación en el proyecto de código
Guarda solo valores modificados si existen cambios
Configuration.Save()
Guarda el nivel de cambios especificado, si existe algún cambio
Configuration.Save(ConfigurationSaveMode)
Guarda el nivel de cambios especificado, obligando a guardar si el segundo parámetro es verdadero
Configuration.Save(ConfigurationSaveMode, bool)
La enumeración ConfigurationSaveMode tiene los siguientes valores:
- Completo : guarda todas las propiedades de configuración, ya sea que hayan cambiado o no
- Modificado : guarda las propiedades que se han modificado, incluso si el valor actual es el mismo que el original
- Mínimo : guarda solo las propiedades que se han modificado y tienen valores diferentes a los originales
deberías crear una clase como:
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; }
}
}
después de eso en su web.config use:
<section name="MySettings" type="MyNamespace.MySettings"/>
<MySettings MyConfigSetting1="myValue">
Ese es el camino) Si desea utilizar no atributos, sino propiedades, simplemente cree la clase derivada de ConfigurationElement e inclúyala en su clase defived from ConfigurationSettings.
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());
}
}