2014-01-21 38 views
0

我們有一個Windows應用商店應用程序,它與我們的服務器使用XML進行請求/響應,並與XmlSerializer進行序列化。我們遇到的問題是我們的一個類型可以包含任意的XML作爲它的一個屬性。在非WinRT應用程序中,使用會是這樣。WinRT XmlAnyElement和序列化

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

如果使用'[XmlAnyElement] public object [] Data {get;組; '',這是否有效? – WiredPrairie

+0

是的這適用於反序列化。我之前得到了這個工作,這很奇怪......所以在調試器中,當我反序列化現有數據時,它將是System.Xml.XmlElement類型。然後我可以做一些hackery,使用反序列化器來實例化XmlElement以保存新數據。 但問題是,要真正讀取/使用數據,這是不可能的。 WinRT中不存在System.Xml.XmlElement,即使它在調試器中工作良好。如果我把它傳遞給javascript層,會拋出一個異常,因爲我看不到System.Xml.XmlElement,所以我無法投射/使用它。 – littlepod

+0

然後我嘗試使用反射,並調用OuterXml屬性並傳回一個字符串。 PropertyInfo property = Data.GetType()。GetRuntimeProperty(「OuterXml」); var xmlString = property.GetValue(Data)as String; return xmlString; 這會拋出一個異常「The API'System.Xml.XmlNode.get_OuterXml()'無法在當前平臺上使用」 不知道我現在留下了什麼。 – littlepod

回答

0

到目前爲止,我只找到了一個破解得到這個工作。如果我們使用

這將正確地反序列化現有數據。在調試器中檢查它時,它的類型是System.Xml.XmlElement,它不在WinRT中公開。所以沒有辦法直接設置它。由於我們發現XmlSerializer可以實例化並訪問System.Xml.XmlElement,因此我們使用它來接收對象/ xml片段,將其封裝在容器xml中,以包裝[XmlAnyElement]並調用Deserialize on它讓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; 
    } 
}