我们有一个Windows应用商店应用程序,它使用XML进行请求/响应与我们的服务器通信,并使用XmlSerializer进行序列化。我们遇到的问题是我们的一个类型可以包含任意XML作为其属性之一。在非WinRT应用程序中,用法就是。
public sealed ItemExtension {
[XmlAttribute("source")]
public string Source {get;set;}
[XmlAnyElement]
public XmlElement[] Data {get;set;}
}
这将允许我们在数据库中使用XML,如
<extension source="foo"><randomXml><data/></randomXml></extension>
在WinRT中,不包含XmlElement,System.Xml.XmlElement不存在且Windows.Data.Xml.Dom.XmlElement不兼容。文档提到XElement,但XElement不是受支持的WinRT类型,因此如果我尝试使用它,WinRT项目将无法编译。
这是Windows应用商店应用程序的错误还是有足够的解决方法?
感谢。
答案 0 :(得分:0)
到目前为止,我只是找到了一个能够让它工作的黑客。如果我们使用
[XmlAnyElement]
public object Data {get;set;}
这将正确地反序列化现有数据。在检查它时,它在调试器中是System.Xml.XmlElement类型,它在WinRT中不公开。所以没有办法直接设置它。由于我们发现XmlSerializer可以实例化并访问System.Xml.XmlElement,我们使用它来处理设置它,方法是接受一个object / xml片段,将其包装在容器xml中,以获得包含[XmlAnyElement]并调用Deserialize的包装类型它让XmlSerializer实例化一个XmlElement,然后可以在你希望序列化的目标对象上设置它。
为了获取数据,因为尝试读取此属性会在UI层中引发异常,并且尝试访问InnerXml / OuterXml也会抛出异常,我们将使用XmlSerializer将XmlElement序列化为字符串,然后可以随意使用它。
public sealed class XmlAnyElementContainer
{
[XmlAnyElement]
public object Data { get; set; }
}
public void SetData(object extensionObject)
{
var objectSerializer = new XmlSerializer(extensionObject.GetType());
var settings = new XmlWriterSettings()
{
Indent = false,
OmitXmlDeclaration = true
};
var sb = new StringBuilder();
using (var xmlWriter = XmlWriter.Create(sb, settings))
{
objectSerializer.Serialize(xmlWriter, extensionObject);
}
string objectXml = sb.ToString();
string newXml = "<XmlAnyElementContainer>" + objectXml + "</XmlAnyElementContainer>";
var xmlAnySerializer = new XmlSerializer(typeof(XmlAnyElementContainer));
using (var sr = new StringReader(newXml))
{
[TargetPropertyToSerialize] = (xmlAnySerializer.Deserialize(sr) as XmlAnyElementContainer).Data;
}
}