fetch pertocular data from url xml of amazon product Api - c#

I am new to asp.net and working on amazon product advertising API look up........ I want to fetch the price of the product from the API.They have generated me the URL which is generating the XML contains the details of the product.I only want to fetch the amount from "amount" node.I have tried for many days but could not do it.Can any one help me.Thank You.

REST way
Download file from (AmazonProductAdvtApiSampleCSharpQuery\Sample\src) from https://aws.amazon.com/code/Product-Advertising-API/2480 and copy SignedRequestHelper.cs
SignedRequestHelper helper = new SignedRequestHelper("XXXXXXXXXX", "XXXXXXXXXXXXXXXXXXX", "webservices.amazon.com");
IDictionary < string, string > dictValue = new Dictionary < string, String > ();
dictValue["Service"] = "AWSECommerceService";
dictValue["Version"] = "2011-08-01";
dictValue["Operation"] = "ItemLookup";
dictValue["ItemId"] = asinCode;
dictValue["IdType"] = "ASIN";
dictValue["AssociateTag"] = "xxxxxxxxx-xx";
dictValue["ResponseGroup"] = "ItemAttributes";
string url = helper.Sign(dictValue)
WebRequest request = WebRequest.Create(url);
string price;
using(WebResponse response = await request.GetResponseAsync()) {
if (response != null) {
using(XmlReader reader = XmlReader.Create(response.GetResponseStream())) {
// Now parse XML accordingly
reader.ReadToFollowing("ListPrice")
if (reader.ReadToDescendant("FormattedPrice")) {
price = reader.ReadElementContentAsString();

Related

Get longitude and latitude from API

I have searched on Google and here on Stack Overflow, but due to my limited expertise in C# and SSIS I have some troubles getting through.
My steps in this SSIS package is as follows:
I have a SQL task connected to a for loop which only specifies how many times I should iterate in Forloop container which is =1
Inside Forloop container have a dataflow task
In dataflow task, I use an OLEDB source to get addresses from a SQL table
I connect those OLEDB source to a Script task from which the following script "Should" return my XML answer from which I want to return Latitude and longitude. It does not return the answer that I want.
Example address is - Beihinger Strasse 160 DE-71726 BENNINGEN GERMANY
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
string url = "http://dev.virtualearth.net/REST/v1/Locations?addressLine={0}&output=xml&key={1}";
var Address = Row.Address;
var wGet = WebRequest.Create(String.Format(url, Address, Variables.APIkey));
wGet.Method = WebRequestMethods.Http.Get;
var response = wGet.GetResponse();
var status = ((HttpWebResponse)response).StatusDescription;
Console.WriteLine("Input: " + Address);
if (status == "OK")
{
StreamReader reader = new StreamReader(response.GetResponseStream());
string responseFromServer = reader.ReadToEnd();
reader.Close();
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(responseFromServer);
var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("Point", "http://schemas.microsoft.com/search/local/ws/rest/v1");
var latNode = xmlDoc.DocumentElement.SelectSingleNode("/ResourceSets/ResourceSet/Resources/Location/Point/Latitude", nsmgr);
var lngNode = xmlDoc.DocumentElement.SelectSingleNode("/ResourceSets/ResourceSet/Resources/Location/Point/Longitude", nsmgr);
if (latNode != null && lngNode != null)
{
var numberFormatInfo = new NumberFormatInfo { NumberDecimalSeparator = "." };
Row.Latitude = decimal.Parse(latNode.InnerText, numberFormatInfo);
Row.Longitude = decimal.Parse(lngNode.InnerText, numberFormatInfo);
Row.FullResponse = responseFromServer.ToString();
}
else
{
//Set to null
Row.Latitude_IsNull = true;
Row.Longitude_IsNull = true;
Row.FullResponse = responseFromServer.ToString();
}
}
else
{
//Set to null
Row.Latitude_IsNull = true;
Row.Longitude_IsNull = true;
Row.FullResponse_IsNull = true;
}
response.Close();
}
}
The response I get is:
<?xml version="1.0" encoding="utf-8"?><Response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/search/local/ws/rest/v1"><Copyright>Copyright © 2020 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.</Copyright><BrandLogoUri>http://dev.virtualearth.net/Branding/logo_powered_by.png</BrandLogoUri><StatusCode>200</StatusCode><StatusDescription>OK</StatusDescription><AuthenticationResultCode>ValidCredentials</AuthenticationResultCode><TraceId>b9a94b411dc246ea82d161dae5e7a0c3|DU00000D73|0.0.0.1|Ref A: ACDD23537F6649F6B2F66333BB6D6D01 Ref B: DB3EDGE0918 Ref C: 2020-02-12T11:25:05Z</TraceId><ResourceSets><ResourceSet><EstimatedTotal>0</EstimatedTotal><Resources /></ResourceSet></ResourceSets></Response>
I want a correct call as I get when using URL so I can get Longitude and Latitude- http://dev.virtualearth.net/REST/v1/Locations?addressLine=Beihinger%20Strasse%20160%20DE-71726%20BENNINGEN%20GERMANY&output=xml&key={APIkey}
Any help would be greatly appreciated to what I am missing?

How to read specific values from response

This is the page I'm using for documentation https://lichess.org/api#operation/player
I want to get player usernamename, rating, and title.
My code.
public class Player {
public string username;
public double rating;
public string title;
}
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://lichess.org/");
HttpResponseMessage response = client.GetAsync("player/top/200/bullet").Result;
Here I'm getting response, But I have no clue how to take only properties that I need and store it in a list of players.
After a discussion with you on this problem, it was found that the response that you are receiving is a HTML string, therefore you need to deal with this case differently. I was playing around with the HTML that you have posted in the comments and I was able to parse the string with HTML Agility Pack which can be found here. You can also download this pack from the Nuget Package Manager in Visual Studio.
I am giving you a very basic example of the parsing process that I tried out:
public class ProcessHtml()
{
List<Player> playersList = new List<Player>();
//Get your HTML loaded from a URL. Giving me SSL exceptions so took a different route
//var url = "https://lichess.org/player/top/200/bullet";
//var web = new HtmlWeb();
//var doc = web.Load(url);
//Get your HTML loaded as a file in my case
var doc = new HtmlDocument();
doc.Load("C:\\Users\\Rahul\\Downloads\\CkBsZtvf.html", Encoding.UTF8);
foreach (HtmlNode table in doc.DocumentNode.SelectNodes("//tbody"))
{
foreach (HtmlNode row in table.SelectNodes("tr"))
{
int i = 0;
Player player = new Player();
//Since there are 4 rounds per tr, hence get only what is required based on loop condition
foreach (HtmlNode cell in row.SelectNodes("th|td"))
{
if(i==1)
{
player.username = cell.InnerText;
}
if(i==2)
{
player.rating = Convert.ToDouble(cell.InnerText);
}
if(i==3)
{
player.title = cell.InnerText;
}
i++;
}
playersList.Add(player);
}
}
var finalplayerListCopy = playersList;
}
public class Player
{
public string username;
public double rating;
public string title;
}
After running this, your finalplayerListCopy has a count of 200 and an example data would look like:
Obviously, you would have to play with the data and tailor it as per your need. I hope this helps you out.
Cheers!
from what Ive read from the documentation
async Task<Player> getPlayerAsync(string path)
{
Player player= null;
HttpResponseMessage response = await client.GetAsync(path);
if (response.IsSuccessStatusCode)
{
player = await response.Content.ReadAsAsync<Player>();
}
return player;
}
getPlayerAsync("https://lichess.org/player/top/200/bullet");

How to use Adaptive Cards on Teams Messaging Extension?

I'm developing a Teams Message Extension and I'm using ThumbnailCard to display my results, however I wanted to use a custom adaptive card. Is that possible?
var resultCardList = GetAttachments(title);
var response = new ComposeExtensionResponse(new ComposeExtensionResult("list", "result"));
response.ComposeExtension.Attachments = resultCardList.ToList();
return response;
foreach (var contract in contractItems)
{
var lastModified = (DateTime)contract["Modified"];
var justificativa = contract["JustificativaContrato"];
var card = new ThumbnailCard
{
Title = $"{contract.Client_Title} - {lastModified.ToShortDateString()} {lastModified.ToLongTimeString()}",
Text = $"Justificativa: {justificativa}",
Tap = new CardAction { Type = "openUrl", Value = $"{Tenant}{ContractList.DefaultEditFormUrl}?ID={contract.Id}" },
Images = new List<CardImage> { new CardImage("http://lorempixel.com/640/480?rand=" + DateTime.Now.Ticks.ToString()) }
};
cardList.Add(card
.ToAttachment()
.ToComposeExtensionAttachment());
}
return cardList;
I've tried to use the below method to generate the Adaptive Card and just add it to the list:
private static Microsoft.Bot.Connector.Attachment CreateAdaptiveCardAttachment()
{
// combine path for cross platform support
string[] paths = { ".", "Cards", "welcomeCard.json" };
string fullPath = Path.Combine(paths);
var adaptiveCard = System.IO.File.ReadAllText(#"Cards\welcomeCard.json");
return new Microsoft.Bot.Connector.Attachment()
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = JsonConvert.DeserializeObject(adaptiveCard),
};
}
The messaging extension does not allow sending adaptive cards like that.
It requires using the "MessagingExtensionResult" of the framework and just the card sent in the response. The documentation is a bit lacking here.
When you get a call from the messaging extension its action is of type "composeExtension/query"
Create the general "result" list like this:
var invokeResponse = new MessagingExtensionResponse();
var results = new MessagingExtensionResult
{
AttachmentLayout = "list",
Type = "result",
Attachments = new List<MessagingExtensionAttachment>(),
};
For each result in the list you need to create a MessagingExtensionAttachment like this: (Note: Cards need to have a preview!)
results.Attachments.Add(new MessagingExtensionAttachment
{
ContentType = "application/vnd.microsoft.teams.card.adaptive",
Content = JsonConvert.DeserializeObject(cardData),
Preview = new Attachment
{
ContentType = "application/vnd.microsoft.card.thumbnail",
Content = new AttachmentContent
{
text = "Project: " + task.ProjectName,
title = task.Name,
},
}
});
Finally send the result as "InvokeResponse"
return new InvokeResponse
{
Body = invokeResponse,
Status = 200,
};
While "content" of the attachment is the full adaptive card.
You can find an example for the response in json here:
https://learn.microsoft.com/de-de/microsoftteams/platform/concepts/messaging-extensions/search-extensions#response-example
You can freely mix card types based on that, but i never got that working tho...as of now you need to limit to one specific card type as far as i know.
All above is if you're using
Microsoft.Bot.Builder.Teams
Microsoft.Bot.Connector.Teams
Microsoft.Bot.Schema.Teams
in the latest versions.

I used SvcUtil to create classes from WSDL. What do I deserialize into?

I used svcUtil.exe to create classes from https://gw.sam.gov/SAMWS/1.0/Entity?wsdl
but I cannot for the life of me find what to deserialize the result into? When I created my own classes the root is envelope but it isn't even in the new classes.
I can paste the classes but it is really long? Is there a general answer to this?
I will paste the classes upon request.
Thanks in advance...
The classes are over 10x too long to post.
Adding code for the pull:
static void Main(string[] args)
{
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var _url = "https://gw.sam.gov/SAMWS/1.0/Entity";
//Run date is a specific date if provided otherwise use yesterday
DateTime startDateTime = DateTime.Now.AddDays(-1).Date;
for (int hr = 0; hr < 24; hr++)
{
XMLclassRequest xmlSoap = new XMLclassRequest();
string soap = xmlSoap.BuildSOAPrequest(startDateTime.AddHours(hr));
//string soap2 = xmlSoap.BuildSOAPrequest2(startDateTime.AddHours(hr));
string response = null; //This is the original pull with FAR and DFAR Responses
//string response2 = null; //This is FAR and DFAR
using (MyWebClient client = new MyWebClient())
{
client.Headers.Add("Content-Type", "text/xml;charset=utf-8");
client.Headers.Add("SOAPAction", "\"http://tempuri.org/IMyService/MyOperation\"");
try
{
response = client.UploadString(_url, soap);
//response2 = client.UploadString(_url, soap2);
}
catch
{ } //This will skip the hour attempted and move to next. The error I have been receiving is no data which is differently formatted XML that causes the error
}
//File.WriteAllText(#"D:\temp\bigpull.xml", response);
MemoryStream stream = null;
if (response != null)
{
byte[] byteArray = Encoding.Unicode.GetBytes(response);
stream = new MemoryStream(byteArray);
}
getEntities results;
XmlSerializer serializer = new XmlSerializer(typeof(getEntities));
try
{ results = (getEntities)serializer.Deserialize(stream); }
catch
{ } //This will skip the hour attempted and move to next. The error I have been receiving is no data which is differently formatted XML that causes the error
stream.Close();
string str;
}
The response is coming back. I just can't get it into an object to use.
I couldn't get this loaded into an object but ended up loading it to an XDocument and parsed that:
var _url = "https://gw.sam.gov/SAMWS/1.0/Entity";
//Run date is a specific date if provided otherwise use yesterday
DateTime startDateTime = DateTime.Now.AddDays(-1).Date;
for (int hr = 0; hr < 24; hr++)
{
XMLclassRequest xmlSoap = new XMLclassRequest();
string soap = xmlSoap.BuildSOAPrequest(startDateTime.AddHours(hr));
//string soap2 = xmlSoap.BuildSOAPrequest2(startDateTime.AddHours(hr));
string response = null; //This is the original pull with FAR and DFAR Responses
//string response2 = null; //This is FAR and DFAR
using (MyWebClient client = new MyWebClient())
{
client.Headers.Add("Content-Type", "text/xml;charset=utf-8");
client.Headers.Add("SOAPAction", "\"http://tempuri.org/IMyService/MyOperation\"");
try
{
response = client.UploadString(_url, soap);
//response2 = client.UploadString(_url, soap2);
}
catch
{ } //This will skip the hour attempted and move to next. The error I have been receiving is no data which is differently formatted XML that causes the error
}
//File.WriteAllText(#"D:\temp\far20190604.xml", response);
XDocument xdoc = XDocument.Parse(response);
var entities = from e in xdoc.Descendants("entity") select e;
foreach (var e in entities)
{
string DUNS = e.Descendants("DUNS").FirstOrDefault().Value;
var provisions = from p in e.Descendants("provision") select p;
foreach (var p in provisions)
{
string ParentID = p.Descendants("id").FirstOrDefault().Value;
var answers = from a in p.Descendants("answer") select a;
foreach (var a in answers)
{
var section = a.Descendants("section").Count()>0? a.Descendants("section").FirstOrDefault().Value : "";
var answerText = a.Descendants("answerText").Count() > 0 ? a.Descendants("answerText").FirstOrDefault().Value : "";
Console.WriteLine(DUNS + " " + ParentID + " " + section + " " + answerText);
}
}
}

REST JSON, Server lmit of 50 records, get all records (updated with current example)

I'm using a REST API to get JSON. The owner has imposed a limit of 50 results. Can someone suggest any links / tutorials on how I can get all the records and then derserialisze them into list?
I'm using RestSharp & C#
Since posting this question yesterday I have tried to work through a solution which creates a new method which can be used accross all REST calls. What I have is this:
public T getAllRecords<T>(List<T> genericList, string RestCommand, string[,] parameters)
{
int pageCount = 50;
var client = new RestClient("https://******************************");
client.Authenticator = new HttpBasicAuthenticator("*******", "*******");
var request = new RestRequest(RestCommand, Method.GET);
// add the parameters
for (int i = 0; i < parameters.Length / 2; i++)
{
request.AddParameter(parameters[i, 0], parameters[i, 1]);
}
var response = client.Execute(request);
var content = response.Content;
if (typeof(T) == typeof(Rootobject))
{
List<Rootobject> tempObject = new List<Rootobject>();
tempObject.Cast<Rootobject>();
Rootobject myRel = JsonConvert.DeserializeObject<Rootobject>(content);
tempObject.Add(myRel);
// create logic for looping through remaining records
int totalRecords = myRel.meta.pageInfo.totalResults;
do
{
request.AddParameter("startAt", pageCount);
response = client.Execute(request);
content = response.Content;
Rootobject myRel1 = JsonConvert.DeserializeObject<Rootobject>(content);
tempObject.Add(myRel1);
pageCount += 50;
} while (pageCount <= totalRecords);
List<Item.Datum> totalList = new List<Item.Datum>();
foreach (Rootobject rootItem in tempObject)
{
foreach (Item.Datum item in rootItem.data)
{
totalList.Add(item);
}
}
return (T)Convert.ChangeType(totalList, typeof(Item.Datum));
}
return default(T);
}
I call it like this:
var allItems = getAllRecords(new List<Rootobject>(), "abstractitems", new string[,] { { "project", "001" }, { "itemType", "151" }, { "maxResults", "50" } });
I was expecting it to retun a list of objects of type Item.Datum, however it errors with the error:
System.InvalidCastException: 'Object must implement IConvertible.'
I've just about reached the limit of my current understanding, appreciate any pointers as to how to get this over the finish line.
Thanks.
As this explains Jama SaaS APIs allow a maximum of 50 records to be returned, you will have to make multiple calls if you want more than those 50 records. This can be done with a simple for loop.

Categories

Resources