Windows runtime WinRT XmlAnyElement和序列化

Windows runtime WinRT XmlAnyElement和序列化,windows-runtime,xml-serialization,xmlanyelement,Windows Runtime,Xml Serialization,Xmlanyelement,我们有一个Windows应用商店应用程序,该应用程序使用XML与服务器进行通信,用于请求/响应,并使用XmlSerializer进行序列化。我们遇到的问题是,我们的一个类型可以包含任意XML作为其属性之一。在非WinRT应用程序中,使用情况可能会有所不同 public sealed ItemExtension { [XmlAttribute("source")] public string Source {get;set;} [XmlAnyElement] pu

我们有一个Windows应用商店应用程序,该应用程序使用XML与服务器进行通信,用于请求/响应,并使用XmlSerializer进行序列化。我们遇到的问题是,我们的一个类型可以包含任意XML作为其属性之一。在非WinRT应用程序中,使用情况可能会有所不同

public sealed ItemExtension {
    [XmlAttribute("source")]
    public string Source {get;set;}

    [XmlAnyElement]
    public XmlElement[] Data {get;set;}
}
这将允许我们在数据库中像

<extension source="foo"><randomXml><data/></randomXml></extension>

在WinRT中,不包括XmlElement,System.Xml.XmlElement不存在,并且Windows.Data.Xml.Dom.XmlElement不兼容。文档中提到了XElement,但XElement不是受支持的WinRT类型,因此如果我尝试使用它,WinRT项目将无法编译

这是Windows应用商店应用程序的一个bug还是有足够的解决方法


谢谢。

到目前为止,我只找到了一种方法来让它工作。如果我们使用

[XmlAnyElement]
public object Data {get;set;}
这将正确地反序列化现有数据。在调试器中检查时,它的类型为System.Xml.XmlElement,在WinRT中未公开。所以没有办法直接设置这个。因为我们发现XmlSerializer可以实例化和访问System.Xml.XmlElement,所以我们使用它来处理设置它,方法是接收一个对象/Xml片段,将其包装在容器Xml中,作为包含[XmlAnyElement]的包装器类型,并对其调用反序列化以让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;
    }
}
公共密封类xmlanyementcontainer
{
[xmlanyement]
公共对象数据{get;set;}
}
public void SetData(对象扩展对象)
{
var objectSerializer=新的XmlSerializer(extensionObject.GetType());
var设置=新的XmlWriterSettings()
{
缩进=假,
OmitXmlDeclaration=true
};
var sb=新的StringBuilder();
使用(var xmlWriter=xmlWriter.Create(sb,设置))
{
序列化(xmlWriter,extensionObject);
}
字符串objectXml=sb.ToString();
字符串newXml=”“+objectXml+”;
var xmlAnySerializer=新的XmlSerializer(typeof(XmlAnyElementContainer));
使用(var sr=newstringreader(newXml))
{
[TargetPropertyToSerialize]=(xmlAnySerializer.Deserialize(sr)为XmlAnyElementContainer)。数据;
}
}

如果使用
[xmlanyement]public object[]Data{get;set;}
,这是否有效?是的,这适用于反序列化。我刚开始工作,很奇怪。。。因此,在调试器中,当我反序列化现有数据时,它将是System.Xml.XmlElement类型。然后我可以做一些黑客操作,使用反序列化程序,实例化XmlElement以保存新数据。但问题是要真正读取/使用数据是不可能的。System.Xml.XmlElement在WinRT中不存在,即使它在调试器中工作得很好。如果我将其传递到javascript层,则会引发异常,因为我看不到System.Xml.XmlElement,所以无论如何我都无法在中强制转换/使用它。然后我尝试使用反射,只调用OuterXml属性并传递一个字符串。PropertyInfo property=Data.GetType().GetRuntimeProperty(“OuterXml”);var xmlString=property.GetValue(数据)作为字符串;返回xmlString;这引发了一个异常“API'System.Xml.XmlNode.get_OuterXml()”无法在当前平台上使用“不确定我现在还剩下什么。好吧,我让它工作了,反序列化的黑客程序也一样,我可以再次使用它,将XmlElement重新序列化为字符串,并输出原始Xml。。。我希望有更好的方法来实现这一点。您是否已锁定使用
XmlSerializer