gpt4 book ai didi

c# - DataContract 向后兼容序列化

转载 作者:行者123 更新时间:2023-11-30 17:13:12 28 4
gpt4 key购买 nike

我上过这样的课:

[DataContract(Namespace = "blah")]
public class Item
{
[DataMember(Order = 0)]
public int Index { get; set; }

[DataMember(Order = 1)]
public Uri ItemSource { get; set; }

[DataMember(Order = 2)]
public Uri ErrorSource { get; set; }
}

我有很多它的序列化副本(在文件中)(包括一些生产文件),现在我的任务是将此类更改为以下内容:

[DataContract(Namespace = "blah")]
public class Item
{
[DataMember(Order = 0)]
public int Index { get; set; }

[DataMember(Order = 1)]
public ItemSourcesCollection Sources { get; set; }
}

ItemSourcesCollection 在哪里

[CollectionDataContract(ItemName = "ItemSourceItem", Namespace = "blah")]
public class ItemSourcesCollection : List<ItemSource> {}

ItemSource 在哪里

[DataContract]
public class ItemSource
{
[DataMember]
public Uri SourcePath { get; set; }

[DataMember]
public ItemSourceType Type { get; set; }
}

ItemSourceType 在哪里

[Serializable]
public enum ItemSourceType
{
Data,

Errors
}

问题是向后兼容性。旧的序列化项目是否有可能被正确反序列化?迁移具有向后兼容性的数据协定的最佳实践/模式是什么?

最佳答案

是的,经过一些思考是可能的。我正在做以下事情以在反序列化期间手动检查以前的版本。

第一次使用IExtensibleDataObject对于 Item 类:

[DataContract(Namespace = "blah")]
public class Item : IExtensibleDataObject
{
[DataMember(Order = 0)]
public int Index { get; set; }

[DataMember(Order = 1)]
public ItemSourcesCollection Sources { get; set; }
}

现在是反序列化方法的棘手问题:

    /// <summary>
/// The deserialized.
/// </summary>
/// <param name="context">
/// The streaming context.
/// </param>
[OnDeserialized]
private void Deserialized(StreamingContext context)
{
// reflection for backward compatibilty only
if (this.ExtensionData == null)
{
return;
}

IList members = this.CheckForExtensionDataMembers();

if (members == null)
{
return;
}

string value = this.GetExtensionDataMemberValue(members, "ItemSource");
// do something with value

value = this.GetExtensionDataMemberValue(members, "ErrorSource");
// do something with value

}

/// <summary>
/// The check for extension data members.
/// </summary>
/// <returns>
/// Thel list of extension data memebers.
/// </returns>
private IList CheckForExtensionDataMembers()
{
PropertyInfo membersProperty = typeof(ExtensionDataObject).GetProperty(
"Members", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);

var members = (IList)membersProperty.GetValue(this.ExtensionData, null);

if (members == null || members.Count <= 0)
{
return null;
}

return members;
}

/// <summary>
/// The get extension data member value.
/// </summary>
/// <param name="members">
/// The members.
/// </param>
/// <param name="dataMemberName">
/// The data member name.
/// </param>
/// <returns>
/// Returns extension data member value.
/// </returns>
private string GetExtensionDataMemberValue(IList members, string dataMemberName)
{
string innerValue = null;

object member =
members.Cast<object>().FirstOrDefault(
m =>
((string)m.GetType().GetProperty("Name", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public).GetValue(m, null)).Equals(
dataMemberName, StringComparison.InvariantCultureIgnoreCase));

if (member != null)
{
PropertyInfo valueProperty = member.GetType().GetProperty("Value", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);

object value = valueProperty.GetValue(member, null);

PropertyInfo innerValueProperty = value.GetType().GetProperty("Value", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Public);

object tmp = innerValueProperty.GetValue(value, null);

var s = tmp as string;
if (s != null)
{
innerValue = s;
}
}

return innerValue;
}

以上所有内容都将在 Item 类中。

关于c# - DataContract 向后兼容序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9992469/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com