XML序列化正确但不能反序列化数组对象

时间:2013-12-20 17:29:51

标签: c# .net xml serialization

我有一个需要序列化XML的项目。我的XSD是Java库和C#.NET 4.0库的目标。我的C#库似乎在反序列化特定的XML时遇到了问题。

这是有问题的XML。

<FbiXml>
    <Ticket>
        <UserID>1</UserID>
        <Key>qqym2OmtNjiUOBDbfr2tXg==</Key>
    </Ticket>
    <FbiMsgsRs statusCode="1000">
        <SaveSORs statusCode="1000">
            <SalesOrder>
                <ID>517</ID>
                <Note/>
                <TotalPrice>0.07</TotalPrice>
                <TotalTax>0</TotalTax>
                <ItemTotal>0</ItemTotal>
                <Salesman/>
                <Number>629</Number>
                <Status>20</Status>
                <Carrier>Delivery</Carrier>
                <FirstShipDate>2013-12-20T08:43:46</FirstShipDate>
                <CreatedDate>2013-12-20T08:43:46</CreatedDate>
                <IssuedDate>2013-12-20T08:43:46</IssuedDate>
                <TaxRateName>None</TaxRateName>
                <ShippingTerms>Prepaid &amp; Billed</ShippingTerms>
                <PaymentTerms>COD</PaymentTerms>
                <CustomerContact/>
                <CustomerName>Stackoverflow</CustomerName>
                <CustomerID>19</CustomerID>
                <FOB>Origin</FOB>
                <QuickBooksClassName>None</QuickBooksClassName>
                <LocationGroup>Main</LocationGroup>
                <PoNum/>
                <PriceIsHomeCurrency>true</PriceIsHomeCurrency>
                <BillTo/>
                <Ship/>
                <Cost>0</Cost>
                <Items>
                    <SalesOrderItem>
                        <ID>3725</ID>
                        <ProductNumber/>
                        <SOID>-1</SOID>
                        <Description>Adjustment Amount</Description>
                        <Taxable>false</Taxable>
                        <Quantity>1</Quantity>
                        <ProductPrice>0.07</ProductPrice>
                        <TotalPrice>0.07</TotalPrice>
                        <UOMCode>ea</UOMCode>
                        <ItemType>11</ItemType>
                        <Status>-1</Status>
                        <Note/>
                        <QuickBooksClassName/>
                        <NewItemFlag>true</NewItemFlag>
                        <LineNumber>1</LineNumber>
                        <AdjustmentAmount>0</AdjustmentAmount>
                        <AdjustPercentage>0</AdjustPercentage>
                        <QtyFulfilled>0</QtyFulfilled>
                        <QtyPicked>0</QtyPicked>
                        <TotalCost>0</TotalCost>
                        <TaxID>1</TaxID>
                        <TaxRate>0.1</TaxRate>
                        <TaxCode>None</TaxCode>
                    </SalesOrderItem>
                </Items>
            </SalesOrder>
        </SaveSORs>
    </FbiMsgsRs>
</FbiXml>

我正在使用此代码测试我的C#库。

using FishbowlSDK;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;

namespace TestFishbowlLibrary
{
    class Program
    {
        static void Main(string[] args)
        {
            testSODeserialize();
        }

        public static void testSODeserialize()
        {
            String XML = Resource1.SOXMLTEST001;
            FbiXml fbixml = new FbiXml();
            System.Xml.Serialization.XmlSerializer xml = new System.Xml.Serialization.XmlSerializer(fbixml.GetType());
            xml.UnknownAttribute += new XmlAttributeEventHandler(Serializer_UnknownAttribute);
            xml.UnknownElement += new XmlElementEventHandler(Serializer_UnknownElement);
            String rs = XML;
            rs = rs.Replace(@"<FbiXml>", @"<FbiXml xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns=""FishbowlSDK"">");
            StringReader sr = new StringReader(rs);
            XmlTextReader xtr = new XmlTextReader(sr);
            FbiXml Response = (FbiXml)xml.Deserialize(xtr);
            SaveSORsType loadsors = (SaveSORsType)Response.FbiMsgsRs.Items[0];
            SalesOrder so = loadsors.SalesOrder;
            if (so.Items.Count == 0)
            {
                throw new Exception("This XML has Sales Order Items, but it deserialized none!");
            }            
        }

        private static void Serializer_UnknownAttribute(object sender, XmlAttributeEventArgs e)
        {
            Console.WriteLine("Unknown Attribute");
            Console.WriteLine("\t" + e.Attr.Name + " " + e.Attr.InnerXml);
            Console.WriteLine("\t LineNumber: " + e.LineNumber);
            Console.WriteLine("\t LinePosition: " + e.LinePosition);
        }

        private static void Serializer_UnknownElement(object sender, XmlElementEventArgs e)
        {
            Console.WriteLine("Unknown Element");
            Console.WriteLine("\t" + e.Element.Name + " " + e.Element.InnerXml);
            Console.WriteLine("\t LineNumber: " + e.LineNumber);
            Console.WriteLine("\t LinePosition: " + e.LinePosition);
        }


    }
}

这是完整XSD的片段。只是销售订单对象。

<xs:element name="SalesOrder">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="ID" type="xs:integer" minOccurs="0" />
            <xs:element name="Note"   type="xs:string"   minOccurs="0" />
            <xs:element name="TotalPrice"   type="xs:string"   minOccurs="0" />
            <xs:element name="TotalTax"   type="xs:string"   minOccurs="0" />
            <xs:element name="ItemTotal"   type="xs:string"   minOccurs="0" />
            <xs:element name="Salesman"   type="xs:string"   minOccurs="0" />
            <xs:element name="Number"   type="xs:string"   minOccurs="0" />
            <xs:element name="Status"   type="xs:integer"   minOccurs="0" />
            <xs:element name="Carrier"   type="xs:string"   minOccurs="0" />
            <xs:element name="FirstShipDate"   type="xs:dateTime"   minOccurs="0" />
            <xs:element name="CreatedDate"   type="xs:dateTime"   minOccurs="0" />
            <xs:element name="IssuedDate"   type="xs:dateTime"   minOccurs="0" />
            <xs:element name="TaxRateName"   type="xs:string"   minOccurs="0" />
            <xs:element name="ShippingTerms"   type="xs:string"   minOccurs="0" />
            <xs:element name="PaymentTerms"   type="xs:string"   minOccurs="0" />
            <xs:element name="CustomerContact"   type="xs:string"   minOccurs="0" />
            <xs:element name="CustomerName"   type="xs:string" />
            <xs:element name="CustomerID"   type="xs:integer" />
            <xs:element name="FOB"   type="xs:string"   minOccurs="0" />
            <xs:element name="QuickBooksClassName"   type="xs:string"   minOccurs="0" />
            <xs:element name="LocationGroup"   type="xs:string"   minOccurs="0" />
            <xs:element name="PoNum"   type="xs:string"   minOccurs="0" />
            <xs:element name="BillTo"   type="tns:BillType"   minOccurs="0" />
            <xs:element name="Ship"   type="tns:ShipType"   minOccurs="0" />
            <xs:element name="IssueFlag"   type="xs:boolean"   default="false" />
            <xs:element name="VendorPO"   type="xs:string"   minOccurs="0" />
            <xs:element name="CustomerPO"   type="xs:string"   minOccurs="0" />
            <xs:element name="TotalIncludesTax"   type="xs:boolean"   minOccurs="0" />
            <xs:element name="TypeID"   type="xs:integer"   minOccurs="0" />
            <xs:element name="URL"   type="xs:string"   minOccurs="0" />
            <xs:element name="Cost"   type="xs:double"   minOccurs="0" />
            <xs:element name="DateLastModified"   type="xs:dateTime"   minOccurs="0" />
            <xs:element name="SalesmanInitials"   type="xs:string"   minOccurs="1" />
            <xs:element ref="tns:CustomFields"   minOccurs="0" />
            <xs:element ref="tns:Memos"   minOccurs="0" />
            <xs:element ref="tns:Items"   minOccurs="0" />
        </xs:sequence>
    </xs:complexType>
</xs:element>

这是C#Library中的目标代码。它是用xsd2code生成的。

[System.Xml.Serialization.XmlArrayAttribute(Order = 35)]
[System.Xml.Serialization.XmlArrayItemAttribute("SalesOrderItem", IsNullable = false)]
public List<SalesOrderItem> Items
{
    get
    {
        return this.itemsField;
    }
    set
    {
        this.itemsField = value;
    }
}

这是我的测试代码输出的内容。

Unknown Element
    PriceIsHomeCurrency true
     LineNumber: 25
     LinePosition: 52
Unknown Element
    BillTo 
     LineNumber: 26
     LinePosition: 14
Unknown Element
    Ship 
     LineNumber: 27
     LinePosition: 12
Unknown Element
    Cost 0
     LineNumber: 28
     LinePosition: 19
Unknown Element
    Items 
      <SalesOrderItem xmlns="FishbowlSDK">
        <ID>3725</ID>
        <ProductNumber />
        <SOID>-1</SOID>
        <Description>Adjustment Amount</Description>
        <Taxable>false</Taxable>
        <Quantity>1</Quantity>
        <ProductPrice>0.07</ProductPrice>
        <TotalPrice>0.07</TotalPrice>
        <UOMCode>ea</UOMCode>
        <ItemType>11</ItemType>
        <Status>-1</Status>
        <Note />
        <QuickBooksClassName />
        <NewItemFlag>true</NewItemFlag>
        <LineNumber>1</LineNumber>
        <AdjustmentAmount>0</AdjustmentAmount>
        <AdjustPercentage>0</AdjustPercentage>
        <QtyFulfilled>0</QtyFulfilled>
        <QtyPicked>0</QtyPicked>
        <TotalCost>0</TotalCost>
        <TaxID>1</TaxID>
        <TaxRate>0.1</TaxRate>
        <TaxCode>None</TaxCode>
      </SalesOrderItem>

     LineNumber: 55
     LinePosition: 13

所以我的c#知道有一个已知的元素。但为什么?因为我可以以编程方式生成销售订单对象,并且XML已正确序列化。

1 个答案:

答案 0 :(得分:0)

我发现了这个问题。它是“PriceIsHomeCurrency”的未知元素,因为对象的顺序现在与反序列化程序所期望的不同,因此认为Items元素是未知的。修复此未知元素解决了序列化问题。