為簡單起見,假設我有這個類:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
我使用以下兩種方法進行序列化/反序列化:
public void Serialize(Person person, string outputFilePath)
{
using (var stream =
new FileStream(outputFilePath, FileMode.Create, FileAccess.Write))
{
var serializer = new XmlSerializer(person.GetType());
serializer.Serialize(stream, person);
}
}
public Person Deserialize(string filePath)
{
using (var stream = new FileStream(filePath, FileMode.Open))
{
var serializer = new XmlSerializer(typeof(Person));
return (Person)serializer.Deserialize(stream);
}
}
現在,假設我將一些Person物件序列化為 XML 檔案,然后重命名Person該類的一個或多個屬性:
// Renamed from `Name`
public string FullName { get; set; }
我的目標是允許程式仍然從那些具有Name元素的舊 XML 檔案中反序列化,而不是FullName
在這里XmlElementAttribute無濟于事:
// If I do this, I can't deserialize from files created after
// the property has been renamed.
[XmlElement("Name")]
public string FullName { get; set; }
如果我可以支持多個舊名稱,那將是理想的,也許使用一些屬性。例如,
[XmlAlternateDeserializationElement("Name")]
[XmlAlternateDeserializationElement("Label")]
public string FullName { get; set; }
但任何其他方式就足夠了。我怎樣才能做到這一點?
uj5u.com熱心網友回復:
您可以利用UnknownElement / UnknownAttribute事件XmlSerializer來處理舊的元素名稱或屬性名稱:
var serializer = new XmlSerializer(typeof(Person));
serializer.UnknownElement = (sender, e) =>
{
var person = (Person)e.ObjectBeingDeserialized;
if (e.Element.Name == "Name")
{
person.FullName = e.Element.InnerText;
}
};
這使您的實際資料類保持干凈,并將兼容性代碼集中在序列化方法中。
uj5u.com熱心網友回復:
下面顯示了當一個或多個屬性名稱發生更改時如何反序列化 XML 檔案名。
注意:在下面的代碼中,當 XML 被序列化時,它將以較新的格式保存。
XML - 原始
<Person>
<Id>1</Id>
<Name>John Smith</Name>
<City>Some City</City>
</Person>
XmlPerson 原件:
using System.Xml.Serialization;
namespace XmlSerializationRenamedProperty
{
[XmlRoot(ElementName = "Person", IsNullable = false)]
public class XmlPersonOriginal
{
public int Id { get; set; }
public string Name { get; set; }
public string City { get; set; }
public string StateOrProvince { get; set; }
}
}
連載
public static void SerializeObjectToXMLFile(object obj, string xmlFilename)
{
using (System.IO.TextWriter xmlStream = new System.IO.StreamWriter(xmlFilename))
{
System.Xml.Serialization.XmlSerializerNamespaces ns = new System.Xml.Serialization.XmlSerializerNamespaces();
ns.Add(string.Empty, "urn:none");
//create new instance
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
//write to XML file
serializer.Serialize(xmlStream, obj, ns);
}
}
用法(序列化):
string filename = @"C:\Temp\Person.xml";
XmlPersonOriginal person = new XmlPersonOriginal() { Id = 1, Name = "John Smith", City = "Some City"};
Helper.SerializeObjectToXMLFile(person, filename);
反序列化
public static T DeserializeXMLFileToObject<T>(string xmlFilename)
{
T rObject = default(T);
using (System.IO.StreamReader xmlStream = new System.IO.StreamReader(xmlFilename))
{
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
rObject = (T)serializer.Deserialize(xmlStream);
}
return rObject;
}
用法(反序列化):
string filename = @"C:\Temp\Person.xml";
XmlPersonOriginal person = Helper.DeserializeXMLFileToObject<XmlPersonOriginal>(filename);
現在,如果決定將屬性名稱從 更改Name為FullName,則可以創建一個繼承自原始 (XmlPersonOriginal) 的新類 (XmlPerson_v2) 并覆寫任何已更改的屬性名稱。為了能夠覆寫該屬性,請在該屬性中添加關鍵字“virtual”。
XmlPerson 原件:
using System.Xml.Serialization;
namespace XmlSerializationRenamedProperty
{
[XmlRoot(ElementName = "Person", IsNullable = false)]
public class XmlPersonOriginal
{
public int Id { get; set; }
public virtual string Name { get; set; }
public string City { get; set; }
public string StateOrProvince { get; set; }
}
}
XmlPerson_v2:
using System;
using System.Xml.Serialization;
namespace XmlSerializationRenamedProperty
{
[XmlRoot(ElementName = "Person", IsNullable = false)]
public class XmlPerson_v2 : XmlPersonOriginal
{
public string FullName { get; set; }
#pragma warning disable CS0809
[XmlIgnore]
[Obsolete("Name is deprecated, use FullName instead.")]
public override string Name
{
get
{
return base.Name;
}
set
{
FullName = value;
}
}
}
}
用法(序列化):
string filename = @"C:\Temp\PersonModified.xml";
XmlPerson_v2 person = new XmlPerson_v2() { Id = 1, FullName = "John Smith", City = "Some City"};
Helper.SerializeObjectToXMLFile(person, filename);
用法(反序列化):
string filename = @"C:\Temp\Person.xml";
XmlPerson_v2 person = Helper.DeserializeXMLFileToObject<XmlPerson_v2>(filename);
用法(反序列化):
string filename = @"C:\Temp\PersonModified.xml";
XmlPerson_v2 person = Helper.DeserializeXMLFileToObject<XmlPerson_v2>(filename);
資源
- 如何將方法標記為過時或棄用?
- 過時的屬性類
- 抑制代碼分析違規
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/430775.html
