2012-04-02 34 views
10

Tôi có một lớp học cần được sắp xếp và deserialzed.Ghi đè quá trình deserialization XML để sử dụng deserialization cơ sở và thêm chức năng

Nhưng mỗi lần sau khi làm hỏng, tôi cần gọi phương thức đồng bộ hóa các tham chiếu.

Dù sao tôi có thể thực hiện việc deserialization và sử dụng deserialization truyền thống nhưng thêm các cuộc gọi đến phương pháp của tôi sau khi deserialization thường xuyên?

+0

Bạn có thể làm rõ chính xác ý của bạn là gì? "Tôi được gọi để gọi một phần mềm đồng bộ hóa tham chiếu"? Vui lòng giải thích _why_ điều này là cần thiết. – Oded

+0

cho lớp ví dụ bao gồm: thành viên A, MemberB và danh sách thành viên có xmlIgnore và nên contian thành viên A và B thường xuyên desrialization sẽ tạo ra các trường hợp khác nhau cho danh sách và thành viên tôi cần danh sách để tham khảo các thành viên được deserilized . câu hỏi làm thế nào để tạo ra một phương pháp desrialization bài? hoặc thực hiện và gọi điện cho việc deserialization thường xuyên – user271077

+0

Bạn có thể cung cấp một ví dụ không? Vẫn chưa rõ những gì bạn đang cố gắng hoàn thành. Bạn muốn điền các trường thành viên khác với 'XmlIgnore' vào một đối tượng sau mỗi lần deserialization? – mellamokb

Trả lời

8
using System.Xml.Serialization; 

namespace Custom.Xml.Serialization 
{ 
    public interface IXmlDeserializationCallback 
    { 
     void OnXmlDeserialization(object sender); 
    } 

    public class CustomXmlSerializer : XmlSerializer 
    { 
     protected override object Deserialize(XmlSerializationReader reader) 
     { 
      var result = base.Deserialize(reader); 

      var deserializedCallback = result as IXmlDeserializationCallback; 
      if (deserializedCallback != null) 
      { 
       deserializedCallback.OnXmlDeserialization(this); 
      } 

      return result; 
     } 
    } 
} 

kế thừa lớp học của bạn từ IXmlDeserializationCallback và triển khai logic đồng bộ hóa của bạn trong phương pháp OnXmlDeserialization.

tín dụng cho How do you find out when you've been loaded via XML Serialization?

UPDATE:

tốt, như xa như tôi hiểu được topicstarter, ông không muốn "bằng tay" gọi một số logic sau mỗi deserialization XML. Vì vậy, thay vì thực hiện việc này:

public class MyEntity 
{ 
    public string SomeData { get; set; } 

    public void FixReferences() 
    { 
      // call after deserialization 
      // ... 
    } 
} 

foreach (var xmlData in xmlArray) 
{ 
    var xmlSer = new XmlSerializer(typeof(MyEntity)); 
    using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(xmlData))) 
    { 
     var entity = (MyEntity)xmlSer.Deserialize(memStream); 
     entity.FixReferences(); 

     // do something else with the entity 
     // ... 
    } 
} 

anh ấy muốn thực hiện chỉ deserialization, mà không phải lo lắng về các cuộc gọi thêm. Trong trường hợp này, giải pháp đề xuất là sạch/đơn giản - bạn chỉ cần kế thừa lớp thực thể của bạn từ giao diện IXmlDeserializationCallback, và thay thế XmlSerializer với CustomXmlSerializer:

public class MyEntity: IXmlDeserializationCallback 
    { 
     public string SomeData { get; set; } 

     private void FixReferences() 
     { 
       // call after deserialization 
       // ... 
     } 

     public void OnXmlDeserialization(object sender) 
     { 
      FixReferences(); 
     } 
    } 

    foreach (var xmlData in xmlArray) 
    { 
     var xmlSer = new CustomXmlSerializer(typeof(MyEntity)); 
     using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(xmlData))) 
     { 
      var entity = (MyEntity)xmlSer.Deserialize(memStream); 
      // entity.FixReferences(); - will be called automatically 

      // do something else with the entity 
      // ... 
     } 
    } 
+1

Đáng buồn thay, phương pháp ghi đè không bao giờ được gọi là ... – Herdo

+0

Bất kỳ ý tưởng nào tại sao các phương thức ghi đè không được gọi trong .NET 4.5? – Raj

4

lựa chọn của bạn sử dụng XmlSerializer còn hạn chế.

  • Deserialize toàn bộ đồ thị đối tượng của bạn và sau đó áp dụng bất kỳ sửa chữa nào bạn yêu cầu.
  • Thực hiện một số thao tác trong bộ phận định vị tài sản của đối tượng của bạn.
  • Triển khai IXmlSerializable trên các loại của bạn để bạn có quyền kiểm soát rõ ràng về tuần tự hóa/deserialization. Không phải là một lựa chọn dễ dàng.

Nếu bạn có thể thay đổi để sử dụng DataContractSerializer, có lợi thế (và bất lợi) thì bạn có thể sử dụng OnDeserializedAttribute. Ví dụ

[DataContract] 
public class MyClass 
{ 
    [DataMember] 
    public string AMember{get;set;} 

    [OnDeserialized] 
    public void OnDeserialized(StreamingContext context) 
    { 
     // called after deserializing instance of MyClass 
    } 
} 
1

tôi có một giải pháp tốt đẹp 4 u

ghi lớp tĩnh này

public delegate void OnDeserializedEventArgs(object itemDeserialized, string xmlSource); 
public delegate void OnDeserializedFailedEventArgs(string xmlSource); 
public static class SerializationServices 
{ 
    public static event OnDeserializedEventArgs OnDeserializedEvent; 
    public static event OnDeserializedFailedEventArgs OnDeserializedFailedEvent; 

    public static T Deserialize<T>(this string item) where T : class 
    { 
     XmlSerializer ser = new XmlSerializer(item.GetType()); 
     StringReader sr = new StringReader(item); 
     var obj = ser.Deserialize(sr); 

     if (obj is T) 
     { 
      if (OnDeserializedEvent != null) 
       OnDeserializedEvent(obj, item); 

      return obj as T; 
     } 

     if (OnDeserializedFailedEvent != null) 
      OnDeserializedFailedEvent(item); 

     //callback - invalid event 
     return null; 
    } 
} 

và sau đó sử dụng nó với mã này

public class MyDesrializedClass 
{ 
    //put some properties here... 
} 
class Program 
{ 
    static void Main(string[] args) 
    { 
     SerializationServices.OnDeserializedEvent += SerializationServices_OnDeserializedEvent; 
     SerializationServices.OnDeserializedFailedEvent += SerializationServices_OnDeserializedFailedEvent; 

     string someXml = string.Empty; //replace this with something... 
     MyDesrializedClass deserializedClass = someXml.Deserialize<MyDesrializedClass>(); 
    } 

    private static void SerializationServices_OnDeserializedFailedEvent(string xmlSource) 
    { 
     //will get here before 'deserializedClass' will get it's results 
    } 

    private static void SerializationServices_OnDeserializedEvent(object itemDeserialized, string xmlSource) 
    { 
     //will get here before 'deserializedClass' will get it's results 
    } 
} 

nếu u dán các mã vào các không gian tên khác nhau, đừng quên thêm 'using ...' otherwize u wont xem phương thức deserialize trong contexial program t

Tzahi

+0

thông báo rằng giải pháp của tôi không yêu cầu u kế thừa bất kỳ lớp cơ sở nào và không yêu cầu u khởi tạo các phiên bản mới – Tzahi

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