2010-03-23 39 views
3

在我們的應用程序中,我們需要以propertyName,propertyValue,propertyType的形式將對象的屬性保存到同一個數據庫表中,而不管對象的類型如何。我們決定使用XamlWriter來保存給定對象的所有屬性。然後,我們使用XamlReader加載創建的XAML,並將其重新轉換爲屬性的值。這在大部分情況下工作正常,除了空字符串。 XamlWriter將保存一個空字符串,如下所示。XamlReader.Parse在空字符串上拋出異常

<String xmlns="clr-namespace:System;assembly=mscorlib" xml:space="preserve" /> 

的XamlReader看到這個字符串,並試圖創建一個字符串,但找不到在String對象使用一個空的構造,所以它拋出一個ParserException。

我能想到的唯一解決方法是,如果它是空字符串,則不會實際保存屬性。然後,當我加載屬性時,我可以檢查哪些不存在,這意味着它們將是空字符串。

有沒有這方面的一些解決方法,或者是否有更好的方法來做到這一點?

回答

0

嘗試序列化字符串時,我們遇到了類似的問題。我們解決這個問題的唯一方法是創建一個具有合適構造函數的結構體或類。然後我們使用這種類型來加載和保存我們的字符串值。

0

我也遇到了這個問題,並搜索了網絡的解決方案,但找不到一個。

我解決它由(與來自的XamlWriter的輸出饋送FixSavedXaml)檢查保存的XML並固定空字符串,像這樣:

static string FixSavedXaml(string xaml) 
    { 
     bool isFixed = false; 
     var xmlDocument = new System.Xml.XmlDocument(); 
     xmlDocument.LoadXml(xaml); 
     FixSavedXmlElement(xmlDocument.DocumentElement, ref isFixed); 
     if (isFixed) // Only bothering with generating new xml if something was fixed 
     { 
      StringBuilder xmlStringBuilder = new StringBuilder(); 
      var settings = new System.Xml.XmlWriterSettings(); 
      settings.Indent = false; 
      settings.OmitXmlDeclaration = true; 

      using (var xmlWriter = System.Xml.XmlWriter.Create(xmlStringBuilder, settings)) 
      { 
       xmlDocument.Save(xmlWriter); 
      } 

      return xmlStringBuilder.ToString(); 
     } 

     return xaml; 
    } 

    static void FixSavedXmlElement(System.Xml.XmlElement xmlElement, ref bool isFixed) 
    { 
     // Empty strings are written as self-closed element by XamlWriter, 
     // and the XamlReader can not handle this because it can not find an empty constructor and throws an exception. 
     // To fix this we change it to use start and end tag instead (by setting IsEmpty to false on the XmlElement). 
     if (xmlElement.LocalName == "String" && 
      xmlElement.NamespaceURI == "clr-namespace:System;assembly=mscorlib") 
     { 
      xmlElement.IsEmpty = false; 
      isFixed = true; 
     } 

     foreach (var childElement in xmlElement.ChildNodes.OfType<System.Xml.XmlElement>()) 
     { 
      FixSavedXmlElement(childElement, ref isFixed); 
     } 
    }