Solved

How to make a XML call in C#

Posted on 2015-01-13
11
269 Views
Last Modified: 2015-01-23
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
Comment
Question by:pzozulka
11 Comments
 
LVL 9

Expert Comment

by:sudheeshthegreat
ID: 40547968
When you say "it fails", do you get an exception on executing this code? If so, can you share those details?
0
 
LVL 8

Author Comment

by:pzozulka
ID: 40547997
Exception: Cannot access a closed Stream.
0
 
LVL 75

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 166 total points
ID: 40548014
Look at lines 27 and 35. Notice anything wrong about their order?   ; )
0
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 
LVL 8

Author Comment

by:pzozulka
ID: 40548127
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
 
LVL 23

Expert Comment

by:Michael74
ID: 40548268
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
 
LVL 8

Author Comment

by:pzozulka
ID: 40548299
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
 
LVL 11

Assisted Solution

by:louisfr
louisfr earned 334 total points
ID: 40548359
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
 
LVL 8

Author Comment

by:pzozulka
ID: 40549197
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
 
LVL 11

Expert Comment

by:louisfr
ID: 40549222
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
 
LVL 8

Author Comment

by:pzozulka
ID: 40549264
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
 
LVL 11

Accepted Solution

by:
louisfr earned 334 total points
ID: 40549273
you wrote
s:/getTransactionDetailsResponse/s:transaction
instead of
/s:getTransactionDetailsResponse/s:transaction
0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Xsl-fo show PDF when no results are returned 2 18
Alert on Server memory 2 22
TSQL query to generate xml 4 34
RegEx with optional part 4 23
This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

773 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question