2016-07-12 5 views
0

私はTimeRangesのコレクションを持つTimeDetailsクラスを持っています。 このクラスはシリアル化され、DBに格納されます。DatacontractSerializerは基底型を継承型にシリアル化しません

以前は、DateTimeRange型のリストでした。今、私はそれに新しいプロパティ(SomeId)を追加する必要があります。そこで私はそれをAvailableTimeRangeに継承し、SomeIdプロパティを追加しました。 (私はそのが他の場所で使用されるため、そのままDateTimeRangeを残している。

古い行(DateTimeRangeプロパティ型を有する)の直列化復元に失敗した。

ここでは私のユニットテストは

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Runtime.Serialization; 
using mynamespace; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 

namespace UnitTestProject1 
{ 
    [TestClass] 
    public class UnitTest1 
    { 
     [TestMethod] 
     public void With_DateTimeRange() 
     { 
      var xml = "<TimeDetails xmlns=\"http://schemas.datacontract.org/2004/07/mynamespace\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" + 
         "<TimeList>" + 
         "<DateTimeRange><From>2016-01-21T08:00:00</From><To>2016-01-21T11:00:00</To></DateTimeRange>" + 
         "<DateTimeRange><From>2016-07-12T06:00:00</From><To>2016-07-12T09:00:00</To></DateTimeRange>" + 
         "</TimeList>" + 
         "</TimeDetails>"; 
      TimeDetails details = TimeDetails.FromXml(xml); 
      Assert.AreEqual(2, details.TimeList.Count); 
     } 

     [TestMethod] 
     public void With_AvailableTimeRange() 
     { 
      var xml = 
      "<TimeDetails xmlns=\"http://schemas.datacontract.org/2004/07/mynamespace\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">"+ 
      "<TimeList>"+ 
      "<AvailableTimeRange><From>2016-07-12T08:00:00</From><SomeId>100</SomeId><To>2016-07-12T09:00:00</To></AvailableTimeRange>"+ 
      "</TimeList></TimeDetails>"; 

      var details = TimeDetails.FromXml(xml); 
      Assert.AreEqual(1, details.TimeList.Count); 
      Assert.IsTrue(details.TimeList[0] is AvailableTimeRange); 
      Assert.AreEqual(100, (details.TimeList[0] as AvailableTimeRange).SomeId); 
     } 
    } 
} 

namespace mynamespace 
{ 
    public class TimeDetails 
    { 
     public List<AvailableTimeRange> TimeList { get; set; } 

     public static TimeDetails FromXml(string xml) 
     { 
      if (String.IsNullOrWhiteSpace(xml)) 
       return null; 

      TimeDetails timeDetails; 
      byte[] data = System.Text.Encoding.UTF8.GetBytes(xml); 
      using (MemoryStream ms = new MemoryStream(data)) 
      { 
       DataContractSerializer serializer = new DataContractSerializer(typeof (TimeDetails), 
        new[] {typeof (AvailableTimeRange), typeof (DateTimeRange)}); 
       timeDetails = (TimeDetails) serializer.ReadObject(ms); 
      } 
      return timeDetails; 
     } 

    } 
    public class DateTimeRange 
    { 
     public DateTime From { get; set; } 
     public DateTime To { get; set; } 
    } 

    public class AvailableTimeRange : DateTimeRange 
    { 
     public long? SomeId { get; set; } 
    } 
} 

答えて

0
です後方互換性のため

あなたはDateTimeRangeのリストを残す必要があります - それはベースと派生型の両方を格納できるXML使用で

public List<DateTimeRange> TimeList { get; set; } 

を。 XML内のメンバーの順序が重要である - 用心

<DateTimeRange i:type=\"AvailableTimeRange\"><From>2016-07-12T08:00:00</From><To>2016-07-12T09:00:00</To><SomeId>100</SomeId></DateTimeRange> 

AvailableTimeRangeインスタンスを識別するために属性。

+0

これは機能します!どうもありがとう – user2100334

関連する問題