Multiple APIs from different providers on the same page

I have a ASP.net page that queries an API provider which works as expected but I want to add APIs from other providers on the same page. How can I achieve this?
Below is the example of the current API query:

Dim doc  As New XmlDocument()
doc.Load("http://api.test.com/1.0/products.xml;q=paris?token=SAD345A8718524374ZXZXCVMSHWEU8")

Dim nsManager As New XmlNamespaceManager(doc.NameTable)
nsManager.AddNamespace("ns1", "urn:com:test:pf:model:xml:output")
nsManager.AddNamespace("ns2", "urn:com:test:pf:model:xml:common")
Dim nodes As XmlNodeList = doc.SelectNodes("//ns1:products/ns1:product", nsManager)

Dim dataSource As IEnumerable
dataSource = From node As XmlNode in nodes
Select Name = node.SelectSingleNode("ns2:name", nsManager).InnerText, _
Description = node.SelectSingleNode("ns2:description", nsManager).InnerText, _
Image = node.SelectSingleNode("ns2:productImage", nsManager).InnerText, _

Set up an Apollo server and let the front end deal with it??? I KID, I JOKE(kind of).

Ok I tried this method by loading 3 APIs in this way:

Dim doc As New XmlDocument()
dim doc1 = (“AP1”)
dim doc2 = (“AP2”)
dim doc3 = (“AP3”)

doc.Load(doc1)
doc.Load(doc2)
doc.Load(doc3)

But this always load the last one API3 and ignores the first 2. Is there a way to get to load all three instead of only the third one?

I don’t know what you mean by API. I am not aware of a specific definition of that in the context of ASP.Net.

XmlDocument is a class, not an API. So I do not understand.

How do you know that or why do you think that is so?

In the first code at the top of the page, I have put an example of the API I am querying. It is the Application Programming Interface I am using and is not specific to any language. below is the API i am querying and getting the results back.

doc.Load("http://api.test.com/1.0/products.xml;q=paris?token=SAD345A8718524374ZXZXCVMSHWEU8")

They might call it an API but for us it is not. You are simply loading an XML document.

The answer would be easy if you understood the basic OOP concept of classes. You simply need to create separate instances of the XmlDocument class. You are creating doc1, doc2 and doc3 but then you use doc (not doc1, doc2 and doc3) for the load. You need to create doc1, doc2 and doc3 as instances of XmlDocument and then use each of them, not doc. Do you understand?

I have already done that but it doesn t work because the code below is just one instance and it works but if I add more instances, it doesnt work…I have a search box that query the API xml file so if I add separate xml files, how will the search query all the files:

This is one instance:

dim docx = ("http://api.link.com/1.0/products.xml;q='%"&Request.QueryString("id")&"%';tdCategoryId=168;fid=20590......")

doc.Load(docx)
Dim nsManager As New XmlNamespaceManager(doc.NameTable)
nsManager.AddNamespace("ns1", "urn:com:tradedoubler:pf:model:xml:output")
nsManager.AddNamespace("ns2", "urn:com:tradedoubler:pf:model:xml:common")
Dim nodes As XmlNodeList = doc.SelectNodes("//ns1:products/ns1:product", nsManager)
Dim dataSource As IEnumerable


dataSource = From node As XmlNode in nodes
Select Name = node.SelectSingleNode("ns2:name", nsManager).InnerText, _
Description = node.SelectSingleNode("ns2:description", nsManager).InnerText, _
Image = node.SelectSingleNode("ns2:productImage", nsManager).InnerText, _
Price = node.SelectSingleNode("ns1:offers/ns1:offer/ns1:priceHistory/ns2:price", nsManager).InnerText, _
ProductUrl = node.SelectSingleNode("ns1:offers/ns1:offer/ns2:productUrl", nsManager).InnerText, _
ProgramName = node.SelectSingleNode("ns1:offers/ns1:offer/ns2:programName", nsManager).InnerText, _
Logo = node.SelectSingleNode("ns1:offers/ns1:offer/ns2:programLogo", nsManager).InnerText
rpMyRepeater.DataSource = dataSource
rpMyRepeater.DataBind()
type or paste code here

If you understand

Are you writing classes (OOP) to perform those operations? It has been at least 8 years since I done XML. All the APIs I call return JSON to me for parsing.

You might want to set up a simple repository pattern.

I use a repository class pattern to simplify my data access. This allow me to add new API or databases at will. My User Interface/front end is separated from the backend via the repository pattern. Here is a high level overview very basic pattern.

A. Create a class that represents the product

B. Write a Repository Class that contains the methods for retrieving the data and returning the data in a List<product>. You would place your API calls in this class.

   public List<product> GetProducts(){
       // contains calls to different APIs
      List<product> products = new  new List<product>();
     products = GetDataFromAPI();
     products.Add(GetDataFromAPI2());
     products.Add(GetDataFromSomeDB());
    return products;
}
 public List<product> GetDataFromAPI(){ Your code here that returns a list products}
 public List<product> GetDataFromAPI2(){ data access that returns products}
public List<product> GetDataFromSomeDB(){ data access that returns products}

C. The UserControl or Page would make calls to the Repository Class then bind the results to the grid or repeater.

1 Like

The issue I have isnt with getting the data. The data can be viewed but it cant be bound to the repeater properly, It always binds the last one so it overwrites the first one. So in the code below, both datasources 1 and 2 show data but not simultaneously. if I swap the order, it always shows the second one, so it is the binding that is the issue. Need to find a way to add both datasources 1 and 2 to another item and then bind that item ?

Dim dataSource1 As IEnumerable
Dim dataSource2 As IEnumerable

rpMyRepeater.Datasource = datasource1
rpMyRepeater.Datasource = datasource2
rpMyRepeater.Databind()

I think not and if not then I cannot help you if you don’t listen.

Read my last comment. I have created multiple xml instances but the problem i m experiencing is binding multiple datasources to the same repeater

XmlDocument.doc (13.1 KB)
The code is attached. I highlighted where the binding is which is where the problem is. There are two xml instances in the attachement. It s finding a way to bind both xml datasources (highlighted) to the same repeater. The second one always overwrites the first one

rpMyRepeater.Datasource = datasource1
rpMyRepeater.Datasource = datasource2 

How are the object differentiated on those two lines?

datasource1 is getting data from node1 and datasource2 from node2,

dataSource1 = From node1 As XmlNode1 in nodes
dataSource2 = From node2 As XmlNode2 in nodes

The results of datasource1 should be appended to datasource2 and be bound to the repeater but they are just overwritten

Isn’t that what assigning a value does to any existing value, overwrite it?

Yes Agree. I am trying to find a way to append the results of both datasources togethewr into one and then bind the repeater to it something like below but need something to work:

datasource3 = datasource1 + datasource2
rpMyRepeater.Datasource = datasource3

1 Like

It is quite difficult to understand. You should not use it so much. It is difficult to know which it you mean.

Finally I understand. Now I will look over everything again.

1 Like

I think this is what you need to do, or something like it.

First, you are using IEnumerable. It (IEnumerable) is non-generic, right? That might not be a problem here but it is better to use generic classes such as List<>.

Then the important part (I think) of what saludalabshome is saying is that you can create an instance of List<> and then just add each of the sets of items to that, using the Add method. Actually, products is initialized with one document then more are added. Then bind to the combined list, products or whatever.