Solved

How to make a XML call in C#

Posted on 2015-01-13
11
255 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 74

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
 
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
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
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

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Suggested Solutions

For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
Many times as a report developer I've been asked to display normalized data such as three rows with values Jack, Joe, and Bob as a single comma-separated string such as 'Jack, Joe, Bob', and vice versa.  Here's how to do it. 
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

759 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now