在我们的应用程序中,我们需要以propertyName,propertyValue,propertyType的形式将对象的属性保存到同一个数据库表中,而不管对象的类型如何。我们决定使用XamlWriter来保存所有给定对象的属性。然后,我们使用XamlReader加载已创建的XAML,并将其重新转换为属性的值。除了空字符串之外,这在大多数情况下都可以正常工作。 XamlWriter将保存一个空字符串,如下所示。
<String xmlns="clr-namespace:System;assembly=mscorlib" xml:space="preserve" />
XamlReader看到这个字符串并尝试创建一个字符串,但是在String对象中找不到要使用的空构造函数,因此它会抛出一个ParserException。
我能想到的唯一解决方法是,如果属性为空字符串,则不实际保存该属性。然后,当我加载属性时,我可以检查哪些不存在,这意味着它们将是空字符串。
是否有一些解决方法,或者有更好的方法吗?
答案 0 :(得分:0)
在尝试序列化字符串时,我们遇到了类似的问题。我们解决它的唯一方法是创建一个具有适当构造函数的StringWrapper
结构或类。然后,我们使用此类型加载并保存字符串值。
答案 1 :(得分:0)
我也遇到了问题,并在网上搜索了一个解决方案,但找不到一个。
我通过检查保存的XML并修复空字符串来解决这个问题(使用XamlWriter的输出提供FixSavedXaml):
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);
}
}