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

时间:2014-04-23 15:29:27

标签: c# xml xmlserializer

我从没有名称空间的第三方接收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:类型初始值设定项   &#39; MyCompany.MyProject.Test.AggregatorTests&#39;抛出一个例外。 ---&GT;   System.InvalidOperationException:存在反映类型的错误   &#39; MyCompany.MyProject.Root&#39 ;. ---&GT; System.InvalidOperationException:   反映属性&#39; ReportAReport&#39;时出现错误。 ---&GT;   System.InvalidOperationException:存在反映类型的错误   &#39; MyCompany.MyProject.ReportA.ReportAReport&#39 ;. ---&GT;   System.InvalidOperationException:反映出错   财产&#39;地址&#39;。 ---&GT; System.InvalidOperationException:有   反映类型的错误&#39; MyCompany.MyProject.ReportA.Address&#39;。 ---&GT;   System.InvalidOperationException:类型   &#39; MyCompany.MyProject.ReportA.Address&#39;和   &#39; MyCompany.MyProject.Address&#39;两者都使用XML类型名称,&#39;地址&#39;,   来自命名空间&#39;&#39;。使用XML属性指定唯一的XML名称   和/或类型的名称空间..

此异常所指的行如下:

XmlSerializer serializer = new XmlSerializer(typeof(Root));

对于正在发生的事情似乎相当清楚。 XmlSerializer无法了解哪个Address类要映射属性&#39;地址&#39;在ReportAReport班。

我无法理解为什么它无法理解哪个Address类来映射属性。在ReportAReport的课程定义中,地址&#39;属性声明为MyCompany.MyProject.ReportA.Address类型。

我甚至尝试使用XmlElementAttributeType上指定ReportAReport

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

尽管如此,这似乎相当多余......

问题

编译器清楚地知道Address这里指的是MyCompany.MyProject.ReportA.Address。为什么XmlSerializer无法识别这一点?

不应该XmlSerializer知道如果它遇到Address节点内的ReportAReport节点,那么它的类型为MyCompany.MyProject.ReportA.Address而不是MyCompany.MyProject.Address }?

我在这里缺少什么?


我添加了堆栈跟踪,因为它显示了XmlSerializer初始化进程打嗝的位置。我实际上从我的真实世界示例中提取了这个堆栈跟踪,其中有几个节点比样本更深,因此堆栈跟踪中可能会有一些递归级别似乎与示例代码I&排列#39;已提供。

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的初始化是问题所在。这个问题已被编辑,以说明这一事实,我在说话时擦掉了脸上的蛋糕。我向任何误导了最初错误和不完整信息的人道歉。

1 个答案:

答案 0 :(得分:0)

尝试使用此模型进行反序列化。您可以实例化任一类型的新地址,并从反序列化模型中设置值。您可以使用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;
            }
        }
    }