2012-05-22 12 views
8

मैं इस वर्ग को फ़ाइल में सहेजने के लिए XMLSerializer का उपयोग कर रहा हूं। कक्षा में एक स्ट्रिंग और एनम है जैसा कि नीचे दिखाया गया है:XmlSerializer: एक enum मान को Deserialize कैसे करें

public class IOPoint 
{ 
    string Name {get; set;} 
    TypeEnum {get; set;} 
} 


public enum TypeEnum 
{ 
    Temperature, 
    Pressure, 
    Humidity, 
} 

जब धारावाहिक ऐसा लगता है।

<IOPoint> 
    <Name>Relative Humidity</Name> 
    <TypeEnum>Humidity</TypeEnum> 
</IOPoint> 

मैं serializing किया गया है और कई संस्करण के लिए कोई समस्या नहीं के साथ इस वस्तु deserializing। अब मैं आर्द्रता का समर्थन नहीं करना चाहता, इसलिए मैंने इसे enum से हटा दिया। हालांकि, एक्सएमएल से deserializing जब यह एक अपवाद का कारण बनता है क्योंकि TypeEnum फ़ील्ड, आर्द्रता में मान टाइपएनम के लिए मान्य मान नहीं है। यह समझ में आता है, लेकिन इसे कैसे संभालें?

मैं जो करना चाहता हूं वह सिर्फ इस त्रुटि को अनदेखा कर रहा है। और मूल्य को शून्य के रूप में छोड़ दें। मैंने ऑन अज्ञात एलिमेंट XmlDeserilizationEvent क्लास को कार्यान्वित करने का प्रयास किया है। दुर्भाग्यवश, यह इस त्रुटि को नहीं पकड़ता है।

इस त्रुटि को पकड़ने और अनदेखा करने के बारे में कोई भी विचार (मैं deserialization पूरा होने के बाद साफ कर सकते हैं)।

मिच

+0

यदि आपको कोई समाधान मिला तो मुझे पता होना अच्छा लगेगा। मुझे एक संबंधित समस्या है जहां सर्वर-साइड में एक नया एनम फ्लैग वैल्यू शामिल है जिसमें क्लाइंट को पता नहीं है, इसलिए वास्तव में केवल एक फ़ील्ड के क्रमबद्धता को प्रबंधित करने का तरीका ढूंढना है। अगली बार मैं सिर्फ एक int का उपयोग करूंगा, लेकिन अभी के लिए ... पिछड़ा संगतता। – avenmore

उत्तर

5

आप सदस्य अप्रचलित

public enum TypeEnum 
{ 
    Temperature, 
    Pressure, 
    [Obsolete] 
    Humidity 
} 
+2

कारण मैं [अप्रचलित] विशेषता का उपयोग नहीं कर सकता क्योंकि यह हमारे कोड में enum मानों के माध्यम से पुनरावृत्त करने के लिए सामान्य अभ्यास है। तो अगर "आर्द्रता" अप्रचलित चिह्नित भी है, तो भी यह हमारे foreach loops में उठाया जाएगा। (जब तक कि गणनाकर्ता को ओवरराइड करने का कोई तरीका न हो?) – Mitch

+0

क्या आप इसका उपयोग कर रहे चर परिवर्तनीय बना सकते हैं? उदा। टाइप टाइपम?वैल = शून्य; –

4

यह आम तौर पर खराब व्यवहार का एक गणन सदस्य को हटाने के लिए अपने पुस्तकालय से प्रयोग में है के बाद माना जाता है चिह्नित कर सकते हैं। आप सदस्य को जगह में क्यों नहीं छोड़ते हैं, लेकिन भविष्य में उपयोग को रोकने के लिए इसे [Obsolete] विशेषता के साथ चिह्नित करें? ObsoleteAttribute(string,bool) कन्स्ट्रक्टर का दूसरा पैरामीटर true के रूप में निर्दिष्ट करने पर चिह्नित सदस्य का उपयोग होने पर संकलन-समय त्रुटि उत्पन्न होगी। typeEnum == (TypeEnum)2:

public enum TypeEnum 
{ 
    Temperature, 
    Pressure, 

    [Obsolete("It's always sunny in Philadelphia", true)] 
    Humidity, 
} 

त्रुटि deserialized मूल्यों की जाँच, आप अंतर्निहित कीमत के खिलाफ तुलना कर सकते दरकिनार करने के लिए।

1

आप IXmlSerializable लागू कर सकते हैं, जहां आप Enum के लिए TryParse जैसे कुछ का उपयोग कर सकते हैं।

लेकिन मैं अप्रचलित विशेषता का उपयोग कर अन्य पोस्टरों से सहमत हूं।

+0

यदि मुझे एक और कामकाज नहीं मिल रहा है, तो IXMLSerializable का उपयोग कर कस्टम क्रमबद्धता मेरा एकमात्र समाधान हो। जबकि मैं इसमें हूं, मैं एक संस्करण फ़ील्ड भी जोड़ूंगा जिसका उपयोग मैं deserialization को मार्गदर्शन करने के लिए कर सकता था। हम ISerializable का उपयोग करते समय कुछ ऐसा करते हैं। असली कक्षा में लगभग 15 फ़ील्ड हैं। मुझे आश्चर्य है कि क्या मैं सिर्फ एक क्षेत्र के लिए deserializer कोड लिखने से दूर हो सकता है? – Mitch

2

आप विशेषताओं का उपयोग कर सकते हैं चारों ओर नोड नाम बदलने और xml क्रमबद्धता से तत्वों को छिपाने के लिए, बस उस एक तत्व मैन्युअल पार्स करने के लिए:

public class IOPoint 
{ 
public string Name {get; set;} 

[XmlIgnore] 
public TypeEnum TypeEnum {get; set;} 

[XmlElement("TypeEnum")] 
public string LegacyTypeEnum 
{ 
    get { return this.TypeEnum.ToString(); } 
    set 
    { 
    try 
    { 
    this.TypeEnum = (TypeEnum)Enum.Parse(typeof(TypeEnum),value); 
    } 
    catch(ArgumentException) 
    { 
    // Handle "Humidity" 
    } 
    catch(OverflowException) 
    { 
    } 
    } 
} 
} 

प्रति टिप्पणी वहाँ कुछ भ्रम हो गया लगता है; विजुअल स्टूडियो 2010 प्रोजेक्ट के रूप में here is a worked example। यह दृष्टिकोण किसी ऑब्जेक्ट की केवल एक प्रॉपर्टी को मैन्युअल रूप से पार्स करने का एक आसान तरीका है (अभी भी XML पार्सिंग करने के लिए XmlSerializer का लाभ उठाना)।

+0

enum मान को enum के बजाय स्ट्रिंग के रूप में सीरियलाइज़ करना, एक अच्छा विचार होगा यदि मेरे पास पहले से ही XML फ़ाइलों को पढ़ने की आवश्यकता नहीं है। इन मौजूदा फ़ाइलों में तत्व है और मुझे अभी भी TypeEnum फ़ील्ड के मान को पढ़ने और तदनुसार कार्य करने की आवश्यकता है। अपवाद को पकड़ने के लिए एक आदर्श समाधान होगा जब यह आर्द्रता मूल्य को deserialize करने की कोशिश करता है। लेकिन Deserializer पर डाले गए अपवाद हैंडलर में से कोई भी इस त्रुटि को पकड़ नहीं लेता है। – Mitch

+0

मैंने दोनों को प्रदर्शित करने के लिए एक संकलित नमूना शामिल किया है जो यह काम करता है और यह कैसे काम करता है। – user423430