如何解决使用XmlAnyElementAttribute反序列化对象不起作用
[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil","4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:epcglobal:epcis:xsd:1")]
public partial class ErrorDeclarationExtensionType
{
private System.Xml.XmlElement[] anyField;
private System.Xml.XmlAttribute[] anyAttrField;
/// <remarks/>
[System.Xml.Serialization.XmlAnyElementAttribute(Namespace = "",Order = 0)]
public System.Xml.XmlElement[] Any
{
get
{
return this.anyField;
}
set
{
this.anyField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAnyAttributeAttribute()]
public System.Xml.XmlAttribute[] AnyAttr
{
get
{
return this.anyAttrField;
}
set
{
this.anyAttrField = value;
}
}
}
创建一个简单的程序,将对象序列化为字符串,然后将该字符串反序列化为对象:
static void Main(string[] args)
{
var example = new ErrorDeclarationExtensionType();
var doc = new XmlDocument();
doc.LoadXml("<testXML2 xmlns=\"urn:testXML2\">anyContents0</testXML2>");
var test = doc.DocumentElement;
var array = new XmlElement[]
{
test
};
example.Any = array;
var sw = new StringWriter();
XmlTextWriter tw = null;
var xmlSerializer = new XmlSerializer(example.GetType());
tw = new XmlTextWriter(sw);
xmlSerializer.Serialize(tw,example);
Console.WriteLine(sw.ToString());
Console.ReadKey();
ErrorDeclarationExtensionType errorDeclaration;
var xmlSer = new XmlSerializer(typeof(ErrorDeclarationExtensionType));
using (TextReader tr = new StringReader(sw.ToString()))
{
errorDeclaration = (ErrorDeclarationExtensionType)xmlSer.Deserialize(tr);
}
Console.ReadKey();
}
反序列化后,所有字段的get对象均等于null。猜猜这是XmlAnyElementAttribute的问题,但没有得到任何解决方案。实际上,该类是prod中使用的其他类的属性,但是在这种情况下有相同的错误。
解决方法
您的问题是您设置的XmlAnyElementAttribute.Namespace
与XML不一致:
[System.Xml.Serialization.XmlAnyElementAttribute(Namespace = "",Order = 0)]
public System.Xml.XmlElement[] Any
{
get
{
return this.anyField;
}
set
{
this.anyField = value;
}
}
通过设置此属性,您表示只有命名空间中不存在的未知元素可以绑定到Any
属性。但是,示例XML中的unknown元素位于其他命名空间中,尤其是"urn:testXML2"
。如果我将示例XML更改为不包含名称空间,例如
<ErrorDeclarationExtensionType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<testXML2>anyContents0</testXML2>
</ErrorDeclarationExtensionType>
然后Any
成功填充。演示小提琴#1 here。
类似地,如果我将元数据属性中的命名空间更改为"urn:testXML2"
,则将填充Any
:
[System.Xml.Serialization.XmlAnyElementAttribute(Namespace = "urn:testXML2",Order = 0)]
public System.Xml.XmlElement[] Any
演示小提琴#2 here。
如果我删除了XmlAnyElementAttribute.Namespace
,那么任何一个都可以成功绑定:
[System.Xml.Serialization.XmlAnyElementAttribute(Order = 0)]
public System.Xml.XmlElement[] Any
{
get
{
return this.anyField;
}
set
{
this.anyField = value;
}
}
演示小提琴#3 here。
documentation remarks for XmlAnyElementAttribute
中对此的解释有些不正确:
序列化时...如果设置Namespace属性值,则还必须设置Name属性,并且XmlElement或XmlNode对象也必须具有相同的名称和命名空间值。
实际上,设置Namespace
不使用Name
似乎并不会在序列化和反序列化期间导致.NET Core 3.1.5中的错误,并绑定到具有该特定名称空间的所有未知元素。 / p>
注意:
-
您可能希望将
XmlTextWriter
的使用替换为XmlWriter
,因为从.Net 2.0开始不赞成使用前者:var sw = new StringWriter(); using (var tw = XmlWriter.Create(sw,new XmlWriterSettings { Indent = true /* or false if you prefer*/ })) { xmlSerializer.Serialize(tw,example); }
-
您已设置
XmlAnyElementAttribute.Order = 0
:获取或设置元素序列化或反序列化的显式顺序。
将
Order
属性用于一种类型的一个公共属性或字段之后,必须将其应用于该类型的所有公共属性和字段以及所有继承的类型。因此,要成功反序列化任何已知元素,您的未知元素将需要出现-尽管在这种情况下,您的类没有其他元素,并且不需要设置
Order
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。