Expandiendo sobre mi problema anterior , he decidido (des) serializar mi clase de archivo de configuración que funcionó muy bien.
Ahora quiero almacenar una matriz asociativa de las letras de unidad que desea asignar (clave es la letra de unidad, el valor es la ruta de acceso a la red) y han tratado de utilizar Dictionary
, HybridDictionary
y Hashtable
para esto, pero siempre me sale el siguiente error al llamar ConfigFile.Load()
o ConfigFile.Save()
:
Se produjo un error al reflejar el tipo 'App.ConfigFile'. [snip] System.NotSupportedException: no se puede serializar el miembro App.Configfile.mappedDrives [snip]
Por lo que he leído, los diccionarios y HashTables se pueden serializar, entonces, ¿qué estoy haciendo mal?
[XmlRoot(ElementName="Config")]
public class ConfigFile
{
public String guiPath { get; set; }
public string configPath { get; set; }
public Dictionary<string, string> mappedDrives = new Dictionary<string, string>();
public Boolean Save(String filename)
{
using(var filestream = File.Open(filename, FileMode.OpenOrCreate,FileAccess.ReadWrite))
{
try
{
var serializer = new XmlSerializer(typeof(ConfigFile));
serializer.Serialize(filestream, this);
return true;
} catch(Exception e) {
MessageBox.Show(e.Message);
return false;
}
}
}
public void addDrive(string drvLetter, string path)
{
this.mappedDrives.Add(drvLetter, path);
}
public static ConfigFile Load(string filename)
{
using (var filestream = File.Open(filename, FileMode.Open, FileAccess.Read))
{
try
{
var serializer = new XmlSerializer(typeof(ConfigFile));
return (ConfigFile)serializer.Deserialize(filestream);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + ex.ToString());
return new ConfigFile();
}
}
}
}
fuente
DataContractSerializer
clase puede hacer eso. Solo la salida es un poco fea.Hay una solución en el blog de Paul Welter: Diccionario genérico serializable XML
fuente
string
valores, pero arrojará unaInvalidOperationException
deserialización mencionando un elemento contenedor inesperado si intenta almacenar objetos personalizados o matrices de cadenas en él. (Vea mi pregunta para ver un ejemplo de los problemas que enfrenté con esto.)En lugar de usar
XmlSerializer
puedes usar unSystem.Runtime.Serialization.DataContractSerializer
. Esto puede serializar diccionarios e interfaces sin problemas.Aquí hay un enlace a un ejemplo completo, http://theburningmonk.com/2010/05/net-tips-xml-serialize-or-deserialize-dictionary-in-csharp/
fuente
Crea un sustituto de serialización.
Ejemplo, tiene una clase con propiedad pública de tipo Diccionario.
Para admitir la serialización Xml de este tipo, cree una clase genérica de clave-valor:
Agregue un atributo XmlIgnore a su propiedad original:
Exponga una propiedad pública de tipo de matriz, que contenga una matriz de instancias SerializableKeyValue, que se utilizan para serializar y deserializar en la propiedad SearchCategories:
fuente
Debe explorar Json.Net, bastante fácil de usar y permite que los objetos Json se deserialicen en el Diccionario directamente.
james_newtonking
ejemplo:
fuente
Los diccionarios y las tablas hash no son serializables con
XmlSerializer
. Por lo tanto, no puede usarlos directamente. Una solución alternativa sería utilizar elXmlIgnore
atributo para ocultar esas propiedades del serializador y exponerlas a través de una lista de pares clave-valor serializables.PD: la construcción de un
XmlSerializer
es muy costosa, así que siempre almacénelo en caché si existe la posibilidad de poder reutilizarlo.fuente
Quería una clase SerializableDictionary que usara atributos xml para clave / valor, así que adapté la clase de Paul Welter.
Esto produce xml como:
Código:
Pruebas unitarias:
fuente
La clase Diccionario implementa ISerializable. La definición de Diccionario de clase se da a continuación.
No creo que ese sea el problema. consulte el siguiente enlace, que dice que si tiene cualquier otro tipo de datos que no sea serializable, el Diccionario no se serializará. http://forums.asp.net/t/1734187.aspx?Is+Dictionary+serializable+
fuente
Puede usar ExtendedXmlSerializer . Si tienes una clase:
y crea una instancia de esta clase:
Puede serializar este objeto usando ExtendedXmlSerializer:
La salida xml se verá así:
Puede instalar ExtendedXmlSerializer desde nuget o ejecutar el siguiente comando:
Aquí hay un ejemplo en línea
fuente
Este artículo explica exactamente cómo manejar esto: ¿Cómo ... Serializo una tabla hash en C # cuando la aplicación lo requiere?
Espero que esto sea útil
fuente