2009-04-23 24 views
8

numaralı sürümlere ayırın. BinaryFormatter (C#) ile bir ağaç görünümü serileştirmek için kullandım. Sadece bunu yapan ve bütün serileştirilebilir sınıfları içeren Meclis şimdi güçlü bir isme sahip oldu ve imzalandı ve yeni bir versiyon numarası aldı (ancak uygulama değişmedi). Nesneyi şimdi imzalı ve

I bayt [] dizi serisini deneyin

, satır

(TreeViewData)binaryFormatter.Deserialize(memoryStream); 

ArgumentNullException üretir. (Parametre: tür)

Sürüm numarasının sorun olduğunu düşünmüştüm, bu yüzden kendi Bağlayıcısı'nı uyguladım. BindToType yönteminin üzerine yazdım ve sürümün düzeltildiğinden ve doğru türün döndüğünden emin oldum. Ancak, şu anda, program BindToType yöntemini bırakıyor, yine de yukarıda belirtilen istisnayı elde ediyorum.

Bunu nasıl düzeltirim?

cevap

3

'u bir serileştirme vekili kullanarak deneyebilirsiniz, ancak yeniden üretebileceğimiz bir şey olmadan iyi bir yanıt vermek zor olacaktır. Bununla birlikte, temel problem, BinaryFormatter'in, montajlar gibi şeylere gelince çok ama çok kırılgan olmasıdır. Heck, within an assembly bile yeterince kırılgan.

TreeViewData ağaç tabanlı olduğundan, xml'nin daha iyi (daha fazla sürüm toleranslı) bir seçenek olup olmayacağını merak ediyorum. Verimlilik bir endişe varsa, yüksek performans, sürüm toleranslı, taşınabilir ikili seri hale getirme sağlayan özel ikili biçimler (protobuf-net gibi) vardır. Verileriniz zaten serileştirilmişse ... yolu değiştirmenin zamanı olup olmadığını merak ediyorum. Verileri serileştirmek için eski montajı kullanmayı deneyin ve daha sağlam bir serileştirme stratejisine geçin.

11

Buna çözmek için bir SerializationBinder kullanabilirsiniz:

private class WeakToStrongNameUpgradeBinder : SerializationBinder 
{ 
    public override Type BindToType(string assemblyName, string typeName) 
    { 
     try 
     { 
      //Get the name of the assembly, ignoring versions and public keys. 
      string shortAssemblyName = assemblyName.Split(',')[0]; 
      var assembly = Assembly.Load(shortAssemblyName); 
      var type = assembly.GetType(typeName); 
      return type; 
     } 
     catch (Exception) 
     { 
      //Revert to default binding behaviour. 
      return null; 
     } 
    } 
} 

Sonra

var formatter = new BinaryFormatter(); 
formatter.Binder = new WeakToStrongNameUpgradeBinder(); 

Voila, eski tefrika nesneler bu formatlayıcıyla serileştirilemezse edilebilir. Eğer tür de değiştiyse, eski tiplerinizi yeni tiplerinize serpmek için SerializationSurrogate kullanabilirsiniz.

Diğerlerinin belirttiği gibi, IFormatter belgesine güvenmek yerine kendi serileştirme işleminizi yapmak, sürüm oluşturma ve serileştirilmiş boyut üzerinde çok daha fazla kontrole sahip olduğunuzdan dolayı iyi bir fikirdir.

+0

Oh çok teşekkür ederim. –

1

Benim önerim kalıcı depolamanız için yerleşik serileştirmeleri asla kullanmamaktır. Her zaman başka bir sebepten ötürü kendi kodunuzu yazın, bir gün ileride dosya formatlarınızı başka bir dilde okumanız ve yazmanız gerekecektir.

İlgili konular