2011-03-21 24 views
15

मैं एक आवेदन के पुराने संस्करण के साथ "SomeClass" deserialize करने की कोशिश कर रहा हूँ। मुझे यह नीचे अपवादDeserialization पीछे की संगतता

सिस्टम। रनटाइम। क्रमबद्धता। क्रमबद्धता अपवाद: ऑब्जेक्टमेनगर को फ़िक्सअप की एक अवैध संख्या मिली। यह आमतौर पर फॉर्मेटर में एक समस्या इंगित करता है।

Deserialization अपवाद फेंकता जब मैं संस्करण 0.9 को क्रमानुसार और संस्करण 0.8 का उपयोग कर deserialize की कोशिश करो। मैंने सोचा कि OptionalField विशेषता चाल चलती है, लेकिन ऐसा नहीं हुआ।

// Version 0.8 
[Serializable()] 
class Foo{ 
    Bar b; 
} 

// Version 0.9 
[Serializable()] 
class Foo{ 
    Bar b; 
    [OptionalField] 
    Zoo z; 
} 

यह देखते हुए कि मैं संस्करण 0.8 बदल नहीं सकते, मैं कैसे जोड़ना चाहिए फू के लिए और अधिक राज्य वस्तु ऐसी है कि पिछले संस्करणों जो कुछ भी वे कर सकते हैं deserialize कर सकते हैं?

किसी भी सूचक को वास्तव में सराहना की जाएगी।

अद्यतन 1 बार और चिड़ियाघर अन्य कक्षाएं हैं जो धारावाहिक हैं और इसमें हैशटेबल और अन्य धारावाहिक सामान शामिल हैं। सब कुछ उन वर्गों में क्रमिक है। इसके अलावा, मेरे पास कोई स्ट्रैट नहीं है।

+0

चाहे क्षेत्र वैकल्पिक है या नहीं, यहां अप्रासंगिक है - तथ्य यह है कि धारावाहिक संस्करणों में काम नहीं करता है, AFAIK; यह कहना नहीं है कि आप सदस्यों को जोड़ नहीं सकते हैं, निश्चित रूप से आप कर सकते हैं, लेकिन, उदाहरण के लिए, मैं केवल एक क्रियात्मक प्रकार को परिभाषित नहीं कर सकता हूं और मौजूदा के साथ क्रमबद्ध वस्तुओं को deserialize कर सकते हैं - विधानसभाओं के साथ कुछ करने के लिए, या प्रकार 'टोकन ', मुझे लगता है। –

+0

करेफ, 'चिड़ियाघर' का वास्तविक प्रकार क्या है? मुझे याद है कि कुछ प्रकार (सरणी) बस सही काम नहीं कर पाए। –

+0

क्या आप बाइनरी क्रमबद्धता के बजाय एक्सएमएल क्रमबद्धता का उपयोग करने के इच्छुक होंगे? यह अधिक संस्करण-सुरक्षित होगा। – code4life

उत्तर

26

पहले, कभी नहीं कभी नहीं का उपयोग CLR के क्रमबद्धता कार्यों के बजाय Soap Serialization भंडारण। हम आम तौर पर उस गलती को एक बार बनाते हैं, ऑब्जेक्ट को ब्लॉब डेटाबेस फ़ील्ड में डालते हैं और पिछली सोच में खुद को पॅट करते हैं कि हम चालाक हैं। और फिर सीएलआर को एक पैच मिलता है या हमारी असेंबली संस्करण बदलती है और आप खराब हो जाते हैं। तो ऐसा मत करो।

public sealed class CustomBinder : SerializationBinder { 

    public override Type BindToType(string assemblyName, string typeName) { 

     Type typeToDeserialize = null; 

     if (typeName.IndexOf("SomeType") != -1) { 
      typeToDeserialize = typeof(Foo.Bar.Bax.NewType); 
     } 
     else if (typeName.IndexOf("SomeOtherType") != -1) { 
      typeToDeserialize = typeof(Foo.Bar.Bax.SomeOtherNewType); 
     } 
     else { 
      // ... etc 
     } 

     return typeToDeserialize; 
    } 
} 

सेट संरूपक को आपके पहले उपयोग कर रहे हैं की Binder संपत्ति:

आप अभी भी यह करने के लिए चाहते हैं, तो समस्या का प्रबंधन करने के लिए सबसे अच्छा तरीका अपने स्वयं के SerializationBinder कि कुछ इस तरह दिखता बनाने के लिए है deserializing करने के लिए ताकि यह चूक को ओवरराइड करता है।

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

+2

क्या आपकी 'नेवर' टिप्पणी एक्सएमएल क्रमबद्धता पर भी लागू होती है? मुझे लगता है कि डेटाकंट्रैक्ट और डेटामेम्बर के साथ जेनरेट की गई संरचना पर अच्छा नियंत्रण है। उस पर आपकी राय प्राप्त करने में रुचि होगी। – paul

+0

नहीं, लेकिन बाइनरी सीरिएलाइज़र लंबी अवधि के क्रमिकरण के लिए उपयुक्त नहीं है। तार के ऊपर बाइट पंप करने के लिए यह सबसे उपयुक्त है, उदाहरण के लिए, क्लाइंट-सर्वर एप्लिकेशन। उदाहरण के लिए वेबफॉर्म इसका उपयोग करता है। – Sebazzz

2

ऐसा लगता है कि ऐसा करने का एक तरीका एक संस्करण वाली वस्तु होगी, इस तरह आप नवीनतम संस्करण का उपयोग कर ऑब्जेक्ट को deserializing करने का प्रयास कर सकते हैं। यदि यह काम नहीं करता है, तो यह सफल होने तक एक संस्करण को वापस ले जाएं। फिर एक बार जब आपका ऑब्जेक्ट हो जाए, तो उसे ऑब्जेक्ट के नवीनतम संस्करण में अपडेट करें और किसी भी फ़ील्ड के लिए डिफ़ॉल्ट मान का उपयोग करें जिसके लिए आपके पास डेटा नहीं है।

+0

यदि हम अपने आवेदन को डाउनग्रेड (रोलबैक का परिणाम) तो हमारे पास ऐसे फ़ील्ड होंगे जो गायब हैं (डेटा गायब होने की बजाय); वैसे भी आप जो कह रहे हैं वह यह होना चाहिए। – karephul

+0

मुझे पता है कि सी प्रोग्रामर क्या करने के लिए उपयोग करते हैं। मैंने सोचा कि हम बहुत उच्च स्तर पर अमूर्तता पर प्रोग्राम कर रहे हैं और यह मानक समस्या हो सकती है। आपकी अंतर्दृष्टि के लिए धन्यवाद। – karephul

0

optional field विशेषता को चाल चलनी चाहिए थी। क्या आप वास्तविक कक्षाएं पोस्ट कर सकते हैं जिन्हें आप क्रमबद्ध करने की कोशिश कर रहे हैं।

आप इन बातों को पहले की कोशिश कर सकते -

यदि कोई हो कन्वर्ट structs करने के लिए classes

कुछ भी है कि लंबी अवधि के जैसा दिखता है के लिए कोशिश binary serilization

+0

मैंने पोस्ट अपडेट किया है। – karephul

+0

क्या आपने साबुन क्रमबद्ध करने की कोशिश की? –

4

यदि प्रत्येक संस्करण के लिए निर्माता संगत हैं (उदा।वहाँ एक parameterless या दोनों संस्करणों के लिए Foo(Bar b) निर्माता) आप अपने सिस्टम deserializing पहले

BinaryFormatter formatter = new BinaryFormatter(); 
formatter.AssemblyFormat = Formatters.FormatterAssemblyStyle.Simple; 

कॉल कर सकते हैं है।

3

इस मुद्दे की जांच करने वाले लोगों की सलाह के रूप में "बहुत देर हो चुकी है" ... मैं दृढ़ता से बाइनरीफॉर्मेटर के माध्यम से जारी रहने के खिलाफ सलाह देता हूं। सिंक में मौजूद 2 ऐप-डोमेन के बीच क्षणिक स्थानांतरण के लिए यह ठीक है, लेकिन यह इसके बारे में आईएमओ है। अन्य क्रमिकरण उपकरण मौजूद हैं जिनके पास इन मुद्दों का समाधान नहीं है। बाइनरी के मामले में, प्रोटोबफ-नेट एक बहुत ही उचित विकल्प है - बिना दर्द के जोड़ने/निकालने/नाम बदलने की इजाजत देता है।

संबंधित मुद्दे