Resolved Read data from API response

AlexJames

Well-known member
Joined
Mar 20, 2020
Messages
65
Programming Experience
10+
Hi All

I'm currently consuming a REST api and i need some guidance on reading the response data. My experience with reading this type of data is very minimal and i'm trying to find the best way to do it.

below is the code for getting the API data.

C#:
 public string ModitarWebRequestCall()
        {
            string apiUrl = "https://api.moditar.com/Document/GetContent";
            string username = "JohnDoe";
            string password = "Password123";
            string collection = "ea85fbf3-5858-4348-bcab-08a8f39ad30c";
            string markasread = "False";

            var request = (HttpWebRequest)WebRequest.Create(apiUrl);
            request.Method = "GET";
            request.Accept = "application/xml";

            request.Headers.Add("username", username);
            request.Headers.Add("password", password);
            request.Headers.Add("collection", collection);
            request.Headers.Add("Markasread", markasread);

            string content = string.Empty;
            try
            {
                using (var response = (HttpWebResponse)request.GetResponse())
                {
                    using (var stream = response.GetResponseStream())
                    {
                        using (var sr = new StreamReader(stream))
                        {
                            content = sr.ReadToEnd();
                            sr.Close();
                            Console.WriteLine("Data received from Moditar");
                        }
                    }
                }
                return content;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return null;
            }
        }

I'm using the code below to call the above method and this is where I need to process the data.

C#:
        public void ProcessDatafromModitarApi()
        {
            var getData = new ModitarApiConnection();
            getData.ModitarWebRequestCall();
        }

What is the best way to read this data ? there are options for json, xml readers, leave it as text etc. so many choices. Any guidance on this would be greatly appreciated.
 
I was thought i could deserialize the data that had already come through the stream reader
Depends, which way you handle your response. The docs recommend using xml reader though, and the Deseriaize method takes a xmlreader. Note :
Or the OP could pass in the stream directly and bypass the stream reader.
If no one else does, I will try pick this up later.
 
I did see something on the web where the dev streamed the data into memory with MemoryStreamer and then deserialised it afterwards, not sure if i'm over complicating this for myself or not.
 
You don't even have to stream it into a memory stream (unless you are planning on deserializing the same stream more than once).

This (using the new C# 8.0 using) would be sufficient:
C#:
using var response = (HttpWebResponse)request.GetResponse();
using var stream = response.GetResponseStream();
var serializer = new XmlSerializer(typeof(OrderedItem));
return (OrderedItem)serializer.Deserialize(stream);
(If you have an older version of C#, obviously use the scoped version of using.)
 
You don't even have to stream it into a memory stream (unless you are planning on deserializing the same stream more than once).

This (using the new C# 8.0 using) would be sufficient:
C#:
using var response = (HttpWebResponse)request.GetResponse();
using var stream = response.GetResponseStream();
var serializer = new XmlSerializer(typeof(OrderedItem));
return (OrderedItem)serializer.Deserialize(stream);
(If you have an older version of C#, obviously use the scoped version of using.)
Thanks Skydiver

I'm just getting bogged down with all the different options and confusing myself even more. Main focus now is just to get this XML data deserialized. In your example i'm assuming that "OrderedItem" is a node in the XML file ?
 
No. It's a class where the XML data will be read into. Typically the class type name matches the XML element name but this can be overridden. You should take time to read about XML serialization and deserialization instead of just throwing code at the screen to see what sticks.

 
No. It's a class where the XML data will be read into. Typically the class type name matches the XML element name but this can be overridden. You should take time to read about XML serialization and deserialization instead of just throwing code at the screen to see what sticks.


Ah i see now where the OrderedItem comes from, I agree I need to spend more time on serialization etc but i'm on a bit of a time crunch with this one. I also need more experience with XML , this is one section of my development career that i have ignored completely over the years. Ive created the OrderedItem class and testing your suggestion out but i get a "cannot implicitly covert type to string" in this below line.

C#:
return (OrderedItem)serializer.Deserialize(stream);

Any ideas ?
 
Yes, because a class OrderedItem cannot be convert to a string. You declared your ModitarWebRequestCall() to return a string in your line #1:
C#:
public string ModitarWebRequestCall()
Perhaps your should return a OrderedItem instead of a string.
 
I agree I need to spend more time on serialization etc but i'm on a bit of a time crunch with this one.
Tell your manager you need time to learn.
 
Yes, because a class OrderedItem cannot be convert to a string. You declared your ModitarWebRequestCall() to return a string in your line #1:
C#:
public string ModitarWebRequestCall()
Perhaps your should return a OrderedItem instead of a string.

Thanks Skydiver, i'm going to step away from this for a bit I'm getting frustrated and making stupid mistakes and missing obvious things. I actually have a ProcessXML class that calls the ModitarWebrequestCall method, I should be doing me deserialization and xml reading in that class, my initial idea was to get the data back in a string and do the work from there, but completely lost focus. I'm trying to stick to the Single responsibility Principle and have my classes focus on just one thing.
 
In that case, your original code in post #1 was mostly correct. All you needed was to use the stream reader to read to the end and return the string. There was no need to call Deserialize() after reading to the end.
 
In that case, your original code in post #1 was mostly correct. All you needed was to use the stream reader to read to the end and return the string. There was no need to call Deserialize() after reading to the end.
Probable correction? Because the Deserializer method wants a xmlreader. (Point, switch it for an XML reader since the source in code p/#1 is receiving XML) As Soon as I am free, I will try this out for you Alex. Just very snowed under with a freelance job atm
 
In that case, your original code in post #1 was mostly correct. All you needed was to use the stream reader to read to the end and return the string. There was no need to call Deserialize() after reading to the end.
Thanks Skydiver

So with my original plan, once i got the string of data back, i would then need to deserialise that so that i can read the XML. Is my thinking correct with that ?
 
See post #24... He just wants to return the string from the REST web service. He didn't actually want to deserialize within the same class. He has another class to do the deserialization.

Part of me feels that the HttpClient.GetStringAsync() maybe an easier way to get just the string, but only for that non-standard authentication scheme that client uses.
 
Probable correction? Because the Deserializer method wants a xmlreader. (Point, switch it for an XML reader since the source in code p/#1 is receiving XML) As Soon as I am free, I will try this out for you Alex. Just very snowed under with a freelance job atm
No worries at all Sheepings, I really appreciate you guys taking the time to help me with this and learn.
 
Thanks Skydiver

So with my original plan, once i got the string of data back, i would then need to deserialise that so that i can read the XML. Is my thinking correct with that ?
Yes, one you have a string, then you would pass that string into the deserializer.

Seems a little inefficient to go from stream to string and string to object, but it really depends on how your unit tests are setup.
 
Back
Top Bottom