2011-10-09 21 views
7

Tôi có một chút vấn đề với việc tuần tự hóa đối tượng TimeZoneInfo. Tôi đã cố gắng sử dụng TimeZoneInfo biến trong hợp đồng dữ liệu cho dịch vụ WCF nhưng serialization đã thất bại. Vì vậy, tôi đã viết đoạn mã nhỏ này để kiểm tra sự tuần tự hóa. Dưới đây là một những gì tôi làm:C# TimeZoneInfo serialization

 var fileName = "tmp.xml"; 
     var tz = TimeZoneInfo.Local; 
     var dataSer = new DataContractSerializer(typeof(TimeZoneInfo)); 

     try 
     { 
      using (var xml = new FileStream(fileName, FileMode.Create)) 
      { 
       dataSer.WriteObject(xml, tz); 
      } 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e.Message); 
     } 

Bây giờ, khi tôi gọi writeObject phương pháp nó ném một ngoại lệ:

Type 'System.TimeZoneInfo+AdjustmentRule[]' with data contract name 'ArrayOfTimeZoneInfo.AdjustmentRule:http://schemas.datacontract.org/2004/07/System' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.

Nếu tôi cố gắng thêm [KnownType (typeof (System.TimeZoneInfo.AdjustmentRule []))] đến lớp tôi nhận được cùng một lỗi. Và nếu tôi thêm dòng này vào giao diện hợp đồng dữ liệu của tôi tôi nhận biên dịch báo lỗi:

Error 1 'System.TimeZoneInfo.AdjustmentRule' is inaccessible due to its protection level

và theo lớp tài liệu TimeZoneInfo thực hiện ISerializable vì vậy nó nên serialize theo mặc định.

Có ai cho tôi biết tôi đang làm gì sai ở đây không? Tôi sẽ đánh giá cao sự giúp đỡ nào.

Cảm ơn.

Trả lời

6

Tôi không chắc chắn lý do tại sao nó không chỉ tuần tự một cách đơn giản, nhưng bạn có xem xét việc chỉ cần serialize các ID? Đó có thể là khá hiệu quả hơn - và đơn giản hơn! - hơn serializing tất cả các thông tin bên trong, và nên được tốt miễn là cả hai hệ thống có múi giờ đó.

EDIT: Lưu ý rằng thao tác này sẽ không hoạt động với múi giờ tùy chỉnh, bạn nên xem ToSerializedString như được lưu ý ở nơi khác.

+1

Vâng, tôi có nghĩa là một công việc xung quanh tôi sẽ phải làm một cái gì đó thuộc loại đó. Nhưng tôi muốn có biến mạnh mẽ gõ và nói chung tôi là loại mystified là tại sao điều này không hoạt động. Điểm của lớp là ISerializable nếu tôi không thể serialize nó? – RedOctober

+1

@RedOctober: Tôi không biết - điều đó có vẻ kỳ quặc. Tôi không biết đủ về WCF để biết liệu DataContractSerializer sử dụng cùng một định dạng như BinarySerializer bình thường mà tôi * tin * những gì ISerializable là về. Lưu ý rằng nếu bạn tuần tự hóa chỉ ID, thì khi bạn tìm nạp lại múi giờ, bạn sẽ nhận được thông tin cập nhật nhất từ ​​hệ điều hành, thay vì chỉ những gì đã được biết tại thời điểm tuần tự hóa. Cho dù đây là một điều tốt hay không phụ thuộc vào tình hình chính xác của bạn, tất nhiên. –

+1

1. Hành vi này trông giống như một lỗi trong khuôn khổ. 2. ID sẽ không đủ khi bạn nhận được múi giờ tùy chỉnh. Tôi đã sử dụng phương pháp ToSerializedString như giải pháp thay thế. (http://msdn.microsoft.com/en-us/library/system.timezoneinfo.toserializedstring(v=vs.100).aspx) –

1

Tôi cũng không chắc chắn lý do. Như Jon đã đề xuất một thuộc tính proxy với ID là có lẽ là con đường để đi.

Ngoài ra, nếu bạn thực sự cần truyền nội dung của TimeZoneInfo và hỗ trợ các vùng tùy chỉnh, bạn nên sử dụng thuộc tính proxy bao bọc ToSerializedString()FromSerializedString().