2009-04-02 11 views
8

Để kiểm soát nhiều hơn việc tuần tự hóa, tôi đã chuyển đổi một lớp từ [DataContract] thành [Serializable], triển khai cả GetObjectData và hàm tạo deserializing đặc biệt. Khi tôi làm điều này, XML được phát ra bây giờ có thông tin kiểu được áp dụng cho tất cả các phần tử. Tôi không muốn thông tin thừa này, và tôi tự hỏi làm thế nào để thông báo cho serializer không xuất nó.Khi sử dụng ISerializable với DataContractSerializer, làm cách nào để ngăn bộ nối tiếp xuất ra thông tin loại?

Dưới đây là đoạn code mẫu sử dụng [DataContract]:

[DataContract(Namespace = "")] 
class Test 
{ 
    public Test() { } 
    [DataMember] 
    public Nullable<int> NullableNumber = 7; 
    [DataMember] 
    public int Number = 5; 

    public static void Go() 
    { 
     var test = new Test(); 
     var dcs = new DataContractSerializer(typeof(Test)); 
     using (var s = new StreamWriter("test.xml")) 
     { 
      dcs.WriteObject(s.BaseStream, test); 
     } 
    }   
} 

này kết quả đầu ra XML sau (chú ý không có thông tin kiểu trên Nullable và Số - đây là kết quả mong muốn):

<Test xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
    <NullableNumber>7</NullableNumber> 
    <Number>5</Number> 
</Test> 

Nếu tôi sửa đổi mã ở trên như sau (thêm [Serializable],: ISerializable và hai phương thức tuần tự hóa):

[Serializable] 
class Test : ISerializable 
{ 
    public Test() { } 
    public Nullable<int> NullableNumber = 7; 
    public int Number = 5; 

    public static void Go() 
    { 
     var test = new Test(); 
     var dcs = new DataContractSerializer(typeof(Test)); 
     using (var s = new StreamWriter("test.xml")) 
     { 
      dcs.WriteObject(s.BaseStream, test); 
     } 
    }   
    public Test(SerializationInfo info, StreamingContext context) 
    { 
     NullableNumber = info.GetInt32("NullableNumber"); 
     Number = info.GetInt32("Number"); 
    } 

    public void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     info.AddValue("NullableNumber", NullableNumber); 
     info.AddValue("Number", Number); 
    } 
} 

Nó bây giờ phát ra XML sau đây. Lưu ý thông tin kiểu (i: type = "x: int") được thêm vào từng phần tử.

<Test xmlns="http://schemas.datacontract.org/2004/07/XMLSerialization" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:x="http://www.w3.org/2001/XMLSchema"> 
    <NullableNumber i:type="x:int" xmlns="">7</NullableNumber> 
    <Number i:type="x:int" xmlns="">5</Number> 
</Test> 

Tại sao lại thực hiện việc này? Làm thế nào để tôi ngừng làm việc đó?

Cảm ơn!

+0

Cảm ơn bạn đã đặt câu hỏi bởi vì nó đã giải đáp câu hỏi của tôi :-) Đối với "lý do" - trong ví dụ đầu tiên có một đảm bảo mỗi mục là trường, vì vậy bạn có thể nhận được loại trường chỉ bằng cách tìm kiếm ở kiểu 'Test'. Trong trường hợp thứ hai ** bạn ** nằm trong tầm kiểm soát, vì vậy những mục đó không phải là các trường, bạn có thể viết/đọc dữ liệu ngẫu nhiên. – astrowalker

Trả lời

0

Bạn có cần ISerializable tại đây không? Những gì đã được thường xuyên DataContractSerializer không cho bạn? Nếu bạn chuyển về điều này, nó sẽ hoạt động tốt. Về cơ bản, bằng cách triển khai serialization tùy chỉnh, dữ liệu không còn dựa trên hợp đồng - vì vậy, để bao gồm thông tin bổ sung này để đảm bảo rằng nó có thể hiểu được sau này.

Vì vậy: có lý do nào để triển khai ISerializable trong trường hợp này không?

+0

Tôi đã cắt bớt ví dụ để làm cho câu hỏi dễ dàng hơn. Tôi cần serialization tùy chỉnh vì lý do tôi không hiển thị ở đây. – Eric

+0

Trong số (danh sách dài) các lý do tôi cần serialization tùy chỉnh, lớn nhất là tôi cần có điều kiện xuất các thuộc tính nhất định dựa trên các thông tin khác. – Eric

+1

Tôi không hiểu nhận xét của bạn về "nó" có "để bao gồm thông tin bổ sung này". Thật vậy, ví dụ XML đầu tiên ở trên deserializes tốt với deserializer [Serializable], do đó deserializer không cần thông tin kiểu này. – Eric