我想创建一个可序列化的类来表示可以包含任意消息内容的xml信封。示例xml(简化)如下:
<?xml version="1.0" encoding="utf-8"?>
<Envelope>
<MessageA>
<Url></Url>
</MessageA>
</Envelope>
<?xml version="1.0" encoding="utf-8"?>
<Envelope>
<MessageB>
<Value></Value>
</MessageB>
</Envelope>
我的想法是使用通用的信封类来处理这个问题:
[Serializable]
[XmlRoot(ElementName="Envelope")]
public class Envelope<TContent> where TContent : new()
{
public Envelope()
{
Content = new TContent();
}
public TContent Content { get; set; }
}
[Serializable]
public class MessageA
{
public string Url { get; set; }
}
[Serializable]
public class MessageB
{
public string Value { get; set; }
}
这些可以序列化:
var envelope = new Envelope<MessageA>();
envelope.Content.Url = "http://www.contoso.com";
string xml = envelope.ToXml();
但是,我得到以下内容,而不是我想要的xml消息(上面的示例)。如何更改类或序列化过程以将Content元素重命名为Message本身的名称?
<?xml version="1.0" encoding="utf-8"?>
<Envelope>
<Content>
<Url>http://www.contoso.com</Url>
</Content>
</Envelope>
答案 0 :(得分:0)
发现XmlAttributeOverrides类有针对此问题的解决方案。将以下方法添加到Envelope类会导致ToXml()扩展方法根据需要序列化对象。
public string ToXml()
{
return ToXml(typeof(TContent).Name);
}
public string ToXml(string contentElementName)
{
XmlElementAttribute element = new XmlElementAttribute(contentElementName, typeof(TContent));
XmlAttributes attributes = new XmlAttributes();
attributes.XmlElements.Add(element);
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
overrides.Add(typeof(Envelope<TContent>), "Content", attributes);
return ToXml(this, overrides);
}
public string ToXml(Envelope<TContent> value, XmlAttributeOverrides overrides)
{
using (var sw = new Utf8StringWriter())
{
var settings = new XmlWriterSettings
{
OmitXmlDeclaration = omitXmlDeclaration,
Indent = true
};
XmlSerializer xs = new XmlSerializer(typeof(Envelope<TContent>), overrides);
using (XmlWriter writer = XmlWriter.Create(sw, settings))
{
xs.Serialize(writer, value);
}
return sw.ToString();
}
}