2010-03-23 4 views
3

Dans notre application, nous devons enregistrer les propriétés des objets dans la même table de base de données, quel que soit le type d'objet, sous la forme propertyName, propertyValue, propertyType. Nous avons décidé d'utiliser XamlWriter pour sauvegarder toutes les propriétés de l'objet donné. Nous utilisons ensuite XamlReader pour charger le code XAML créé et le restituer dans la valeur de la propriété. Cela fonctionne très bien, sauf pour les chaînes vides. Le XamlWriter sauvegardera une chaîne vide comme ci-dessous.XamlReader.Parse renvoie une exception sur la chaîne vide

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

Le XamlReader voit cette chaîne et tente de créer une chaîne, mais ne peut pas trouver un constructeur vide dans l'objet String à utiliser, il jette un ParserException.

La seule solution à laquelle je peux penser est de ne pas enregistrer la propriété si elle est une chaîne vide. Ensuite, au fur et à mesure que je charge les propriétés, je peux vérifier celles qui n'existaient pas, ce qui signifie qu'elles auraient été des chaînes vides.

Y at-il une solution de contournement pour cela, ou y a-t-il encore une meilleure façon de le faire?

Répondre

0

Nous avons rencontré un problème similaire lors de la tentative de sérialisation des chaînes. La seule façon de résoudre ce problème était de créer une structure ou une classe StringWrapper possédant les constructeurs appropriés. Nous avons ensuite utilisé ce type pour charger et enregistrer nos valeurs de chaîne.

0

J'ai également eu le problème et j'ai cherché sur le Web pour trouver une solution mais je n'ai pas pu en trouver un.

Je l'ai résolu en inspectant le XML enregistré et fixant les chaînes vides, comme celui-ci (FixSavedXaml d'alimentation avec la sortie de XamlWriter):

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); 
     } 
    } 
Questions connexes