gpt4 book ai didi

c# - 如何让 XamlReader.Parse 不抛出 "property does not exist"XamlParseException?

转载 作者:行者123 更新时间:2023-11-30 22:48:47 26 4
gpt4 key购买 nike

我正在使用 XAML 序列化一些对象,它在大多数情况下工作得很好。

我现在面临的问题是,当我更改数据结构时,所有旧对象都会产生如下所示的异常。我不介意这些值是否丢失。

有没有办法关闭这些异常,让 xaml 阅读器忽略未知属性?如果现在没有办法做到这一点,新的 System.Xaml 命名空间中是否有可以做到这一点的东西?

System.Windows.Markup.XamlParseException: The property 'BorderPadding' does not exist in XML namespace 'clr-namespace:TemplateGenerator;assembly=App_Code'. Line '1' Position '158'.
at System.Windows.Markup.XamlParser.ThrowExceptionWithLine(String message, Int32 lineNumber, Int32 linePosition)
at System.Windows.Markup.XamlParser.ThrowException(String id, String value1, String value2, Int32 lineNumber, Int32 linePosition)
at System.Windows.Markup.XamlParser.WriteUnknownAttribute(XamlUnknownAttributeNode xamlUnknownAttributeNode)
at System.Windows.Markup.XamlParser.ProcessXamlNode(XamlNode xamlNode, Boolean& cleanup, Boolean& done)
at System.Windows.Markup.XamlParser.ReadXaml(Boolean singleRecordMode)
at System.Windows.Markup.TreeBuilderXamlTranslator._Parse()
at System.Windows.Markup.XamlParser.Parse()
at System.Windows.Markup.XamlTreeBuilder.ParseFragment()
at System.Windows.Markup.TreeBuilder.Parse()
at System.Windows.Markup.XamlReader.XmlTreeBuildDefault(ParserContext pc, XmlReader reader, Boolean wrapWithMarkupCompatReader, XamlParseMode parseMode, Boolean etwTracingEnabled)
at System.Windows.Markup.XamlReader.Load(XmlReader reader)
at System.Windows.Markup.XamlReader.Parse(String xamlText)

最佳答案

事实证明,实现起来并不像乍看起来那么难。这里的关键信息是提到的异常不是由 XamlReader 引发的,而是由 XamlObjectWriter 引发的,它负责使用 XamlReader 和创建和填充结果对象。因此,我们需要做的就是提供一个自定义的 XamlReader,它可以简单地跳过未知属性。在我看来,最通用的方法是创建一个可以环绕另一个(任意)阅读器的阅读器。这个想法可以概括如下:

  • Read 方法中,我们从底层阅读器读取了一次
  • 如果我们遇到未知属性,只要 XamlReader.NodeTypeStartMember,就可以通过检查 XamlReader.Member.IsUnknown 轻松确定,我们简单地继续阅读直到我们到达成员定义的末尾(一个相应的1 EndMember 节点)并通过再次阅读移动到下一个节点;如果下一个节点也是未知属性,我们重复该过程

这样,对 Read 的单个调用将跳过未知属性,可能会导致从底层读取器进行多次读取,但这种行为对消费者来说是透明的。

这是一个示例代码:

public class LaxXamlReader : XamlReader
{
public override bool Read()
{
//Read once from the underlying reader
_Reader.Read();

//Check if current node is an unknown property
while (NodeType == XamlNodeType.StartMember && Member.IsUnknown)
{
//We need to track member nesting level so that we can correctly
//identify the corresponding EndMember node
var level = 1;
while (level > 0)
{
_Reader.Read();
if (NodeType == XamlNodeType.StartMember)
level++;
else if (NodeType == XamlNodeType.EndMember)
level--;
}

//At this point we're at the corresponsing EndMember node, so we
//advance to the next node; if it's also an unknown property, it
//will be caught by the while loop
_Reader.Read();
}

//If we've reached the end of input return false
return !IsEof;
}

public override XamlReader ReadSubtree()
=> new LaxXamlReader(_Reader.ReadSubtree());

protected override void Dispose(bool disposing)
{
//Only dispose the underlying reader if Dispose() was called;
//otherwise let GC do the job
if (disposing)
((IDisposable)_Reader).Dispose();
base.Dispose(disposing);
}

//The code below simply forwards the functionality from the underlying reader

public LaxXamlReader(XamlReader reader)
{
_Reader = reader;
}

private readonly XamlReader _Reader;
public override bool IsEof => _Reader.IsEof;
public override XamlMember Member => _Reader.Member;
public override NamespaceDeclaration Namespace => _Reader.Namespace;
public override XamlNodeType NodeType => _Reader.NodeType;
public override XamlSchemaContext SchemaContext => _Reader.SchemaContext;
public override XamlType Type => _Reader.Type;
public override object Value => _Reader.Value;
public override void Skip() => _Reader.Skip();
}

使用示例:

var xaml = "<Object Foo=\"Bar\" xmlns=\"clr-namespace:System;assembly=mscorlib\" />";
var obj = XamlServices.Load(new LaxXamlReader(new XamlXmlReader(new StringReader(xaml))));

请注意,XamlReader(以及其他提到的 XAML 相关类型)是在 System.Xaml 命名空间中定义的类型。


1 由于XAML中的属性可以写成元素并包含具有自身属性的对象,我们需要忽略对应于EndMember的节点这些嵌套属性

关于c# - 如何让 XamlReader.Parse 不抛出 "property does not exist"XamlParseException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1500198/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com