2012-03-28 14 views
10

के साथ नामस्थान परिवर्तनों को संभालना मैं JSON.net TypeNameHandling के साथ एक फिक्स में अपना स्वयं का प्रबंधन करने में कामयाब रहा। मैं RavenDB का उपयोग कर एक JSON स्वरूपित ऑब्जेक्ट संग्रहीत कर रहा हूं और मेरे पास मौजूद विरासत संरचना से निपटने के लिए JSON.net serializer के TypeNameHandling को सही पर सेट कर रहा हूं।TypeNameHandling.All

मुझे उस दस्तावेज़ के नामस्थान को बदलने की ज़रूरत है जिसे मैं संग्रहीत कर रहा हूं, इसलिए अब जब यह deserialzed है तो यह त्रुटि "जेएसओएन में निर्दिष्ट प्रकार को हल करने में त्रुटि" त्रुटि को फेंक देता है क्योंकि JSON दस्तावेज़ में प्रकार का संदर्भ अब मौजूद नहीं है ।

क्या किसी प्रकार के रोलिंग माइग्रेशन करने के लिए जेसन deserialization को रोकना संभव है?

धन्यवाद,

उत्तर

18

ठीक है, इसे समझ लिया गया। अंत में यह बहुत सीधे आगे था। आपको DefaultSerializationBinder को ओवरराइड करने की आवश्यकता है जो दस्तावेज़ से .Net प्रकार बनाने के लिए ज़िम्मेदार है। चूंकि मेरे जेसन दस्तावेज़ में पुराना नामस्थान है, इसलिए मुझे सही प्रकार को वापस करने के लिए उस प्रकार के निर्माण को रोकने की आवश्यकता है। मैंने एक सरल कार्यान्वयन एक साथ रखा है जो JSON serializer बनने पर आपको "माइग्रेशन" कॉन्फ़िगर करने की अनुमति देगा।

public class NamespaceMigrationSerializationBinder : DefaultSerializationBinder 
    { 
     private readonly INamespaceMigration[] _migrations; 

     public NamespaceMigrationSerializationBinder(params INamespaceMigration[] migrations) 
     { 
      _migrations = migrations; 
     } 

     public override Type BindToType(string assemblyName, string typeName) 
     { 
      var migration = _migrations.SingleOrDefault(p => p.FromAssembly == assemblyName && p.FromType == typeName); 
      if(migration != null) 
      { 
       return migration.ToType; 
      } 
      return base.BindToType(assemblyName, typeName); 
     } 
    } 

कहाँ इंटरफ़ेस

public interface INamespaceMigration 
{ 
    string FromAssembly { get; } 

    string FromType { get; } 

    Type ToType { get; } 
} 
+3

उन लोगों के लिए जो इसे हुक अप करने के बारे में सोचते हैं, यह इस तरह है: documentStore.Conventions.CustomizeJsonSerializer = serializer => serializer.Binder = नया नेमस्पेस माइग्रेशनसेरियलाइजेशन बाइंडर (माइग्रेशन); – NeilD

+0

रावेनडीबी में नेमस्पेस माइग्रेशन के लिए यह एक अच्छा समाधान है। बहुत बहुत धन्यवाद!!! – marisks

+0

मुझे लगता है कि आप BindToName को ओवरराइड करना भी चाह सकते हैं, या आपकी बचत में $ type = "" हो सकता है। आप कुछ ऐसा कर सकते हैं: सार्वजनिक ओवरराइड शून्य BindToName (टाइप serialized टाइप, बाहर स्ट्रिंग असेंबलीनाम, बाहर स्ट्रिंग प्रकार नाम) { typeName = serializedType.FullName; असेंबलीनाम = serializedType.Assembly.FullName; – pomarc

0

आप एक DocumentConversionListener उपयोग कर सकते हैं यह करने के लिए। कृपया यहां एक नज़र डालें: http://ayende.com/blog/66563/ravendb-migrations-rolling-updates

+0

धन्यवाद डैनियल है। लेकिन इससे पहले कि यह यहां पहुंचने में समस्या हो। यदि आप IDocumentConversionListener के इंटरफ़ेस को देखते हैं तो आप देखेंगे कि यह deserializded ऑब्जेक्ट को भेज रहा है। मेरी समस्या यह है कि यह deserialization पर असफल रहा है। –

+0

आपके पास रावेनजे ऑब्जेक्ट के प्रकार का एक पैरामीटर 'दस्तावेज़' है, जो जेसन पेड़ को deserialized से पहले है। यह आपको वस्तु/संपत्ति में deserialized से पहले संपत्ति के मूल्य को बदलने में सक्षम होना चाहिए। उम्मीद है कि मदद करता है - यदि नहीं, तो कृपया कुछ कोड पोस्ट करें। –