Проблема с сериализацией XML - PullRequest
3 голосов
/ 17 марта 2011

Обычно все это прекрасно работает для сериализации моего объекта в строку XML и обратно в объект. Тем не менее, у меня есть это несоответствие между различными конечными пользователями, которое я не могу отследить.

В принципе, когда я сериализую объект, он выглядит так, когда-то преобразованный в Xml:

<?xml version="1.0" encoding="utf-8"?>
<Step xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name>Step 2</Name>
  <VoltageDip>20</VoltageDip>
  <Loads>
    <Load xsi:type="ThreePhaseMotorLoad">
      <Name>Motor 450 KW Pump</Name>
      <Comments />
      <Quantity>1</Quantity>
      <Voltage>
        <Name>400 Volt 3 Phase 12w 50Hz</Name>
        <V3Id xsi:nil="true" />
        <Value>400</Value>
        <V3Value>415</V3Value>
        <Connection>Wye</Connection>
        <Phase>3</Phase>
        <RangeDescription>231/400v</RangeDescription>
        <VoltageCode>F</VoltageCode>
        <Active>true</Active>
        <Frequency>50</Frequency>
        <PowerFactor>0.8000</PowerFactor>
        <UL2200>false</UL2200>
        <Default>false</Default>
        <TempRiseIds>
          <TempRiseId>F</TempRiseId>
        </TempRiseIds>
      </Voltage>
      <IsNonLinear>true</IsNonLinear>
      <PriorityProperty>KWm</PriorityProperty>
      <KW>0</KW>
      <RunningPowerFactor xsi:nil="true" />
      <StartingPowerFactor>0.90</StartingPowerFactor>
      <KWm>450</KWm>
      <Efficiency xsi:nil="true" />
      <IsLowInertia>false</IsLowInertia>
      <MotorStandard>NEMA</MotorStandard>
      <MotorStartingMethod>VariableFrequencyDrive</MotorStartingMethod>
      <NEMAMotorCode>F</NEMAMotorCode>
      <SolidStateStarterPercent>0</SolidStateStarterPercent>
      <LockedRotorKVAPerHP>5.3</LockedRotorKVAPerHP>
    </Load>
    <Load xsi:type="ThreePhaseMotorLoad">
      <Name>Motor 450 KW Pump</Name>
      <Comments />
      <Quantity>1</Quantity>
      <Voltage>
        <Name>400 Volt 3 Phase 12w 50Hz</Name>
        <V3Id xsi:nil="true" />
        <Value>400</Value>
        <V3Value>415</V3Value>
        <Connection>Wye</Connection>
        <Phase>3</Phase>
        <RangeDescription>231/400v</RangeDescription>
        <VoltageCode>F</VoltageCode>
        <Active>true</Active>
        <Frequency>50</Frequency>
        <PowerFactor>0.8000</PowerFactor>
        <UL2200>false</UL2200>
        <Default>false</Default>
        <TempRiseIds>
          <TempRiseId>F</TempRiseId>
        </TempRiseIds>
      </Voltage>
      <IsNonLinear>true</IsNonLinear>
      <PriorityProperty>KWm</PriorityProperty>
      <KW>0</KW>
      <RunningPowerFactor xsi:nil="true" />
      <StartingPowerFactor>0.90</StartingPowerFactor>
      <KWm>450</KWm>
      <Efficiency xsi:nil="true" />
      <IsLowInertia>false</IsLowInertia>
      <MotorStandard>NEMA</MotorStandard>
      <MotorStartingMethod>VariableFrequencyDrive</MotorStartingMethod>
      <NEMAMotorCode>F</NEMAMotorCode>
      <SolidStateStarterPercent>0</SolidStateStarterPercent>
      <LockedRotorKVAPerHP>5.3</LockedRotorKVAPerHP>
    </Load>
    <Load xsi:type="ThreePhaseMotorLoad">
      <Name>Motor 450 KW Pump</Name>
      <Comments />
      <Quantity>1</Quantity>
      <Voltage>
        <Name>400 Volt 3 Phase 12w 50Hz</Name>
        <V3Id xsi:nil="true" />
        <Value>400</Value>
        <V3Value>415</V3Value>
        <Connection>Wye</Connection>
        <Phase>3</Phase>
        <RangeDescription>231/400v</RangeDescription>
       <VoltageCode>F</VoltageCode>
        <Active>true</Active>
        <Frequency>50</Frequency>
        <PowerFactor>0.8000</PowerFactor>
        <UL2200>false</UL2200>
        <Default>false</Default>
        <TempRiseIds>
          <TempRiseId>F</TempRiseId>
        </TempRiseIds>
      </Voltage>
      <IsNonLinear>true</IsNonLinear>
      <PriorityProperty>KWm</PriorityProperty>
      <KW>0</KW>
      <RunningPowerFactor xsi:nil="true" />
      <StartingPowerFactor>0.90</StartingPowerFactor>
      <KWm>450</KWm>
      <Efficiency xsi:nil="true" />
      <IsLowInertia>false</IsLowInertia>
      <MotorStandard>NEMA</MotorStandard>
      <MotorStartingMethod>VariableFrequencyDrive</MotorStartingMethod>
      <NEMAMotorCode>F</NEMAMotorCode>
      <SolidStateStarterPercent>0</SolidStateStarterPercent>
      <LockedRotorKVAPerHP>5.3</LockedRotorKVAPerHP>
    </Load>
  </Loads>
</Step>

Однако, когда другие случайные пользователи запускают мою программу и сериализуют объект, они получают следующее:

<?xml version="1.0" encoding="utf-8"?>
<Step xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name>Step 2</Name>
  <Loads>
    <Load xsi:type="ThreePhaseMotorLoad">
      <Name>Motor 450 KW Pump</Name>
      <Comments />
      <Quantity>1</Quantity>
      <Voltage>
        <Name>240 Volt 3 Phase 12w 60Hz</Name>
        <RangeDescription>120/240v</RangeDescription>
        <V3Id>3</V3Id>
        <Value>240</Value>
        <V3Value>480</V3Value>
        <Connection>Delta</Connection>
        <Phase>3</Phase>
        <VoltageCode>J</VoltageCode>
        <Active>true</Active>
        <Frequency>60</Frequency>
        <PowerFactor>0.8000</PowerFactor>
        <UL2200>true</UL2200>
        <Default>true</Default>
        <TempRiseIds>
          <TempRiseId>B</TempRiseId>
          <TempRiseId>C</TempRiseId>
          <TempRiseId>D</TempRiseId>
          <TempRiseId>E</TempRiseId>
        </TempRiseIds>
      </Voltage>
      <IsNonLinear>true</IsNonLinear>
      <PriorityProperty>KWm</PriorityProperty>
      <KW>0</KW>
      <RunningPowerFactor xsi:nil="true" />
      <StartingPowerFactor>0.90</StartingPowerFactor>
      <KWm>450</KWm>
      <Efficiency xsi:nil="true" />
      <IsLowInertia>false</IsLowInertia>
      <MotorStandard>NEMA</MotorStandard>
      <MotorStartingMethod>VariableFrequencyDrive</MotorStartingMethod>
      <NEMAMotorCode>F</NEMAMotorCode>
      <SolidStateStarterPercent>0</SolidStateStarterPercent>
      <LockedRotorKVAPerHP>5.3</LockedRotorKVAPerHP>
    </Load>
    <Load xsi:type="ThreePhaseMotorLoad">
      <Name>Motor 450 KW Pump</Name>
      <Comments />
      <Quantity>1</Quantity>
      <Voltage>
        <Name>240 Volt 3 Phase 12w 60Hz</Name>
        <RangeDescription>120/240v</RangeDescription>
        <V3Id>3</V3Id>
        <Value>240</Value>
        <V3Value>480</V3Value>
        <Connection>Delta</Connection>
        <Phase>3</Phase>
        <VoltageCode>J</VoltageCode>
        <Active>true</Active>
        <Frequency>60</Frequency>
        <PowerFactor>0.8000</PowerFactor>
        <UL2200>true</UL2200>
        <Default>true</Default>
        <TempRiseIds>
          <TempRiseId>B</TempRiseId>
          <TempRiseId>C</TempRiseId>
          <TempRiseId>D</TempRiseId>
          <TempRiseId>E</TempRiseId>
        </TempRiseIds>
      </Voltage>
      <IsNonLinear>true</IsNonLinear>
      <PriorityProperty>KWm</PriorityProperty>
      <KW>0</KW>
      <RunningPowerFactor xsi:nil="true" />
      <StartingPowerFactor>0.90</StartingPowerFactor>
      <KWm>450</KWm>
      <Efficiency xsi:nil="true" />
      <IsLowInertia>false</IsLowInertia>
      <MotorStandard>NEMA</MotorStandard>
      <MotorStartingMethod>VariableFrequencyDrive</MotorStartingMethod>
      <NEMAMotorCode>F</NEMAMotorCode>
      <SolidStateStarterPercent>0</SolidStateStarterPercent>
      <LockedRotorKVAPerHP>5.3</LockedRotorKVAPerHP>
    </Load>
    <Load xsi:type="ThreePhaseMotorLoad">
      <Name>Motor 450 KW Pump</Name>
      <Comments />
      <Quantity>1</Quantity>
      <Voltage>
        <Name>240 Volt 3 Phase 12w 60Hz</Name>
        <RangeDescription>120/240v</RangeDescription>
        <V3Id>3</V3Id>
        <Value>240</Value>
        <V3Value>480</V3Value>
        <Connection>Delta</Connection>
        <Phase>3</Phase>
        <VoltageCode>J</VoltageCode>
        <Active>true</Active>
        <Frequency>60</Frequency>
        <PowerFactor>0.8000</PowerFactor>
        <UL2200>true</UL2200>
        <Default>true</Default>
        <TempRiseIds>
          <TempRiseId>B</TempRiseId>
          <TempRiseId>C</TempRiseId>
          <TempRiseId>D</TempRiseId>
          <TempRiseId>E</TempRiseId>
        </TempRiseIds>
      </Voltage>
      <IsNonLinear>true</IsNonLinear>
      <PriorityProperty>KWm</PriorityProperty>
      <KW>0</KW>
      <RunningPowerFactor xsi:nil="true" />
      <StartingPowerFactor>0.90</StartingPowerFactor>
      <KWm>450</KWm>
      <Efficiency xsi:nil="true" />
      <IsLowInertia>false</IsLowInertia>
      <MotorStandard>NEMA</MotorStandard>
      <MotorStartingMethod>VariableFrequencyDrive</MotorStartingMethod>
      <NEMAMotorCode>F</NEMAMotorCode>
      <SolidStateStarterPercent>0</SolidStateStarterPercent>
      <LockedRotorKVAPerHP>5.3</LockedRotorKVAPerHP>
    </Load>
  </Loads>
  <VoltageDip>20</VoltageDip>
</Step>

Вы заметите, что это отличается тем, что VoltageDip и Нагрузки находятся в разных последовательностях. Так что, похоже, он не соответствует последовательности, установленной в схеме. После того, как пользователь десериализует строку Xml, происходит следующее: для свойств Name, Loads и VoltageDip установлены значения по умолчанию (null для ссылочных типов и строк и 0 для int) вместо значений, сохраненных в процессе сериализации.

Каждый, кто использует приложение, использует один и тот же исходный код.

Может кто-нибудь сказать мне, что происходит? Почему порядок последовательностей элементов при сериализации изменяется между разными пользователями / компьютерами? Почему процесс десериализации не может справиться с этим, когда он происходит?

Ответы [ 2 ]

5 голосов
/ 17 марта 2011

Попробуйте использовать order в атрибуте XmlElement в ваших свойствах Для бывших -

[XmlElement(Order = 1)]
public string Prop1{get;set;}

[XmlElement(Order = 2)]
public string Prop1{get;set;}
2 голосов
/ 17 марта 2011

Украсьте свой класс xml, в частности параметр порядка (см. Также: Другой вопрос StackOverFlow ).

using System;
using System.Collections.Specialized;
using System.IO;
using System.Reflection;
using System.Xml.Schema;
using System.Xml.Serialization;
using PSSpecClassLibrary.Attributes;
using PSSpecClassLibrary.Sizing.Loads;
using PSSpecClassLibrary.Utilities;

namespace PSSpecClassLibrary.Sizing
{
    /// <summary>
    /// Class to represent a step in a sizing project.
    /// </summary>
    [Serializable]
    public class Step : PSSpecObject
    {
        #region Fields

        private int m_intVoltageDip;
        private StepList m_stepList;
        private LoadList m_loads;

        #endregion

        #region Properties

        /// <summary>
        /// Returns an XmlSchemaSet for this object type.
        /// </summary>
        [XmlIgnore]
        public static XmlSchemaSet XmlSchemaSet
        {
            get
            {
                try
                {
                    XmlSchemaSet xmlSchemaSet = new XmlSchemaSet();

                    using (Stream stream = Assembly.GetAssembly(typeof(Step)).GetManifestResourceStream("PSSpecClassLibrary.Sizing.Step.xsd"))
                    {
                        xmlSchemaSet.Add(XmlSchema.Read(stream, XmlSchemaReadValidationCallBack));
                    }

                    using (Stream stream = Assembly.GetAssembly(typeof(Step)).GetManifestResourceStream("PSSpecClassLibrary.Guid.xsd"))
                    {
                        xmlSchemaSet.Add(XmlSchema.Read(stream, XmlSchemaReadValidationCallBack));
                    }

                    return xmlSchemaSet;
                }
                catch
                {
                    return null;
                }
            }
        }

        /// <summary>
        /// The Step Name
        /// </summary>
        [XmlElement(Order = 1)]
        public override string Name
        {
            get
            {
                return base.Name;
            }
            set
            {
                base.Name = value;
            }
        }

        /// <summary>
        /// Step Voltage Dip
        /// </summary>
        [XmlElement(Order = 2)]
        public int VoltageDip
        {
            get
            {
                return m_intVoltageDip;
            }
            set
            {
                m_intVoltageDip = value;
            }
        }

        /// <summary>
        /// Step Loads Collection
        /// </summary>
        [XmlElement(Order = 3)]
        public LoadList Loads
        {
            get
            {
                return m_loads;
            }
            set
            {
                if (m_loads != value)
                {
                    if (m_loads != null)
                        m_loads.CollectionChanged -= LoadsChanged;
                    if (value != null)
                    {
                        value.CollectionChanged -= LoadsChanged;
                        value.CollectionChanged += LoadsChanged;
                    }
                }
                m_loads = value;
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Creates an instance of the class.
        /// </summary>
        public Step()
        {
            m_loads = new LoadList(this);
        }

        #endregion
    }
}
...