简体   繁体   English

为什么在映射具有相同名称但不同名称空间的类的对象图时,XmlSerializer无法初始化?

[英]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 命名空间: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; }
    }
}

Namespace: MyCompany.MyProject.ReportA 命名空间:MyCompany.MyProject.ReportA

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 : 我甚至尝试使用XmlElementAttributeReportAReport上指定Type

[XmlElement(Type = typeof(Address))]
public Address Address { get; set; }

Though, that seems fairly redundant anyways... 虽然,这似乎相当多余......

Question

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.

相关问题 NHibernate DuplicateMappingException 当两个类具有相同的名称但不同的命名空间时 - NHibernate DuplicateMappingException when two classes have the same name but different namespaces 如何切换具有相同名称和不同名称空间的类? - How to switch classes with same name and different namespaces? 使用城堡ActiveRecord,当两个类具有相同的名称但名称空间不同时,我得到了NHibernate DuplicateMappingException - Using Castle ActiveRecord, I get an NHibernate DuplicateMappingException when two classes have the same name but different namespaces 如何处理具有相同名称的两个类的MVC DisplayTemplates(不同的命名空间) - How to handle MVC DisplayTemplates for two classes with the same name (different namespaces) 在同一节点中使用 XmlSerializer 订购不同的自定义类 - Order different custom classes with XmlSerializer in same node C# XmlSerializer 用不同的命名空间序列化相同的 class - C# XmlSerializer Serialize the same class with different namespaces EF4 Poco问题映射类型相同名称相同程序集不同的命名空间 - EF4 Poco Issue Mapping Types Same Name Same Assembly Different Namespaces 具有相同对象名称的两个名称空间 - Two namespaces with the same object name 内部类具有相同的命名空间但在不同的程序集中? - Internal classes having the same namespaces but in different assemblies? XmlSerializer +抽象类+派生类=无用的命名空间 - XmlSerializer + Abstract class + Derived classes = Useless namespaces
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM