Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 323
  • Last Modified:

How to make a XML call in C#

I'm new to C# and wanted to know how to make a XML call.

I have the following XML code. I need to do a REQUEST to Authorize.NET, and am expecting a RESPONSE with an XML document.

<?xml version="1.0" encoding="utf-8"?>
<getTransactionDetailsRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
  <merchantAuthentication>
    <name>YourUserLogin</name>
    <transactionKey>YourTranKey</transactionKey>
  </merchantAuthentication>
  <transId>1111111111</transId>
</getTransactionDetailsRequest>

Open in new window


This is what I tried, but it fails:

private string GetTransactionDetails(long _transID)
        {
            string reason = string.Empty;
            bool IsLive = false;
            const string LIVE_URL = "https://api.authorize.net/xml/v1/request.api";
            const string TEST_URL = "https://apitest.authorize.net/xml/v1/request.api";
            const string TEST_NAME = "abc";
            const string TEST_TRANS_KEY = "abc";
            const string TEST_TRANS_ID = "2226934625";

            XNamespace ns = "AnetApi/xml/v1/schema/AnetApiSchema.xsd";

            XDocument doc = new XDocument(
                    new XElement(ns + "getTransactionDetailsRequest",
                        new XAttribute("xmlns", "AnetApi/xml/v1/schema/AnetApiSchema.xsd"),
                    new XElement(ns + "merchantAuthentication",
                        new XElement(ns + "name", TEST_NAME),
                        new XElement(ns + "transactionKey", TEST_TRANS_KEY)),
                    new XElement(ns + "transId", TEST_TRANS_ID))
                    );

            MemoryStream stream = new MemoryStream();
            doc.Save(stream);
            byte[] postBytes = new byte[stream.Length];
            stream.Seek(0, SeekOrigin.Begin);
            stream.Read(postBytes, 0, postBytes.Length);
            stream.Close();

            WebClient WC = new WebClient();
            ServicePointManager.ServerCertificateValidationCallback = TrustAllCertificateCallback;
            HttpWebRequest wrequest = (HttpWebRequest)WebRequest.Create(IsLive ? LIVE_URL : TEST_URL);
            wrequest.Timeout = 300000;
            wrequest.Method = "POST";
            wrequest.ContentType = "application/x-www-form-urlencoded";
            wrequest.ContentLength = stream.Length;

            Stream lilriver = wrequest.GetRequestStream();
            lilriver.Write(postBytes, 0, postBytes.Length);

            HttpWebResponse wresponse = (HttpWebResponse)wrequest.GetResponse();
            Stream rstream = wresponse.GetResponseStream();
            Encoding enc = System.Text.Encoding.GetEncoding("utf-8");

            StreamReader strRead = new StreamReader(rstream, enc);
            string result = strRead.ReadToEnd();
            wresponse.Close();
            strRead.Close();
            rstream.Close();

            return reason;
        }

Open in new window

0
pzozulka
Asked:
pzozulka
3 Solutions
 
sudheeshthegreatCommented:
When you say "it fails", do you get an exception on executing this code? If so, can you share those details?
0
 
pzozulkaAuthor Commented:
Exception: Cannot access a closed Stream.
0
 
käµfm³d 👽Commented:
Look at lines 27 and 35. Notice anything wrong about their order?   ; )
0
NFR key for Veeam Backup for Microsoft Office 365

Veeam is happy to provide a free NFR license (for 1 year, up to 10 users). This license allows for the non‑production use of Veeam Backup for Microsoft Office 365 in your home lab without any feature limitations.

 
pzozulkaAuthor Commented:
Thanks, I resolved that by moving it down a bit, but still can't get the XML response which looks like the below:

Any help would be greatly appreciated.


WebResponse webResponse = wrequest.GetResponse();
            XmlDocument xmldoc = new XmlDocument();
            xmldoc.Load(XmlReader.Create(webResponse.GetResponseStream()));

            XmlNodeList xmList = xmldoc.SelectNodes("/getTransactionDetailsResponse/transaction");

            foreach (XmlNode xn in xmList)
            {
                string responseCode = xn["responseReasonCode"].InnerText;
                string responseDesc = xn["responseReasonDescription"].InnerText;
            }

            var n = xmldoc.DocumentElement.SelectNodes("responseReasonCode"); // returns 0

Open in new window



<?xml version="1.0" encoding="utf-8"?>
<getTransactionDetailsResponse xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
  <messages>
    <resultCode>Ok</resultCode>
    <message>
      <code>I00001</code>
      <text>Successful.</text>
    </message>
  </messages>
  <transaction>
    <transId>1111111111</transId>
    <submitTimeUTC>2002-05-30T09:01:13Z</submitTimeUTC>
    <submitTimeLocal>2002-05-30T02:01:13</submitTimeLocal>
    <transactionType>authOnlyTransaction</transactionType>
    <transactionStatus>settledSuccessfully</transactionStatus>
    <responseCode>1</responseCode>
    <responseReasonCode>1</responseReasonCode>
    <responseReasonDescription>Approved.</responseReasonDescription>
    <authCode>000000</authCode>
    <AVSResponse>X</AVSResponse>
    <cardCodeResponse>M</cardCodeResponse>
    <batch>
      <batchId>12345</batchId>
      <settlementTimeUTC>2002-05-30T10:01:13Z</settlementTimeUTC>
      <settlementTimeLocal>2002-05-30T03:01:13</settlementTimeLocal>
      <settlementState>settledSuccessfully</settlementState>
    </batch>
    <order>
      <invoiceNumber>INV00001</invoiceNumber>
      <description>some description</description>
      <purchaseOrderNumber>PO000001</purchaseOrderNumber>
    </order>
    <authAmount>2.00</authAmount>
    <settleAmount>2.00</settleAmount>
    <tax>
      <amount>1.00</amount>
      <name>WA state sales tax</name>
      <description>Washington state sales tax</description>
    </tax>
    <shipping>
      <amount>2.00</amount>
      <name>ground based shipping</name>
      <description>Ground based 5 to 10 day shipping</description>
    </shipping>
    <lineItems>
      <lineItem>
        <itemId>ITEM00001</itemId>
        <name>name of item sold</name>
        <description>Description of item sold</description>
        <quantity>1</quantity>
        <unitPrice>6.95</unitPrice>
        <taxable>true</taxable>
      </lineItem>
      <lineItem>
        <itemId>ITEM00001</itemId>
        <name>name of item sold</name>
        <description>Description of item sold</description>
        <quantity>1</quantity>
        <unitPrice>6.95</unitPrice>
        <taxable>true</taxable>
      </lineItem>
    </lineItems>
    <prepaidBalanceRemaining>30.00</prepaidBalanceRemaining>
    <taxExempt>false</taxExempt>
    <payment>
      <!-- either creditCard or bankAccount will be here -->
      <creditCard>
        <cardNumber>XXXX1111</cardNumber>
        <expirationDate>XXXX</expirationDate>
        <cardType>Visa</cardType>
      </creditCard>
      <!--<bankAccount>
        <maskedAccountNumber>XXXX0000</maskedAccountNumber>
        <maskedAbaRoutingNumber>XXXX0000</maskedAbaRoutingNumber>
        <nameOnAccount>John Doe</nameOnAccount>
        <bankName>Bank of Blah</bankName>
        <echeckType>WEB</echeckType>
      </bankAccount>-->
    </payment>
    <customer>
      <type>individual</type>
      <id>ABC00001</id>
      <email>mark@example.com</email>
    </customer>
    <billTo>
      <firstName>John</firstName>
      <lastName>Doe</lastName>
      <company></company>
      <address>123 Main St.</address>
      <city>Bellevue</city>
      <state>WA</state>
      <zip>98004</zip>
      <country>USA</country>
      <phoneNumber>000-000-0000</phoneNumber>
      <faxNumber></faxNumber>
    </billTo>
    <shipTo>
      <firstName>John</firstName>
      <lastName>Doe</lastName>
      <company></company>
      <address>123 Main St.</address>
      <city>Bellevue</city>
      <state>WA</state>
      <zip>98004</zip>
      <country>USA</country>
    </shipTo>
    <recurringBilling>false</recurringBilling>
    <customerIP>0.0.0.0</customerIP>
  </transaction>
</getTransactionDetailsResponse>

Open in new window

0
 
Michael FowlerSolutions ConsultantCommented:
If you place a break point at

WebResponse webResponse = wrequest.GetResponse();

Open in new window


what is in the webResponse object after this call completes?
0
 
pzozulkaAuthor Commented:
I can't output the entirety of the webResponse object, but here is the header of it.

{Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,POST,OPTIONS
Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method
Content-Length: 2529
Cache-Control: private
Content-Type: application/xml; charset=utf-8
Date: Wed, 14 Jan 2015 06:14:03 GMT
Server: Microsoft-IIS/7.5
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET

}

Open in new window



After: xmldoc.Load(XmlReader.Create(webResponse.GetResponseStream()));
The below is the value of xmldoc's InnerXML

<?xml version="1.0" encoding="utf-8"?><getTransactionDetailsResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd"><messages><resultCode>Ok</resultCode><message><code>I00001</code><text>Successful.</text></message></messages><transaction><transId>2226934625</transId><submitTimeUTC>2015-01-13T17:54:52.79Z</submitTimeUTC><submitTimeLocal>2015-01-13T09:54:52.79</submitTimeLocal><transactionType>authCaptureTransaction</transactionType><transactionStatus>settledSuccessfully</transactionStatus><responseCode>1</responseCode><responseReasonCode>1</responseReasonCode><responseReasonDescription>Approval</responseReasonDescription><authCode>MTG89G</authCode><AVSResponse>Y</AVSResponse><cardCodeResponse>P</cardCodeResponse><batch><batchId>4019230</batchId><settlementTimeUTC>2015-01-14T02:39:01.887Z</settlementTimeUTC><settlementTimeLocal>2015-01-13T18:39:01.887</settlementTimeLocal><settlementState>settledSuccessfully</settlementState></batch><order><invoiceNumber>INV-12345</invoiceNumber><description>Product Description</description><purchaseOrderNumber>456654</purchaseOrderNumber></order><authAmount>5.00</authAmount><settleAmount>5.00</settleAmount><tax><amount>4.26</amount><description>level2 tax</description></tax><shipping><amount>4.26</amount><description>level2 tax</description></shipping><duty><amount>8.55</amount><description>duty description</description></duty><lineItems><lineItem><itemId>1</itemId><name>vase</name><description>Cannes logo</description><quantity>18.00000</quantity><unitPrice>45.00</unitPrice><taxable>false</taxable></lineItem></lineItems><taxExempt>false</taxExempt><payment><creditCard><cardNumber>XXXX0015</cardNumber><expirationDate>XXXX</expirationDate><cardType>MasterCard</cardType></creditCard></payment><customer><id>99999456654</id></customer><billTo><firstName>Ellen</firstName><lastName>Johnson</lastName><company>Souveniropolis</company><address>14 Main Street</address><city>Pecan Springs</city><state>TX</state><zip>44628</zip><country>USA</country></billTo><shipTo><firstName>China</firstName><lastName>Bayles</lastName><company>Thyme for Tea</company><address>12 Main Street</address><city>Pecan Springs</city><state>TX</state><zip>44628</zip><country>USA</country></shipTo><recurringBilling>false</recurringBilling><customerIP>192.168.1.1</customerIP><product>Card Not Present</product><marketType>eCommerce</marketType></transaction></getTransactionDetailsResponse>

Open in new window


The next line is where it seems to fall apart -- nothing is retrieved in SelectNodes.

I also tried another way (below), but node comes back as NULL:
//XDocument xdoc = XDocument.Load(XmlReader.Create(webResponse.GetResponseStream()));
            ////var node = xdoc.Descendants().Where(n => n.Name == "responseReasonCode").FirstOrDefault();
            //var node = xdoc.Descendants("responseReasonCode").FirstOrDefault();
         
            //if (node != null)
            //{
            //    reason = node.Value;
            //}

Open in new window

0
 
louisfrCommented:
Your XML has a namespace. Your XPath hasn't. Try the following:
XmlNamespaceManager mgr = new XmlNamespaceManager(xmldoc.NameTable);
mgr.AddNamespace("s", "AnetApi/xml/v1/schema/AnetApiSchema.xsd");
XmlNodeList xmList = xmldoc.SelectNodes("/s:getTransactionDetailsResponse/s:transaction", mgr);

Open in new window

0
 
pzozulkaAuthor Commented:
The XML I am sending in my request has a namespace. However, the response XML I'm receiving from Authorize.NET is completely different than the request XML I am sending to them.
0
 
louisfrCommented:
You wrote:
After: xmldoc.Load(XmlReader.Create(webResponse.GetResponseStream()));
The below is the value of xmldoc's InnerXML
<?xml version="1.0" encoding="utf-8"?><getTransactionDetailsResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd"><messages><resultCode>Ok</resultCode><message><code>I00001</code><text>Successful.</text></message></messages><transaction><transId>2226934625</transId><submitTimeUTC>2015-01-13T17:54:52.79Z</submitTimeUTC><submitTimeLocal>2015-01-13T09:54:52.79</submitTimeLocal><transactionType>authCaptureTransaction</transactionType><transactionStatus>settledSuccessfully</transactionStatus><responseCode>1</responseCode><responseReasonCode>1</responseReasonCode><responseReasonDescription>Approval</responseReasonDescription><authCode>MTG89G</authCode><AVSResponse>Y</AVSResponse><cardCodeResponse>P</cardCodeResponse><batch><batchId>4019230</batchId><settlementTimeUTC>2015-01-14T02:39:01.887Z</settlementTimeUTC><settlementTimeLocal>2015-01-13T18:39:01.887</settlementTimeLocal><settlementState>settledSuccessfully</settlementState></batch><order><invoiceNumber>INV-12345</invoiceNumber><description>Product Description</description><purchaseOrderNumber>456654</purchaseOrderNumber></order><authAmount>5.00</authAmount><settleAmount>5.00</settleAmount><tax><amount>4.26</amount><description>level2 tax</description></tax><shipping><amount>4.26</amount><description>level2 tax</description></shipping><duty><amount>8.55</amount><description>duty description</description></duty><lineItems><lineItem><itemId>1</itemId><name>vase</name><description>Cannes logo</description><quantity>18.00000</quantity><unitPrice>45.00</unitPrice><taxable>false</taxable></lineItem></lineItems><taxExempt>false</taxExempt><payment><creditCard><cardNumber>XXXX0015</cardNumber><expirationDate>XXXX</expirationDate><cardType>MasterCard</cardType></creditCard></payment><customer><id>99999456654</id></customer><billTo><firstName>Ellen</firstName><lastName>Johnson</lastName><company>Souveniropolis</company><address>14 Main Street</address><city>Pecan Springs</city><state>TX</state><zip>44628</zip><country>USA</country></billTo><shipTo><firstName>China</firstName><lastName>Bayles</lastName><company>Thyme for Tea</company><address>12 Main Street</address><city>Pecan Springs</city><state>TX</state><zip>44628</zip><country>USA</country></shipTo><recurringBilling>false</recurringBilling><customerIP>192.168.1.1</customerIP><product>Card Not Present</product><marketType>eCommerce</marketType></transaction></getTransactionDetailsResponse>

Open in new window

The part where it says xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd" tells me there's a namespace in that xml.
0
 
pzozulkaAuthor Commented:
Thanks. It fails on the following line with the following exception:
XmlNodeList xmList = xmldoc.SelectNodes("s:/getTransactionDetailsResponse/s:transaction", mgr);

Open in new window


's:/getTransactionDetailsResponse/s:transaction' has an invalid qualified name.

The attached screen shot shows what xml doc looks like after the following line of code -- hoping this info would help:
xmldoc.Load(XmlReader.Create(webResponse.GetResponseStream()));

Open in new window


xmldoc
0
 
louisfrCommented:
you wrote
s:/getTransactionDetailsResponse/s:transaction
instead of
/s:getTransactionDetailsResponse/s:transaction
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now