locked
handling the response from an API call. RRS feed

  • Question

  • User842841555 posted

    Hello everyone, as you can see below, I am making an API call to a third party. The API call seems to be working, however I'm not entirely sure how to handle the data.

    The XML that is returned is in the following format:

    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
       <soap:Body>
          <SearchExResponse xmlns="https://samplepage.com">
             <SearchExResult><![CDATA[<call>
      <Row>
        <id>11983040</id>
        <type>pdf</type>
        <pages>2</pages>
        <size>155949</size>
        <insert_dt>2019-09-04T13:06:37-04:00</insert_dt>
        <index1>TEST-1</index1>
        <index2>20190904</index2>
        <index3>0111</index3>
        <index4>REPORT</index4>
        <index5>testing results</index5>
        <index6>New</index6>
        <index7>1</index7>
        <user_id />
        <status_dt>1900-01-01T00:00:00-05:00</status_dt>
        <status />
      </Row>
    </call>]]></SearchExResult>
          </SearchExResponse>
       </soap:Body>
    </soap:Envelope>
    using System;
    using System.Web;
    using System.Web.UI.WebControls;
    using System.Text.RegularExpressions;
    using System.Web.Services;
    using System.Web.Services.Description;
    
        protected void AccessionDataGridView_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            if (e.CommandName == "Select")
            {
                int rowIndex = Convert.ToInt32(e.CommandArgument);
                GridViewRow gvr = AccessionDataGridView.Rows[rowIndex];
                string acc = (gvr.FindControl("AccessionLabel") as Label).Text;
                //modify string to the API's required format
                acc = acc.Insert(5, "-");
    			
                WEB.WebServices eb = new WEB.WebServices();
    			//string to store results
                string XMLResults;
    			
                XMLResults = eb.SearchEx("user", "pass", "cabinet", "", "", "0111", "", "", "", "", "", "", "X19-00001");
    			
    			//created this string to see if an output was generated, full xml in an alert caused the site to 404.
                string smaller = XMLResults.Substring(0, 5);
    			//visual confirmation the api call worked
                Response.Write("<script>alert('eee" + smaller + "')</script>");
    
               // }
            }
        }

    You can see how I'm trying to see the saved string, it gives a 404 if I try to return the entire thing in an alert box, so I stripped it down to just 5 characters..It appears to be working, but I can't know for sure I suppose without seeing the entire thing.

    Also, the XML response could potentially have multiple rows, if it has multiple rows I want to do something else, if it has just one row I want it to pull text from index5 and store it in a string by itself.

    Any idea how to efficiently do this? I've searched a lot and typically see a lot of stand alone application examples, I've also seen LINQ, but I do not have services.xml.linq

    Wednesday, October 2, 2019 5:06 PM

All replies

  • User475983607 posted

    The XML is from a SOAP service not Web API.  Create a service reference using the SOAP service's WSDL.  This will generate code (a proxy) that you can use to interact with the service like any library that you currently use.  All the XML serialization is handled for you.

    https://docs.microsoft.com/en-us/dotnet/core/additional-tools/wcf-web-service-reference-guide

    The 3rd party documentation should have documentation that shows the WSDL URL and how to use the service.

    Wednesday, October 2, 2019 6:23 PM
  • User-474980206 posted

    you web service is a typical simple wrapper around a xml response. the <SearchExResult> has an encoded xml payload. you need to use a xml parser to get the string content value of <SearchExResult>. then you run this string thru another xml parser to get the payload values.

    pick the xml libraries of you choice. you can use xmlreader to get the <SearchExResult> content, then use another xmleader on this content.

      https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmlreader?view=netframework-4.8

    I'd parse the payload xml into a list of poco objects.

    Wednesday, October 2, 2019 6:30 PM
  • User842841555 posted

    Thank you for your help so far, I have read and used various examples I've found as reference, however I am getting a 404 whenever I try to execute this piece of code (sadly)

                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(XMLResults);
                XmlNamespaceManager xmlnsManager = new System.Xml.XmlNamespaceManager(xmlDoc.NameTable);
    
                xmlnsManager.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
                xmlnsManager.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
                xmlnsManager.AddNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
                xmlnsManager.AddNamespace("si", "https://samplepage.com");
    
                XmlNode node = xmlDoc.SelectSingleNode("/soap:Envelope/soap:Body/si:SearchExResponse/si:SearchExResult/si:call/si:Row/si:Index1", xmlnsManager);
                string batch = node.InnerText;

    Wednesday, October 2, 2019 7:38 PM
  • User283571144 posted

    Hi Mike1986,

    Since the SearchExResult innertext is a cdate not xml nodes. you couldn't directly select the index1 nodes. 

    You should firstly read the SearchExResult innertext and then reload its xml innertext and use select nodes to select it again.

    More details, you could refer to below codes:

                //I use file instead of the xml string.
    string path = @"D:\soap.xml"; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(path); XmlNamespaceManager xmlnsManager = new System.Xml.XmlNamespaceManager(xmlDoc.NameTable); xmlnsManager.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/"); xmlnsManager.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"); xmlnsManager.AddNamespace("xsd", "http://www.w3.org/2001/XMLSchema"); xmlnsManager.AddNamespace("si", "https://samplepage.com"); // You'd access the full path like this XmlNode node = xmlDoc.SelectSingleNode("/soap:Envelope/soap:Body/si:SearchExResponse/si:SearchExResult", xmlnsManager); string cdateinnertext = node.InnerText; XmlDocument xmlDoc1 = new XmlDocument(); xmlDoc1.LoadXml(cdateinnertext); XmlNode node1 = xmlDoc1.SelectSingleNode("/call/Row/index1"); string res = node1.InnerText; int i = 0;

    Result;

    Best Regards,

    Brando

    Thursday, October 3, 2019 2:13 AM
  • User753101303 posted

    This kind of service is supposed to be used this way: https://stackoverflow.com/questions/1302525/how-to-use-a-wsdl ie it provides a service description as a wsdl document and it is used by tools to create the needed classes for you. You'll then use those classes and the "plumbing" is done for you behind the scene.

    Basically as done for JSON or XML rather than writing explicitely tags to a file, you generate classes to serialize/deserialize/process those messages for you allowing you to access to a much higher level view.

    Thursday, October 3, 2019 12:40 PM
  • User-474980206 posted

    the wsdl would only say that the payload was:

    public class SearchExResponse
    {
        public string SearchExResult {get; set;}
    }
    

    it would not know SearchExResult is an xml string. You would still need to use an xml parser on it.

    Thursday, October 3, 2019 2:11 PM