Rozwijając mój wcześniejszy problem , zdecydowałem się (de) serializować moją klasę pliku konfiguracyjnego, która działała świetnie.
Teraz chcę, aby zapisać tablicę asocjacyjną liter dysków do mapowania (klucz jest literą dysku, wartość jest ścieżka sieciowa) i próbowałem za pomocą Dictionary
, HybridDictionary
i Hashtable
dla tego, ale zawsze pojawia się następujący błąd podczas wywoływania ConfigFile.Load()
lub ConfigFile.Save()
:
Wystąpił błąd dotyczący typu „App.ConfigFile”. [wycinek] System.NotSupportedException: nie można serializować elementu członkowskiego App.Configfile.mappedDrives [wycinek]
Z tego, co przeczytałem, słowniki i tabele skrótów mogą być serializowane, więc co robię źle?
[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();
}
}
}
}
źródło
DataContractSerializer
klasa może to zrobić. Po prostu wyjście jest trochę brzydkie.Na blogu Paula Weltera jest rozwiązanie - słownik generyczny XML serializowalny
źródło
string
wartości, ale zgłosiInvalidOperationException
podczas deserializacji wzmiankę o nieoczekiwanym elemencie opakowania, jeśli spróbujesz przechowywać w nim obiekty niestandardowe lub tablice ciągów. (Patrz na moje pytanie na przykład kwestii wychodził z tym.)Zamiast używać
XmlSerializer
, możesz użyćSystem.Runtime.Serialization.DataContractSerializer
. Może to bez problemu serializować słowniki i interfejsy.Oto link do pełnego przykładu, http://theburningmonk.com/2010/05/net-tips-xml-serialize-or-deserialize-dictionary-in-csharp/
źródło
Utwórz surogat serializacji.
Na przykład masz klasę z właściwością publiczną typu Dictionary.
Aby obsługiwać serializację XML tego typu, utwórz ogólną klasę klucz-wartość:
Dodaj atrybut XmlIgnore do swojej oryginalnej właściwości:
Uwidacznij właściwość publiczną typu array, która zawiera tablicę wystąpień SerializableKeyValue, które są używane do serializacji i deserializacji do właściwości SearchCategories:
źródło
Powinieneś zapoznać się z Json.Net, dość łatwym w użyciu i umożliwia deserializację obiektów Json bezpośrednio w Słowniku.
james_newtonking
przykład:
źródło
Słowników i tablic haszujących nie można serializować w programie
XmlSerializer
. Dlatego nie możesz ich używać bezpośrednio. Obejściem byłoby użycieXmlIgnore
atrybutu do ukrycia tych właściwości przed serializatorem i ujawnienia ich za pomocą listy możliwych do serializacji par klucz-wartość.PS: zbudowanie pliku
XmlSerializer
jest bardzo kosztowne, więc zawsze buforuj go, jeśli istnieje szansa, że będzie można go ponownie użyć.źródło
Chciałem klasy SerializableDictionary, która używałaby atrybutów xml dla klucza / wartości, więc dostosowałem klasę Paula Weltera.
To daje XML jak:
Kod:
Testy jednostkowe:
źródło
klasa Dictionary implementuje ISerializable. Definicja słownika klas podana poniżej.
Nie sądzę, że to jest problem. zobacz poniższy link, który mówi, że jeśli masz inny typ danych, którego nie można serializować, słownik nie zostanie serializowany. http://forums.asp.net/t/1734187.aspx?Is+Dictionary+serializable+
źródło
Możesz użyć ExtendedXmlSerializer . Jeśli masz zajęcia:
i utwórz instancję tej klasy:
Możesz serializować ten obiekt za pomocą ExtendedXmlSerializer:
Wyjściowy plik XML będzie wyglądał następująco:
Możesz zainstalować ExtendedXmlSerializer z nuget lub uruchomić następujące polecenie:
Oto przykład online
źródło
W tym artykule wyjaśniono dokładnie, jak sobie z tym poradzić: Jak ... Serializować tabelę skrótów w języku C #, gdy aplikacja tego wymaga?
Mam nadzieję, że to jest pomocne
źródło