为什么 XmlSerializer 在映射具有相同名称但不同命名空间的类的对象图时无法初始化
本文关键字:命名空间 对象图 初始化 映射 XmlSerializer 为什么 | 更新日期: 2023-09-27 17:59:44
>我正在从没有命名空间的第三方接收XML。XML 架构采用简化和模糊处理的形式,如下所示:
<Root>
<Address>
<PostalCode>57373</PostalCode>
</Address>
<ReportAReport>
<Address>
<Zip>18573</Zip>
</Address>
</ReportAReport>
</Root>
请注意,这里有两个不同的Address
类。这些实际上被定义为两个不同的complexType
,每个都在我从第三方收到的矛状XML模式中。一个架构反映Root
模型,而另一个架构反映ReportAReport
每个Address
类都有不同的属性。
我在命名空间中表示每个架构,将每个 XML 架构视为自己的命名空间。事实上,模式定义了命名空间,但是由于某种原因,我从第三方收到的 XML 响应选择省略这些命名空间。
命名空间:MyCompany.MyProject
namespace MyCompany.MyProject
{
public class Root
{
public Address Address { get; set; }
public ReportAReport ReportAReport { get; set; }
}
public class Address
{
public string PostalCode { get; set; }
}
}
命名空间:MyCompany.MyProject.ReportA
namespace MyCompany.MyProject.ReportA
{
public class ReportAReport
{
public Address Address { get; set; }
}
public class Address
{
public string Zip { get; set; }
}
}
我得到的异常如下:
结果消息:无法创建类的实例 MyCompany.MyProject.Test.AggregatorTests. 错误: System.TypeInitializationException:的类型初始值设定项 'MyCompany.MyProject.Test.AggregatorTests'抛出了一个异常。---> 系统无效操作异常:反映类型时出错 "我的公司.我的项目.根"。---> System.InvalidOperationException: 存在反映属性"ReportAReport"的错误。---> 系统无效操作异常:反映类型时出错 'MyCompany.MyProject.ReportA.ReportAReport'.---> 系统无效操作异常:有一个错误反映 属性"地址"。---> System.InvalidOperationException: 有 反映类型"MyCompany.MyProject.ReportA.Address"的错误。---> 系统无效操作异常:类型 "MyCompany.MyProject.ReportA.Address"和"MyCompany.MyProject.ReportA.Address"和 "MyCompany.MyProject.Address"都使用XML类型名称"Address", 从命名空间 ''。使用 XML 属性指定唯一的 XML 名称 和/或类型的命名空间。
此异常所指的行如下所示:
XmlSerializer serializer = new XmlSerializer(typeof(Root));
例外似乎对正在发生的事情相当清楚。XmlSerializer
无法理解将ReportAReport
类中的属性"Address"映射到哪个类Address
。
我不明白的是为什么它无法理解将属性映射到哪个Address
类。在 ReportAReport
的类定义中,"Address" 属性被声明为类型 MyCompany.MyProject.ReportA.Address
。
我什至尝试使用 XmlElementAttribute
来指定ReportAReport
上的Type
:
[XmlElement(Type = typeof(Address))]
public Address Address { get; set; }
不过,无论如何,这似乎相当多余...
问题
编译器清楚地知道Address
这里指的是MyCompany.MyProject.ReportA.Address
。为什么XmlSerializer
无法做出这种辨识?
XmlSerializer
不应该知道,如果它在ReportAReport
节点中遇到Address
节点,它是MyCompany.MyProject.ReportA.Address
类型而不是MyCompany.MyProject.Address
?
我在这里错过了什么?
我添加了堆栈跟踪,因为它显示了 XmlSerializer 初始化过程打嗝的位置。我实际上从我的真实示例中提取了此堆栈跟踪,该示例具有比示例更深的节点,因此堆栈跟踪中可能存在一些级别的递归,这些递归似乎与我提供的示例代码不一致。
Result StackTrace:
at System.Xml.Serialization.XmlReflectionImporter.GetTypeMapping(String typeName, String ns, TypeDesc typeDesc, NameTable typeLib, Type type)
at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, String ns, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, String ns, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.CreateArrayElementsFromAttributes(ArrayMapping arrayMapping, XmlArrayItemAttributes attributes, Type arrayElementType, String arrayElementNs, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportArrayLikeMapping(ArrayModel model, String ns, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, String ns, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, String ns, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, String ns, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, String ns, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.CreateArrayElementsFromAttributes(ArrayMapping arrayMapping, XmlArrayItemAttributes attributes, Type arrayElementType, String arrayElementNs, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportArrayLikeMapping(ArrayModel model, String ns, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, String ns, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportElement(TypeModel model, XmlRootAttribute root, String defaultNamespace, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type)
at MyCompany.MyProject.Test.AggregatorTests..cctor() in c:'Users'crush'Documents'Visual Studio 2012'Projects'MyCompany.MyProject'Test'MyCompany.MyProject.Test'AggregatorTests.cs:line 16
--- End of inner exception stack trace ---
at MyCompany.MyProject.Test.AggregatorTests..ctor()
更新:在意识到我对收到的异常的初步评估完全不正确后,我完全重写了这个问题。我疏忽地认为反序列化是我收到异常的原因,而实际上,它清楚地表明XmlSerializer
的初始化是问题所在。这个问题已经被编辑以陈述这个事实,在我们说话的时候,我正在擦掉脸上的蛋糕。我向任何被最初错误和不完整的信息误导的人道歉。
尝试此模型进行反序列化。您可以实例化任一类型的新地址,并从反序列化模型中设置值。您可以使用自动映射器来完成对象的复制
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class Root
{
private RootAddress addressField;
private RootReportAReport reportAReportField;
/// <remarks/>
public RootAddress Address
{
get
{
return this.addressField;
}
set
{
this.addressField = value;
}
}
/// <remarks/>
public RootReportAReport ReportAReport
{
get
{
return this.reportAReportField;
}
set
{
this.reportAReportField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class RootAddress
{
private ushort postalCodeField;
/// <remarks/>
public ushort PostalCode
{
get
{
return this.postalCodeField;
}
set
{
this.postalCodeField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class RootReportAReport
{
private RootReportAReportAddress addressField;
/// <remarks/>
public RootReportAReportAddress Address
{
get
{
return this.addressField;
}
set
{
this.addressField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class RootReportAReportAddress
{
private ushort zipField;
/// <remarks/>
public ushort Zip
{
get
{
return this.zipField;
}
set
{
this.zipField = value;
}
}
}