0

I am getting a request in the form of xml which i need converted to list in c# using web api.

Here's the request xml that i receive

<OTA_HotelInvCountNotifRQ xmlns="http://www.zzz.com/OTA/2015/03"
TimeStamp="2015-03-10T09:41:51.982" Version="1.2"> <Inventories 
HotelCode="10001"> <Inventory> <StatusApplicationControl Start="2015-03-16" 
End="2015-03-30" Mon="0" Tue="0" Wed="0" Thur="0" Fri="0" Sat="1" Sun="1" 
InvTypeCode="DLX" AllInvCode="False" /> <InvCounts> <InvCount CountType="2" 
Count="17" /> </InvCounts> </Inventory> <Inventory> 
<StatusApplicationControl Start="2015-03-16" End="2015-03-30" 
AllInvCode="False" Mon="1" Tue="1" Wed="1" Thur="1" Fri="1" Sat="1" Sun="1" 
InvTypeCode="STD"></StatusApplicationControl> <InvCounts> <InvCount 
CountType="2" Count="7" /> </InvCounts> </Inventory> </Inventories> 
</OTA_HotelInvCountNotifRQ>

Here's my c# method

 public HttpResponseMessage UpdateHotelAvailability(HttpRequestMessage request)
        {
            var doc = new XmlDocument();
            doc.Load(request.Content.ReadAsStreamAsync().Result);


            var serializer = new XmlSerializer(typeof(HRootObject));
            using (var reader = XmlReader.Create(doc.InnerXml))
            {
                HRootObject Hobj = (HRootObject)serializer.Deserialize(reader);

            }


            HttpResponseMessage res = Request.CreateResponse(HttpStatusCode.OK, 200);
            return res;
        }

c# class for the list object

public class sampleclass
    {

        public class StatusApplicationControl
        {
            public string Start { get; set; }
            public string End { get; set; }
            public string Mon { get; set; }
            public string Tue { get; set; }
            public string Wed { get; set; }
            public string Thur { get; set; }
            public string Fri { get; set; }
            public string Sat { get; set; }
            public string Sun { get; set; }
            public string InvTypeCode { get; set; }
            public string AllInvCode { get; set; }
        }

        public class InvCount
        {
            public string CountType { get; set; }
            public string Count { get; set; }
        }

        public class InvCounts
        {
            public InvCount InvCount { get; set; }
        }

        public class Inventory
        {
            public StatusApplicationControl StatusApplicationControl { get; set; }
            public InvCounts InvCounts { get; set; }
        }

        public class Inventories
        {
            public string HotelCode { get; set; }
            public List<Inventory> Inventory { get; set; }
        }

        public class HRootObject
        {
            public string TimeStamp { get; set; }
            public string Version { get; set; }
            public Inventories Inventories { get; set; }
        }
    }

I need the request xml to be converted to a list by using the above class.I am getting illegal error in path now.Any help would be really appreciated. Thanks

Update :

This is what i get in the innerxml node of the doc

<OTA_HotelInvCountNotifRQ xmlns="http://www.zzz.com/OTA/2015/03"
TimeStamp="2015-03-10T09:41:51.982" Version="1.2"> <Inventories 
HotelCode="10001"> <Inventory> <StatusApplicationControl Start="2015-03-16" 
End="2015-03-30" Mon="0" Tue="0" Wed="0" Thur="0" Fri="0" Sat="1" Sun="1" 
InvTypeCode="DLX" AllInvCode="False" /> <InvCounts> <InvCount CountType="2" 
Count="17" /> </InvCounts> </Inventory> <Inventory> 
<StatusApplicationControl Start="2015-03-16" End="2015-03-30" 
AllInvCode="False" Mon="1" Tue="1" Wed="1" Thur="1" Fri="1" Sat="1" Sun="1" 
InvTypeCode="STD"></StatusApplicationControl> <InvCounts> <InvCount 
CountType="2" Count="7" /> </InvCounts> </Inventory> </Inventories> 
</OTA_HotelInvCountNotifRQ>
Melvin
  • 877
  • 3
  • 11
  • 27
  • If you are getting "illegal error in path ", you will have to first check the path. Once you could resolve the path correctly, you can use LINQ to XML to get the list out of the XML string. – A3006 Apr 07 '17 at 07:28
  • @A3006 Any idea how to do that ? – Melvin Apr 07 '17 at 07:29
  • What are you getting in request.Content.ReadAsStreamAsync().Result right now? – A3006 Apr 07 '17 at 07:29
  • @A3006 I get the mentioned request xml in innerxml node of the doc. – Melvin Apr 07 '17 at 07:33

3 Answers3

1

Try this...

public static void ReadInventory()
        {
            XDocument doc = XDocument.Load(@"D:\\Sample\\Data2.xml");
            XNamespace ns = doc.Root.Name.Namespace; // You will need to use this "ns" in every XPATH except attributes. 
            var v = from h in doc.Descendants(ns+"StatusApplicationControl")
                    select new StatusApplicationControl
                    {
                        Start = h.Attribute("Start").Value,
                        End = h.Attribute("End").Value
                    };

            foreach (var item in v)
            {
                Console.Write("Start" + item.Start + " End " + item.End + "\r\n" );
            }

            Console.WriteLine(v.Count());
        }

I have done this for only Start and End, but you can add remaining attributes.

Let me know in case you have further questions.

A3006
  • 1,051
  • 1
  • 11
  • 28
  • Thanks this works if the xml is in file format but if the same xml is send as request to web api and when i try to read them i get illegal character in path error – Melvin Apr 07 '17 at 10:17
1

This has been tested :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;


namespace ConsoleApplication49
{   
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            new Sampleclass(FILENAME);
        }
    }
    public class Sampleclass
    {
        public static HRootObject  hRootObject { get; set; }

        public Sampleclass(string filename)
        {
            XDocument doc = XDocument.Load(filename);
            XNamespace ns = ((XElement)doc.FirstNode).GetDefaultNamespace();

            hRootObject = doc.Elements(ns + "OTA_HotelInvCountNotifRQ").Select(m => new HRootObject() {
                TimeStamp = (DateTime)m.Attribute("TimeStamp"),
                Version = (string)m.Attribute("Version"),
                 Inventories = m.Elements(ns + "Inventories").Select(n => new Inventories() {
                     HotelCode = (string)n.Attribute("HotelCode"),
                     Inventory = n.Elements(ns + "Inventory").Select(o => new Inventory() {
                         StatusApplicationControl = o.Elements(ns + "StatusApplicationControl").Select(p => new StatusApplicationControl() {
                             Start = (DateTime)p.Attribute("Start"),
                             End = (DateTime)p.Attribute("End"),
                             Mon = (int)p.Attribute("Mon"),
                             Tue = (int)p.Attribute("Tue"),
                             Wed = (int)p.Attribute("Wed"),
                             Thur = (int)p.Attribute("Thur"),
                             Fri = (int)p.Attribute("Fri"),
                             Sat = (int)p.Attribute("Sat"),
                             Sun = (int)p.Attribute("Sun"),
                             InvTypeCode = (string)p.Attribute("InvTypeCode"),
                             AllInvCode = (Boolean)p.Attribute("AllInvCode")
                         }).FirstOrDefault(),
                         InvCounts = o.Elements(ns + "InvCounts").Select(p => new InvCounts() {
                             InvCount = p.Elements(ns + "InvCount").Select(q => new InvCount() {
                                 Count = (int)q.Attribute("Count"),
                                 CountType = (int)q.Attribute("CountType")
                             }).FirstOrDefault()
                         }).FirstOrDefault()
                     }).ToList()
                 }).FirstOrDefault()
            }).FirstOrDefault();
        }


        public class StatusApplicationControl
        {
            public DateTime Start { get; set; }
            public DateTime End { get; set; }
            public int Mon { get; set; }
            public int Tue { get; set; }
            public int Wed { get; set; }
            public int Thur { get; set; }
            public int Fri { get; set; }
            public int Sat { get; set; }
            public int Sun { get; set; }
            public string InvTypeCode { get; set; }
            public Boolean AllInvCode { get; set; }
        }

        public class InvCount
        {
            public int CountType { get; set; }
            public int Count { get; set; }
        }

        public class InvCounts
        {
            public InvCount InvCount { get; set; }
        }

        public class Inventory
        {
            public StatusApplicationControl StatusApplicationControl { get; set; }
            public InvCounts InvCounts { get; set; }
        }

        public class Inventories
        {
            public string HotelCode { get; set; }
            public List<Inventory> Inventory { get; set; }
        }

        public class HRootObject
        {
            public DateTime TimeStamp { get; set; }
            public string Version { get; set; }
            public Inventories Inventories { get; set; }
        }
    }


}
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • Thanks a lot for your valuable time to answer but you read xml file from local system i get them as request in web api so i get illegal character path error.But if i read xml from local pc then it is working fine. – Melvin Apr 07 '17 at 10:30
  • If you are getting back a string (innerxml) yo ucan use .Parse(string) instead of .Load(Filename). – jdweng Apr 07 '17 at 10:46
0

Thanks jdweng and A3006 i have combined both your code and ideas as one.If you expect a web request in xml then kindly see the web api method below

public HttpResponseMessage UpdateHotelAvailability()
    {

        string incomingText = this.Request.Content.ReadAsStringAsync().Result;
        XDocument doc = XDocument.Parse(incomingText);
        XNamespace ns = doc.Root.Name.Namespace;
        var v = from h in doc.Descendants(ns+"StatusApplicationControl")
                select new StatusApplicationControl
                {
                    Start = h.Attribute("Start").Value,
                    End = h.Attribute("End").Value
                };

        HttpResponseMessage res = Request.CreateResponse(HttpStatusCode.OK, 200);
        return res;
    }
Melvin
  • 877
  • 3
  • 11
  • 27