我有一个TimeDetails类,它有一组TimeRanges。 此类已序列化并存储到DB。
以前的列表是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 :(得分:0)
为了向后兼容,您应该保留DateTimeRange
的列表 - 它可以存储基本类型和派生类型。
public List<DateTimeRange> TimeList { get; set; }
在xml中使用type
属性来标识AvailableTimeRange
个实例:
<DateTimeRange i:type=\"AvailableTimeRange\"><From>2016-07-12T08:00:00</From><To>2016-07-12T09:00:00</To><SomeId>100</SomeId></DateTimeRange>
注意 - xml中的成员顺序很重要。