在本文的帮助下,我能够创建一个解决方案。唯一需要注意的是它需要DataContractSerializer
而不是System.Xml.Serialization
. 这是我的实现的dotnetfiddle。
public class DataContractXmlSerializer<T>
{
private readonly DataContractSerializer _dataContractSerializer;
public DataContractXmlSerializer()
{
_ = Attribute.GetCustomAttribute(typeof(T), typeof(DataContractAttribute))
?? throw new InvalidOperationException($"Type {typeof(T)} does not contain Attribute of type {typeof(DataContractAttribute)}.");
_dataContractSerializer = new DataContractSerializer(typeof(T));
}
public T Deserialize(string xml)
{
var xmlData = Encoding.UTF8.GetBytes(xml);
var xmlStream = new MemoryStream(xmlData);
using (XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(xmlStream, Encoding.UTF8, new XmlDictionaryReaderQuotas(), null))
{
return (T)_dataContractSerializer.ReadObject(reader);
}
}
public string Serialize(T obj)
{
using (MemoryStream memoryStream = new MemoryStream())
{
_dataContractSerializer.WriteObject(memoryStream, obj);
return Encoding.UTF8.GetString(memoryStream.ToArray());
}
}
}
更新如果必须使用System.Xml.Serialization
,我建议使用分层方法在可变模型和不可变模型之间进行转换。这是我对这种方法的dotnetfiddle。
public class ModelXmlSerializer : ImmutableXmlSerializer<ImmutableModel, Model>
{
protected override ImmutableModel ConvertToImmutable(Model mutable)
{
return new ImmutableModel(mutable);
}
protected override Model ConvertToMutable(ImmutableModel immutable)
{
return new Model(immutable);
}
}
public abstract class ImmutableXmlSerializer<TImmutable, TMutable>
{
private readonly MyXmlSerializer<TMutable> _xmlSerializer;
public ImmutableXmlSerializer()
{
_xmlSerializer = new MyXmlSerializer<TMutable>();
}
public TImmutable Deserialize(string xml)
{
return ConvertToImmutable(_xmlSerializer.Deserialize(xml));
}
public string Serialize(TImmutable obj)
{
return _xmlSerializer.Serialize(ConvertToMutable(obj));
}
protected abstract TImmutable ConvertToImmutable(TMutable mutable);
protected abstract TMutable ConvertToMutable(TImmutable immutable);
}
public class MyXmlSerializer<T>
{
private readonly XmlSerializer _xmlSerializer;
public MyXmlSerializer()
{
_xmlSerializer = new XmlSerializer(typeof(T));
}
public T Deserialize(string xml)
{
using (TextReader reader = new StringReader(xml))
{
return (T)_xmlSerializer.Deserialize(reader);
}
}
public string Serialize(T obj)
{
var builder = new StringBuilder();
using (TextWriter writer = new StringWriter(builder))
{
_xmlSerializer.Serialize(writer, obj);
}
return builder.ToString();
}
}
此方法不太通用,因为它需要您为每种模型类型创建映射逻辑。您可以使用 AutoMapper 之类的工具简化该过程,但我更喜欢手动执行此操作。