user88
user88

Reputation: 39

how to explicitly set the Order property of class members using XmlElement asp.net

I am trying to serialize my code.

When I set the Order property of class members using XmlElement ASP.Net, I got exception on this line;

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

Exception is;

Inconsistent sequencing: if used on one of the class's members,the 'Order' property is required on all particle-like members,please explicitly set 'Order' using XmlElement, XmlAnyElement or XmlArray custom attribute on class member '_hotelId'.

Code is:

 using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
             {

                 StreamReader responsereader = new  StreamReader(response.GetResponseStream());

                  var responsedata = responsereader.ReadToEnd();
                  xmldoc = (XmlDocument)JsonConvert.DeserializeXmlNode(responsedata);
                  xmldoc.Save(@"C:\New folder\myfile.xml");

                 DataTable dt = new DataTable();
                 DataRow dr;
                 dt.Columns.Add("hotelId");
                 dt.Columns.Add("name");
                 dt.Columns.Add("address1");
                 dt.Columns.Add("address2");
                 dt.Columns.Add("city");
                 dt.Columns.Add("postalCode");
                 dt.Columns.Add("countryCode");
                 dr = dt.NewRow();

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

                 Stream reader = new FileStream(@"C:\New folder\myfile.xml", FileMode.Open);

                 HotelListResponse htype = (HotelListResponse)serializer.Deserialize(reader);
                 dt.ReadXml(@"C:\New folder\myfile.xml");
                 foreach(hoteltype ht in htype.hotel){
                      GridView1.DataSource = dt;
                      GridView1.DataBind();
                  }

                 //responsereader.Close();
                  //request.GetResponse().Close();

             }
         }
         catch (WebException ex)
         { 
             if (ex.Response == null)
                 throw new NullReferenceException("WebException response");
             throw ex;
         }

 }
    [System.SerializableAttribute()] 
    [System.Xml.Serialization.XmlRoot("HotelListResponse")]
     public class HotelListResponse
     {

         [System.Xml.Serialization.XmlElementAttribute("hotel")]
         public hoteltype[] hotel;
         [System.Xml.Serialization.XmlElement(Order = 0)] 
         public hoteltype[] Items {

             get {
                 return this.hotel;
             }
             set {
                 this.hotel = value;
             }
         } 
     }

    [Serializable]    
    [XmlType("hoteltype")]
    public class hoteltype
    {
        hoteltype(){}     

        public int _hotelId;  
        public string _name;   
        public string _address1;     
        public string _address2;    
        public string _city;
        public int _postalCode;  
        public string _countryCode;

        [XmlElement]
        public hoteltype[] htype;

        [System.Xml.Serialization.XmlElement(Order=1)]

        public int hotelId
        { 
            get {
                return _hotelId;
            } 
          set{
              _hotelId = value;
         }
      }
       [System.Xml.Serialization.XmlElement(Order=2)]

      public string name
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
        }
    }
    [System.Xml.Serialization.XmlElement(Order=3)]

    public string address1
    {
        get
        {
            return _address1;
        }
        set
        {
            _address1 = value;
        }
    }
    [System.Xml.Serialization.XmlElement(Order=4)]

    public string address2
    {
        get
        {
            return _address2;
        }
        set
        {
            _address2 = value;
        }
    }
    [System.Xml.Serialization.XmlElement(Order=5)]

    public string city
    {
        get
        {
            return _city;
        }
        set
        {
            _city = value;
        }
    }
    [System.Xml.Serialization.XmlElement(Order=6)]

    public int postalCode
    {
        get
        {
            return _postalCode;
        }
        set
        {
            _postalCode = value;
        }
    }
    [System.Xml.Serialization.XmlElement(Order=7)]
    public string countryCode
    {
        get
        {
            return _countryCode;
        }
        set
        {
            _countryCode = value;
        }
    }  

}

Upvotes: 0

Views: 3146

Answers (1)

StuartLC
StuartLC

Reputation: 107357

As described in the exception, as soon as you use Order=xx, all of the serializable properties and fields on the class must be ordered. However, it seems that _hotelId may have been intended to be a private backing field. Since XmlSerializer serializes public fields as well, this may be unintentional. If _hotelId really must be public but you don't want it serialized, then you can use XmlIgnore.

I'm guessing your class might look something like:

[System.SerializableAttribute()] 
public partial class HotelListResponse 
{ 
    [System.Xml.Serialization.XmlElement(Order = 0)] 
    public string SomeOrderedField 
    { 
        get;
        set;
    } 

    // ** Problem may be here
    // Because the field is public, XmlSerializer will try to serialize this
    public int _hotelId; 

    [System.Xml.Serialization.XmlElement(Order = 1)] 
    public int HotelId
    { 
        get
        {
            return _hotelId;
        }
        set
        {
            _hotelId = value;
        }
    }

Edit Yes, that's exactly the problem

Make your backing fields private - that's why you've got the public Property accessors for.

    public int _hotelId;  => private int _hotelId;
    public string _name;  => private string _name;

etc.

Edit

    [XmlElement(Order=0)]
    public hoteltype[] htype;

I would also change it to a property at the same time. Use the automatic backing fields if you are using .NET 3.5 or higher.

    [XmlElement(Order=0)]
    public hoteltype[] htype
    {
       get;
       set;
    }

Edit

If you applied the above systematically, your serializable classes should look like:

    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlRoot("HotelListResponse")]
    public class HotelListResponse
    {
        // This is bad practice - never make a backing field public
        //[System.Xml.Serialization.XmlElementAttribute("hotel")]
        //public hoteltype[] hotel;

        // Use the >= .Net 3.5 automatic properties - this way you don't need 
        // the backing field at all, which will prevent confusion over 
        // 'what gets serialized'
        [System.Xml.Serialization.XmlElement(Order = 0)]
        public hoteltype[] Items
        {
            get;
            set;
        }
    }

    [Serializable]
    [XmlType("hoteltype")]
    public class hoteltype
    {
        public hoteltype() { }

        [System.Xml.Serialization.XmlElement(Order = 0)]
        public hoteltype[] htype
        {
            get;
            set;
        }

        [System.Xml.Serialization.XmlElement(Order = 1)]
        public int hotelId
        {
            get;
            set;
        }
        [System.Xml.Serialization.XmlElement(Order = 2)]
        public string name
        {
            get;
            set;
        }

        [System.Xml.Serialization.XmlElement(Order = 3)]
        public string address1
        {
            get;
            set;
        }
        [System.Xml.Serialization.XmlElement(Order = 4)]
        public string address2
        {
            get;
            set;
        }
        [System.Xml.Serialization.XmlElement(Order = 5)]
        public string city
        {
            get;
            set;
        }
        [System.Xml.Serialization.XmlElement(Order = 6)]

        public int postalCode
        {
            get;
            set;
        }
        [System.Xml.Serialization.XmlElement(Order = 7)]
        public string countryCode
        {
            get;
            set;
        }
    }

And testing the above via a serialize / deserialize cycle like so:

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

HotelListResponse X = new HotelListResponse();
X.Items = new hoteltype[2];
X.Items[0] = new hoteltype();
X.Items[0].address1 = "address1";
X.Items[1] = new hoteltype();
X.Items[1].address1 = "address2";

using (Stream writer = new FileStream(@"C:\temp\myfile.xml", FileMode.Create))
{
    serializer.Serialize(writer, X);
    writer.Flush();
}

Stream reader = new FileStream(@"C:\temp\myfile.xml", FileMode.Open);

HotelListResponse htype = (HotelListResponse)serializer.Deserialize(reader);

The following file Deserializes:

<?xml version="1.0"?>
<HotelListResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Items>
    <hotelId>0</hotelId>
    <address1>address1</address1>
    <postalCode>0</postalCode>
  </Items>
  <Items>
    <hotelId>0</hotelId>
    <address1>address2</address1>
    <postalCode>0</postalCode>
  </Items>
</HotelListResponse>

Upvotes: 2

Related Questions