2014-04-08 3 views
6

में एक शब्दकोश को क्रमबद्ध/डी-क्रमबद्ध करने के लिए कैसे करें मैं अपने आवेदन के लिए एक सेव रूटीन लिखने की कोशिश कर रहा हूं जहां एप्लिकेशन के कई भाग एक शब्दकोश में आइटम जोड़ते हैं और फिर सहेजें फ़ंक्शन उन्हें लिखता है एक्सएमएल फ़ाइल। खुली दिनचर्या को उन फ़ाइलों को पढ़ने और शब्दकोश को फिर से पॉप्युलेट करने की आवश्यकता होती है और फिर मैं उन ऑब्जेक्ट को अपने एप्लिकेशन में वापस रख सकता हूं। मैं अब मेरे पास नियमित रूप से डी-सीरियलाइजेशन के साथ संघर्ष कर रहा हूं। बचाने मेरी दिनचर्या के रूप में एक फ़ाइल बनाने के लिए एक्सएमएल

XmlDocument xmlDoc = new XmlDocument(); 

// Write down the XML declaration 
XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null); 

// Create the root element 
XmlElement rootNode = xmlDoc.CreateElement("TireStudy"); 
xmlDoc.InsertBefore(xmlDeclaration, xmlDoc.DocumentElement); 
xmlDoc.AppendChild(rootNode); 

foreach (var saveItem in _SaveItems) 
{ 
    XPathNavigator nav = rootNode.CreateNavigator(); 
    using (var writer = nav.AppendChild()) 
    { 
     var serializer = new XmlSerializer(saveItem.Value.GetType()); 
     writer.WriteWhitespace(""); 
     serializer.Serialize(writer, saveItem.Value); 
     writer.Close(); 
    } 
} 

xmlDoc.Save(fileName); 

यह दिनचर्या काम करता है इस प्रकार है, लेकिन मैं शब्दकोश की कुंजी मान के रूप में अच्छी तरह से फ़ाइल में सहेजा जा करने के लिए चाहते हैं और मुझे यकीन है कि कैसे को डी-क्रमानुसार करने नहीं कर रहा हूँ यह फ़ाइल बनाता है क्योंकि मैं उन्हें पढ़ने से पहले वस्तुओं के प्रकारों को नहीं जानता।

भाग 2 (मैं एक प्रश्न के नए भागों को जोड़ने से नफरत है, लेकिन मैं समस्याओं आगे जाने को संबोधित करने के लिए एक बेहतर तरीका नहीं दिख रहा है)

मैं अब निम्नलिखित कोड है,

var knownTypes = new List<Type> 
{ 
    typeof(ObservableCollection<string>), 
    typeof(ObservableCollection<Segments>), 
    typeof(Segments), 
    typeof(List<string>) 
}; 
var serialized = _SaveItems.Serialize(knownTypes); 

लेकिन मैं निम्न अपवाद

Type 'System.Collections.Generic.List`1[System.String]' cannot be added to list of known types since another type 'System.Collections.ObjectModel.ObservableCollection`1[System.String]' with the same data contract name 'http://schemas.microsoft.com/2003/10/Serialization/Arrays:ArrayOfstring' is already present. If there are different collections of a particular type - for example, List<Test> and Test[], they cannot both be added as known types. Consider specifying only one of these types for addition to the known types list. 

मिल रहा है, तो या तो typeof (ObservableCollection) या typeof (सूची) यह एक मैं नष्ट कर दिया की जरूरत शिकायत हटाना यह अपवाद नहीं।

+0

भाग 2 के बारे में, मैं नहीं यकीन अगर यह एक ढांचा [बाधा] (http://msdn.microsoft.com/en-us/library/aa347850.aspx) या [बग] (http://support.microsoft.com/kb/967339)। – xmamat

+0

किसी भी तरह से, मैंने अपनी सूची से छुटकारा पा लिया और मेरी कक्षा में ऑब्जर्जेबल कोलेक्शन का उपयोग किया और जीवन आसान हो गया। इस पर मदद के लिए आपका धन्यवाद। – PlTaylor

उत्तर

3

आप DataContractSerializer इस्तेमाल कर सकते हैं के रूप में इस post में विस्तार से बताया है, लेकिन आप के रूप में serializer के लिए एक पैरामीटर नेस्टेड object टाइप किये गए वर्गों का समर्थन करने के लिए जाना प्रकार पारित करने के लिए हो सकता है:

using System; 
using System.Collections.Generic; 
using System.Runtime.Serialization; 
using System.IO; 
using System.Xml; 

public static class SerializationExtensions 
{ 
    public static string Serialize<T>(this T obj, IEnumerable<Type> knownTypes) 
    { 
     var serializer = new DataContractSerializer(obj.GetType(), knownTypes); 
     using (var writer = new StringWriter()) 
     using (var stm = new XmlTextWriter(writer)) 
     { 
      serializer.WriteObject(stm, obj); 
      return writer.ToString(); 
     } 
    } 
    public static T Deserialize<T>(this string serialized, IEnumerable<Type> knownTypes) 
    { 
     var serializer = new DataContractSerializer(typeof(T), knownTypes); 
     using (var reader = new StringReader(serialized)) 
     using (var stm = new XmlTextReader(reader)) 
     { 
      return (T)serializer.ReadObject(stm); 
     } 
    } 
} 

public class Address 
{ 
    public string Country { get; set; } 
    public string City { get; set; } 
} 
public class CodedAddress 
{ 
    public int CountryCode { get; set; } 
    public int CityCode { get; set; } 
} 
class Program 
{ 
    static void Main(string[] args) 
    { 
     var persons1 = new Dictionary<string, Address>(); 
     persons1.Add("John Smith", new Address { Country = "US", City = "New York" }); 
     persons1.Add("Jean Martin", new Address { Country = "France", City = "Paris" }); 

     // no need to provide known types to the serializer 
     var serializedPersons1 = persons1.Serialize(null); 
     var deserializedPersons1 = serializedPersons1.Deserialize<Dictionary<string, Address>>(null); 


     var persons2 = new Dictionary<string, object>(); 
     persons2.Add("John Smith", new Address { Country = "US", City = "New York" }); 
     persons2.Add("Jean Martin", new CodedAddress { CountryCode = 33, CityCode = 75 }); 

     // must provide known types to the serializer 
     var knownTypes = new List<Type> { typeof(Address), typeof(CodedAddress) }; 
     var serializedPersons2 = persons2.Serialize(knownTypes); 
     var deserializedPersons2 = serializedPersons2.Deserialize<Dictionary<string, object>>(knownTypes); 
    } 
} 
+0

मेरा google-fu यहां गंभीर रूप से कम हो रहा है। मैंने कल के बेहतर हिस्से को इस में देखकर बिताया और उस पर नहीं आया या महत्व मुझ पर खो गया था। मुझे इसे आज़माएं और आपको वापस आएं। – PlTaylor

+0

मुझे सीरियलाइजेशन पर निम्नलिखित अपवाद मिल रहा है- 'MyProgram.InformationTabs.NavigationTrees.SitesViewModel' टाइप करें, डेटा अनुबंध नाम 'साइट्सव्यूमोडेल: http: //schemas.datacontract.org/2004/07/MyProgram.InformationTabs.NavigationTrees।' उम्मीद नहीं है DataContractResolver का उपयोग करने पर विचार करें या ज्ञात प्रकारों की सूची में स्थिर रूप से ज्ञात किसी भी प्रकार को जोड़ें - उदाहरण के लिए, KnownTypeAttribute विशेषता का उपयोग करके या उन्हें DataContractSerializer को ज्ञात ज्ञात प्रकारों की सूची में जोड़कर। इस तरीके से इसे कैसे सजाने के बारे में कोई विचार है? – PlTaylor

+0

आप सही हैं: किसी को 'शब्दकोश <स्ट्रिंग, ऑब्जेक्ट>' के साथ काम करने के लिए serializer के ज्ञात प्रकार प्रदान करना होगा। मैंने आपकी आवश्यकता को पूरा करने के लिए अपना जवाब अपडेट कर लिया है। शायद इसे करने का सबसे शानदार तरीका नहीं है, लेकिन मुझे यह काम करने के लिए मिला। – xmamat