2012-03-28 33 views
10

Tôi đã cố gắng tự khắc phục sự cố với JSON.net TypeNameHandling. Tôi đang lưu trữ một đối tượng được định dạng JSON bằng cách sử dụng RavenDB và đặt TypeNameHandling của trình nối tiếp JSON.net thành true để xử lý một cấu trúc thừa kế mà tôi đã có.Xử lý các thay đổi không gian tên với TypeNameHandling.All

Tôi cần thay đổi không gian tên của tài liệu mà tôi đang lưu trữ, vì vậy bây giờ khi nó được deserialzed nó ném lỗi "Lỗi giải quyết loại được chỉ định trong JSON" vì tham chiếu đến loại trong tài liệu JSON không còn tồn tại .

Có thể đánh chặn quá trình giải phóng Json để thực hiện một số loại di chuyển lăn không?

Xin cảm ơn,

Trả lời

18

Ok, đã tìm ra. Cuối cùng nó đã khá thẳng về phía trước. Bạn cần ghi đè lên số DefaultSerializationBinder chịu trách nhiệm tạo loại .Net từ tài liệu. Vì tài liệu json của tôi có không gian tên cũ trong đó, tôi cần phải chặn việc tạo kiểu đó để trả về kiểu đúng. Tôi đặt cùng một triển khai đơn giản cho phép bạn định cấu hình "di chuyển" khi trình tạo nối tiếp JSON được tạo.

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); 
     } 
    } 

đâu giao diện

public interface INamespaceMigration 
{ 
    string FromAssembly { get; } 

    string FromType { get; } 

    Type ToType { get; } 
} 
+3

cho những người tự hỏi làm thế nào để móc nó lên, nó như thế này: documentStore.Conventions.CustomizeJsonSerializer = serializer => serializer.Binder = new NamespaceMigrationSerializationBinder (di chuyển); – NeilD

+0

Đây là giải pháp tuyệt vời để di chuyển không gian tên trong RavenDB. Cảm ơn rất nhiều!!! – marisks

+0

Tôi nghĩ rằng bạn có thể muốn ghi đè BindToName quá, hoặc tiết kiệm của bạn có thể có một loại $ = "". Bạn có thể làm một cái gì đó như: công khai ghi đè void BindToName (Loại serializedType, ra chuỗi assemblyName, ra chuỗi typeName) { typeName = serializedType.FullName; assemblyName = serializedType.Assembly.FullName; – pomarc

0

Bạn có thể sử dụng DocumentConversionListener để thực hiện việc này. Vui lòng xem tại đây: http://ayende.com/blog/66563/ravendb-migrations-rolling-updates

+0

Cảm ơn Daniel. Nhưng vấn đề xảy ra trước khi nó có thể đến đây. Nếu bạn nhìn vào giao diện của IDocumentConversionListener, bạn sẽ thấy nó đang gửi đối tượng deserializded qua. Vấn đề của tôi là nó không thành công trên deserialization. –

+0

Bạn có một tham số 'tài liệu' của loại RavenJObject, đó là cây json trước khi nó được deserialized. Điều này sẽ cho phép bạn thay đổi giá trị của thuộc tính trước khi nó được deserialized vào đối tượng/tài sản. Hy vọng rằng sẽ giúp - nếu không, xin vui lòng gửi một số mã. –

Các vấn đề liên quan