使用 StringReader 与 XmlNodeReader 反序列化对象 属性

Deserialize object property with StringReader vs XmlNodeReader

为什么在使用 XmlNodeReader 而不是空字符串反序列化空类型元素时 XmlSerializer 使用 XmlNode 数组填充我的对象 属性 StringReader(或XmlTextReader)?

以下代码示例中的第二个断言失败:

var doc = new XmlDocument();
doc.Load(new StringReader(@"
    <Test xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
          xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
      <Value xsi:type=""xsd:string"" />
    </Test>"));
var ser = new XmlSerializer(typeof (Test));

var reader1 = new StringReader(doc.InnerXml);
var obj1 = (Test) ser.Deserialize(reader1);
Debug.Assert(obj1.Value is string);

var reader2 = new XmlNodeReader(doc.FirstChild);
var obj2 = (Test) ser.Deserialize(reader2);
Debug.Assert(obj2.Value is string);

public class Test
{
    public object Value { get; set; }
}

我猜它与空内部 NamespaceManager 属性 有关,但我不确定如何解决这个神秘的限制。如何可靠地反序列化已解析的 XML 文档的子集而不将其转换回字符串并重新解析?

看起来这是一个非常古老的 XmlNodeReader 错误,Microsoft have no intention of fixing. (Archived Microsoft Connect link here). I found a workaround on Lev Gimelfarb's blog here 将名称空间添加到 reader 的 NameTable 作为前缀查找。

public class ProperXmlNodeReader : XmlNodeReader
{
    public ProperXmlNodeReader(XmlNode node) : base(node)
    {
    }

    public override string LookupNamespace(string prefix)
    {
        return NameTable.Add(base.LookupNamespace(prefix));
    }
}