How to call another REST API when reading current REST API data.

I am retrieving Orders data from WooCommerce by calling REST API:
https://apibuild.giving.massgeneral.org/wc-api/v2/orders?consumer_key=KEY&consumer_secret=KEY&post_status=completed&filter%5bupdated_at_min%5d=2015-03-11.
However the last element ORDER Notes I have to retrieve by calling another REST API:
https://apibuild.giving.massgeneral.org/wc-api/v2/orders/36958/notes/?consumer_key=KEY&consumer_secret=KEY
The result looks like this:
{
    "order_notes": [{
        "id": "17910",
        "created_at": "2015-03-11T18:31:26Z",
        "note": "Order sent to Zapier via the <a href=\"https:\/\/apibuild.giving.massgeneral.org\/wp-admin\/post.php?post=34836&action=edit\">T Shirt Order Fulfillment<\/a> Zapier feed.<br ><br \/>Initiator:<br \/><small>woocommerce_order_status_changed<\/small>",
        "customer_note": false
    }, {
        "id": "17911",
        "created_at": "2015-03-11T18:31:26Z",
        "note": "Order sent to Zapier via the <a href=\"https:\/\/apibuild.giving.massgeneral.org\/wp-admin\/post.php?post=35813&action=edit\">T Shirt Order Received<\/a> Zapier feed.<br ><br \/>Initiator:<br \/><small>woocommerce_order_status_changed<\/small>",
        "customer_note": false
    }, {
        "id": "17908",
        "created_at": "2015-03-11T18:31:24Z",
        "note": "Item #34767 stock reduced from 106 to 105.",
        "customer_note": false
    }, {
        "id": "17909",
        "created_at": "2015-03-11T18:31:24Z",
        "note": "Order item stock reduced successfully.",
        "customer_note": false
    }, {
        "id": "17906",
        "created_at": "2015-03-11T18:31:22Z",
        "note": "Authorize.net Transaction Approved: Visa ending in XXXX (expires XX\/XX)",
        "customer_note": false
    }, {
        "id": "17907",
        "created_at": "2015-03-11T18:31:22Z",
        "note": "Order status changed from Pending Payment to Processing.",
        "customer_note": false
    }]
}
I need ONLY to retrieve what kind of  Credit Card was used. In this example it is Visa.
I am not sure if I can call another REST API. I assigned to my variable Order Number in this case 36958.
So I created Function to retrieve Credit Card Type but got all bunch of errors. I guess I am doing something wrong. But what?
BurzhuinAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Bob LearnedCommented:
How are you calling the first REST URL?  My guess is that you can repeat the same type of request with the different URL to get the next results...
0
BurzhuinAuthor Commented:
//Call getWebServiceResult to return our WorkGroupMetric array
WCOrder[] wcOrdersOutput = GetRestServiceResult(wcApiCompleteUrl);
and looping foreach through wcOrdersOutput.
0
Bob LearnedCommented:
"So I created Function to retrieve Credit Card Type but got all bunch of errors"
Can you show me this code, please?
0
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

BurzhuinAuthor Commented:
public string CreateOrderNotes(String OrderNum)
    {
        bool fireAgain = false;
        //String yesterday = DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd");
        String strOrderNum = OrderNum;
        String strNotes = "";
        String strCardType = "";
        //String yesterday = "2015-02-02";
        //MessageBox.Show("The yesterday date is " + yesterday);
        // Build WC API complete URL
        string wcApiCompleteUrl = Variables.WCAPIBaseUrl + strOrderNum + "/notes/?" + consumer_key=" + Variables.WCAPIConsumerKey + "&consumer_secret=" + Variables.WCAPIConsumerSecret;
        // Just some kind of debug output :-)
        ComponentMetaData.FireInformation(10, "Start - URL", String.Format("The following URL has been used: {0}", wcApiCompleteUrl), "", 0, fireAgain);

        try
        {
            //Call getWebServiceResult to return our WorkGroupMetric array
            WCNotes[] wcNotesOutput = GetRestServiceResult(wcApiCompleteUrl);

            //For each group of metrics output records
            foreach (var wcNotes in wcNotesOutput)
            {
                strNotes =  wcNotes.note;

                if strNotes.Contains("Visa")
                {
                    strCardType = "Visa";
                }
                if strNotes.Contains("Master Card")
                {
                    strCardType = "Master Card";
                }
                if strNotes.Contains("American Express")
                {
                    strCardType = "American Express";
                }
                if strNotes.Contains("Discover")
                {
                    strCardType = "Discover";
                }

            }
           
            return strCardType;

        }
        catch (Exception e)
        {
            FailComponent(e.ToString());
        }
    }


    private WCNotes[] GetRestServiceResult0(string wUrl)
    {

        HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create(wUrl);

        if (Variables.UseStandardProxy)
        {
            httpWReq.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
            httpWReq.PreAuthenticate = true;
        }
        HttpWebResponse httpWResp = (HttpWebResponse)httpWReq.GetResponse();
        WCOrder[] jsonResponse = null;

        try
        {
            //Test the connection
            if (httpWResp.StatusCode == HttpStatusCode.OK)
            {

                Stream responseStream = httpWResp.GetResponseStream();
                string jsonString = null;

                //Set jsonString using a stream reader
                using (StreamReader reader = new StreamReader(responseStream))
                {
                    jsonString = reader.ReadToEnd().Replace("\\", "");
                    reader.Close();
                }

                //Deserialize our JSON
                //JavaScriptSerializer sr = new JavaScriptSerializer();
                //JSON string comes in with a leading and trailing " that need to be removed for parsing to work correctly
                //The JSON here is serialized weird, normally you would not need this trim
                //jsonResponse = sr.Deserialize<WCOrder[]>(jsonString.Trim('"'));
                WCNotes jsonRoot = DeserializeJSon<WCNotes>(jsonString);
                jsonResponse = jsonRoot.Notes;
            }
            //Output connection error message
            else
            {
                FailComponent(httpWResp.StatusCode.ToString());

            }
        }
        //Output JSON parsing error
        catch (Exception e)
        {
            FailComponent(e.ToString());
        }
        return jsonResponse;

    }
0
Bob LearnedCommented:
Oh, yeah, and the errors that you are getting, please.
0
BurzhuinAuthor Commented:
Error      1      'WCNotes' does not contain a definition for 'note' and no extension method 'note' accepting a first argument of type 'WCNotes' could be found (are you missing a using directive or an assembly reference?)      C:\Users\rk688\AppData\Local\Temp\Vsta\SSIS_SC110\Vsta4YClO6nrYU6G__uu3TqJMCw\VstahYqbmLcGTE2Ia5AbPsvqqA\main.cs      266      37      SC_62c91189374d4fd6b180997972364e08

Error      2      Cannot implicitly convert type 'WCNotes[]' to 'WCOrder[]'      C:\Users\rk688\AppData\Local\Temp\Vsta\SSIS_SC110\Vsta4YClO6nrYU6G__uu3TqJMCw\VstahYqbmLcGTE2Ia5AbPsvqqA\main.cs      332      32      SC_62c91189374d4fd6b180997972364e08

Error      3      Cannot implicitly convert type 'WCOrder[]' to 'WCNotes[]'      C:\Users\rk688\AppData\Local\Temp\Vsta\SSIS_SC110\Vsta4YClO6nrYU6G__uu3TqJMCw\VstahYqbmLcGTE2Ia5AbPsvqqA\main.cs      346      16      SC_62c91189374d4fd6b180997972364e08

Warning      4      There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "Microsoft.SqlServer.DTSRuntimeWrap, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91", "x86". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project.      C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets      1605      5      SC_62c91189374d4fd6b180997972364e08
0
Bob LearnedCommented:
Warning      4      There was a mismatch between the processor architecture of the project being built "MSIL" and the
Most of the times, you can ignore this error, unless you have an issue with SSIS.

How are WCNotes and WCOrder classes generated?  Were they hand-coded?
0
BurzhuinAuthor Commented:
#region JSON Classes
[DataContract]
class WCOrders
{
    [DataMember(Name = "orders")]
    public WCOrder[] Orders { get; set; }
}
//Class to hold our work group metrics
[DataContract]
class WCOrder
{
    [DataMember(Name = "id")]
    public int OrderId { get; set; }
    [DataMember(Name = "order_number")]
    public string OrderNo { get; set; }
    [DataMember(Name = "updated_at")]
    public string UpdatedAt { get; set; }
    [DataMember(Name = "completed_at")]
    public string CompletedAt { get; set; }
    [DataMember(Name = "status")]
    public string Status { get; set; }
    [DataMember(Name = "currency")]
    public string Currency { get; set; }
    [DataMember(Name = "billing_address")]
    public WCOrderBillingAddress BillingAddress { get; set; }
    [DataMember(Name = "total")]
    public decimal OrderTotal { get; set; }
    [DataMember(Name = "line_items")]
    public WCOrderLine[] OrderLines { get; set; }
}
[DataContract]
class WCOrderLine
{
    [DataMember(Name = "id")]
    public int LineId { get; set; }
    [DataMember(Name = "subtotal")]
    public decimal SubTotal { get; set; }
    [DataMember(Name = "subtotal_tax")]
    public decimal SubTotalTax { get; set; }
    [DataMember(Name = "total")]
    public decimal Total { get; set; }
    [DataMember(Name = "quantity")]
    public int Quantity { get; set; }
    [DataMember(Name = "name")]
    public string ProductName { get; set; }
    [DataMember(Name = "product_id")]
    public int ProductId { get; set; }
    [DataMember(Name = "sku")]
    public string ProductSKU { get; set; }
}
[DataContract]
class WCNotes
{
    [DataMember(Name = "notes")]
    public WCNotes[] Notes { get; set; }
    public WCNote[] Note { get; set; }
}
//Class to hold our work group metrics
[DataContract]
class WCNote
{
    [DataMember(Name = "note")]
    public string Note { get; set; }
}
[DataContract]
class WCOrderBillingAddress
{
    [DataMember(Name = "first_name")]
    public string BillingFirstName { get; set; }
    [DataMember(Name = "last_name")]
    public string BillingLastName { get; set; }
    [DataMember(Name = "company")]
    public string BillingCompany { get; set; }
    [DataMember(Name = "address_1")]
    public string BillingAddress1 { get; set; }
    [DataMember(Name = "address_2")]
    public string BillingAddress2 { get; set; }
    [DataMember(Name = "city")]
    public string BillingCity { get; set; }
    [DataMember(Name = "state")]
    public string BillingState { get; set; }
    [DataMember(Name = "postcode")]
    public string BillingPostcode { get; set; }
    [DataMember(Name = "country")]
    public string BillingCountry { get; set; }
    [DataMember(Name = "email")]
    public string BillingEmail { get; set; }
    [DataMember(Name = "phone")]
    public string BillingPhone { get; set; }
}
#endregion
0
Bob LearnedCommented:
'WCNotes' does not contain a definition for 'note'
 public WCNote[] Note { get; set; }

Cannot implicitly convert type 'WCNotes[]'
What line does this occur on?

Cannot implicitly convert type 'WCOrder[]' to 'WCNotes[]'  
What line does this occur on?
0
BurzhuinAuthor Commented:
Is there any way to see lines? Because it shows line 265, 331 and 345. I am starting to count and line 265 is empty line, 331 return line. 345 is between functions.
0
Bob LearnedCommented:
If you double-click on the error in the Error window, then it should take you to the code that produced the error.
0
BurzhuinAuthor Commented:
The last line is returning the error: "Error      2      'WCNotes' does not contain a definition for 'note' and no extension method 'note' accepting a first argument of type 'WCNotes' could be found (are you missing a using directive or an assembly reference?)      C:\Users\rk688\AppData\Local\Temp\Vsta\SSIS_SC110\Vsta5eloacb7NUqERBbKOguXPQ\Vsta74Ny_IHqCE6HrSmRoo3opA\main.cs      263      36      SC_62c91189374d4fd6b180997972364e08"

 //Call getWebServiceResult to return our WorkGroupMetric array
            WCNotes[] wcNotesOutput = GetRestServiceResult0(wcApiCompleteUrl);

            //For each group of metrics output records
            foreach (var wcNote in wcNotesOutput)
            {
                strNotes =  wcNote.note;

I know I declared class incorrectly:

[DataContract]
class WCNotes
{
    [DataMember(Name = "notes")]
    public WCNotes[] Notes { get; set; }
    public WCNote[] Note { get; set; }
}
//Class to hold our work group metrics
[DataContract]
class WCNote
{
    [DataMember(Name = "note")]
    public string Note { get; set; }
}
0
Bob LearnedCommented:
The "N" is upper case, so that should be:

 strNotes =  wcNote.Note;

or

public WCNote[] note { get; set; }
0
BurzhuinAuthor Commented:
I figure out other two errors. Now it is only errors I described above and warning.
0
BurzhuinAuthor Commented:
Now I have only warning, but when I tried to run the Package I got an error.
0
Bob LearnedCommented:
It would help to know the runtime error...
0
BurzhuinAuthor Commented:
I got two:

Here is one:

[Error Getting Data From Webservice!] Error: System.Runtime.Serialization.SerializationException: There was an error deserializing the object of type WCNotes. Encountered unexpected character 'h'. ---> System.Xml.XmlException: Encountered unexpected character 'h'.
   at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, XmlException exception)
   at System.Runtime.Serialization.Json.XmlJsonReader.Read()
   at System.Xml.XmlBaseReader.Skip()
   at System.Runtime.Serialization.XmlObjectSerializerReadContext.SkipUnknownElement(XmlReaderDelegator xmlReader)
   at System.Runtime.Serialization.XmlObjectSerializerReadContext.HandleMemberNotFound(XmlReaderDelegator xmlReader, ExtensionDataObject extensionData, Int32 memberIndex)
   at System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson.GetJsonMemberIndex(XmlReaderDelegator xmlReader, XmlDictionaryString[] memberNames, Int32 memberIndex, ExtensionDataObject extensionData)
   at ReadWCNotesFromJson(XmlReaderDelegator , XmlObjectSerializerReadContextComplexJson , XmlDictionaryString , XmlDictionaryString[] )
   at System.Runtime.Serialization.Json.JsonClassDataContract.ReadJsonValueCore(XmlReaderDelegator jsonReader, XmlObjectSerializerReadContextComplexJson context)
   at System.Runtime.Serialization.Json.JsonDataContract.ReadJsonValue(XmlReaderDelegator jsonReader, XmlObjectSerializerReadContextComplexJson context)
   at System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson.ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader)
   at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator reader, String name, String ns, Type declaredType, DataContract& dataContract)
   at System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, DataContract dataContract, String name, String ns)
   at System.Runtime.Serialization.Json.DataContractJsonSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName)
   at System.Runtime.Serialization.XmlObjectSerializer.InternalReadObject(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
   at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
   --- End of inner exception stack trace ---
   at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean

verifyObjectName, DataContractResolver dataContractResolver)
   at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject(XmlDictionaryReader reader)
   at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject(Stream stream)
   at ScriptMain.DeserializeJSon[T](String jsonString)
   at ScriptMain.GetRestServiceResult0(String wUrl)

Here is another:

[Error Getting Data From Webservice!] Error: System.NullReferenceException: Object reference not set to an instance of an object.
   at ScriptMain.CreateOrderNotes(String OrderNum)
0
Bob LearnedCommented:
Is this JSON or XML?
0
BurzhuinAuthor Commented:
I am using JSON. I have no idea from where XML popped out.
0
Bob LearnedCommented:
What are you using to deserialize?

  WCNotes jsonRoot = DeserializeJSon<WCNotes>(jsonString);
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
BurzhuinAuthor Commented:
So, if I understood it correctly, since my WCNotes class is not nested I do not have to deserialize it?
0
Bob LearnedCommented:
If you have a single, complex object, then you should be able to deserialize the entire structure with a single call to deserialize.

What are you using to deserialize?
0
BurzhuinAuthor Commented:
Class WCNotes. Am I not?
0
Bob LearnedCommented:
"So, if I understood it correctly, since my WCNotes class is not nested I do not have to deserialize it?"
Maybe I misunderstood your question.  If WCNotes is the top-level object, then you do need to deserialize that object.
0
BurzhuinAuthor Commented:
You mean function?

public static T DeserializeJSon<T>(string jsonString)
    {
        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
        MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
        T obj = (T)ser.ReadObject(stream);
        return obj;
    }
0
BurzhuinAuthor Commented:
As I understood, I was using wrong declaration. I put "notes" where it should be "order_notes".
0
Bob LearnedCommented:
I would look at Newtonsoft JSON.  You can install the package with Nuget.  I am not a big fan of the DataContractJsonSerializer.

Json.NET 6.0.8
https://www.nuget.org/packages/Newtonsoft.Json/
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.