[英]Why is XmlSerializer failing to initialize when mapping the object graph of classes with the same name, but different namespaces?
I'm receiving XML from a third party that has no namespaces. 我从没有名称空间的第三方接收XML。 The XML schema, in a simplified and obfuscated form, looks like the following:
XML模式以简化和混淆的形式显示如下:
<Root>
<Address>
<PostalCode>57373</PostalCode>
</Address>
<ReportAReport>
<Address>
<Zip>18573</Zip>
</Address>
</ReportAReport>
</Root>
Please take note that there are two distinct Address
classes here. 请注意,这里有两个不同的
Address
类。 These are actually defined as two different complexType
s, each in a spearate XML schema which I have received from the third party. 这些实际上被定义为两个不同的
complexType
,每个都在我从第三方收到的spearate XML模式中。 One schema reflects the Root
model, while the other schema reflects the model for ReportAReport
Each Address
class has distinct properties. 一个模式反映了
Root
模型,而另一个模式反映了ReportAReport
的模型。每个Address
类都有不同的属性。
I represent each in a namespace, treating each XML schema as its own namespace. 我在命名空间中表示每个,将每个XML模式视为自己的命名空间。 In fact, the schemas have namespaces defined, but the XML response I receive from the third party has chosen to omit these namespaces for some reason.
事实上,模式定义了名称空间,但是我从第三方收到的XML响应因某种原因选择省略这些名称空间。
namespace MyCompany.MyProject
{
public class Root
{
public Address Address { get; set; }
public ReportAReport ReportAReport { get; set; }
}
public class Address
{
public string PostalCode { get; set; }
}
}
namespace MyCompany.MyProject.ReportA
{
public class ReportAReport
{
public Address Address { get; set; }
}
public class Address
{
public string Zip { get; set; }
}
}
The exception I'm getting is as follows: 我得到的例外情况如下:
Result Message: Unable to create instance of class MyCompany.MyProject.Test.AggregatorTests.
结果消息:无法创建类MyCompany.MyProject.Test.AggregatorTests的实例。 Error: System.TypeInitializationException: The type initializer for 'MyCompany.MyProject.Test.AggregatorTests' threw an exception.
错误:System.TypeInitializationException:'MyCompany.MyProject.Test.AggregatorTests'的类型初始值设定项引发异常。 ---> System.InvalidOperationException: There was an error reflecting type 'MyCompany.MyProject.Root'.
---> System.InvalidOperationException:有一个错误反映了'MyCompany.MyProject.Root'类型。 ---> System.InvalidOperationException: There was an error reflecting property 'ReportAReport'.
---> System.InvalidOperationException:反映属性'ReportAReport'时出错。 ---> System.InvalidOperationException: There was an error reflecting type 'MyCompany.MyProject.ReportA.ReportAReport'.
---> System.InvalidOperationException:反映出类型为“MyCompany.MyProject.ReportA.ReportAReport”的错误。 ---> System.InvalidOperationException: There was an error reflecting property 'Address'.
---> System.InvalidOperationException:反映属性'Address'时出错。 ---> System.InvalidOperationException: There was an error reflecting type 'MyCompany.MyProject.ReportA.Address'.
---> System.InvalidOperationException:反映出类型为“MyCompany.MyProject.ReportA.Address”的错误。 ---> System.InvalidOperationException: Types 'MyCompany.MyProject.ReportA.Address' and 'MyCompany.MyProject.Address' both use the XML type name, 'Address', from namespace ''.
---> System.InvalidOperationException:类型'MyCompany.MyProject.ReportA.Address'和'MyCompany.MyProject.Address'都使用来自命名空间''的XML类型名称'Address'。 Use XML attributes to specify a unique XML name and/or namespace for the type..
使用XML属性为类型指定唯一的XML名称和/或命名空间。
The line to which this exception is referring is as follows: 此异常所指的行如下:
XmlSerializer serializer = new XmlSerializer(typeof(Root));
The exception seems to be fairly clear about what is happening. 关于正在发生的事情似乎相当清楚。 The
XmlSerializer
is failing to understand to which Address
class to map the property 'Address' in the ReportAReport
class. 该
XmlSerializer
是没有理解到Address
类的属性“地址”映射ReportAReport
类。
What I can't understand is why it is failing to understand to which Address
class to map the property. 我无法理解的是为什么它无法理解要映射属性的
Address
类。 In the class definition of ReportAReport
, the 'Address' property is declared as being of type MyCompany.MyProject.ReportA.Address
. 在
ReportAReport
的类定义中,'Address'属性被声明为MyCompany.MyProject.ReportA.Address
类型。
I even tried using XmlElementAttribute
to specify the Type
on ReportAReport
: 我甚至尝试使用
XmlElementAttribute
在ReportAReport
上指定Type
:
[XmlElement(Type = typeof(Address))]
public Address Address { get; set; }
Though, that seems fairly redundant anyways... 虽然,这似乎相当多余......
The compiler clearly knows that Address
here is referring to MyCompany.MyProject.ReportA.Address
. 编译器清楚地知道这里的
Address
是指MyCompany.MyProject.ReportA.Address
。 Why is the XmlSerializer
unable to make this discernment? 为什么
XmlSerializer
无法识别这个?
Shouldn't XmlSerializer
know that if it encounters an Address
node within a ReportAReport
node, that it is of type MyCompany.MyProject.ReportA.Address
rather than MyCompany.MyProject.Address
? XmlSerializer
不应该知道如果它遇到ReportAReport
节点中的Address
节点,它是MyCompany.MyProject.ReportA.Address
类型而不是MyCompany.MyProject.Address
吗?
What am I missing here? 我在这里错过了什么?
I added the stack trace because it shows where the XmlSerializer initialization process is hiccuping. 我添加了堆栈跟踪,因为它显示了XmlSerializer初始化进程打嗝的位置。 I actually pulled this stack trace from my real world example, which has a few nodes deeper than the samples, so there might be a few levels of recursion in the stack trace that don't seem to line up with the sample code I've provided.
我实际上从我的真实世界示例中提取了这个堆栈跟踪,其中有几个节点比样本更深,因此堆栈跟踪中可能存在一些级别的递归,这些递归似乎与示例代码不符合我的情况提供。
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()
Update: I completely rewrote this question after realizing that my initial assessment about the exceptions I was receiving was completely incorrect. 更新:在我意识到我对我收到的异常的初步评估完全不正确之后,我完全重写了这个问题。 I negligently assumed that deserialization was the cause of the exception I was receiving, when in fact, it was clearly stated that initialization of the
XmlSerializer
was the problem. 我疏忽地认为反序列化是我收到的异常的原因,事实上,有人明确指出
XmlSerializer
初始化是个问题。 The question has been edited to state this fact, and I'm wiping the cake off my face as we speak. 这个问题已被编辑,以说明这一事实,我正在说话时我正在擦掉蛋糕。 I apologize to anyone I misled with initial faulty and incomplete information.
我向任何误导最初错误和不完整信息的人道歉。
try this model to de-serialize against. 尝试使用此模型进行反序列化。 You can instantiate a new Address of either type and set the value from the deserialized model.
您可以实例化任一类型的新地址,并从反序列化模型中设置值。 You could use AutoMapper to accomplish the copy of objects
您可以使用AutoMapper来完成对象的复制
/// <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;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.