Requesting "foreign" Api within ASP.NET Web Api - c#

I write a Web Api 2 Project and within one Method (POSTing a new Location), I want to retrieve some Information, the user not provides (Country, City, region).
I found a solution in the Google Maps API:
http://maps.googleapis.com/maps/api/geocode/json?latlng=38.91845,1.44315&sensor=true
This meens, I must only provide the lat and lon coords within this URL.
How can I send this request and process the result within my own API Method?
My method is till now:
public string PostNewLocation(string mName, decimal mLat, decimal mLot)
{
// Here should be the calling and resolving of the Google API
// string mCity = ...
// string mCountry = ...
// Adding new location to database follows here and works fine...
}

public string PostNewLocation(string mName, decimal mLat, decimal mLot)
{
//do a get request to http://maps.googleapis.com/maps/api/geocode/json?latlng=38.91845,1.44315&sensor=true
//deserialize the json response to your own object and do stuff with it
var response = googleAPIService.Get(mLat, mLot);
//do something with the response
}

Related

Insert in DB a JSON object from a URL

I'm new to the REST API world. I explain my need: at a specific URL I have a raw JSON text, I would like this text to be acquired by my application and inserted later in the DB as a model I created previously through EF. C# NET-CORE 2.2.
if I wasn't clear enough, don't hesitate to ask me for more details.
Thanks in advance!
Edit:
I'm sorry if it' was unclear, I will provide more detail:
Actually, i have a JSON string downloaded from an url. I did it with the following code:
var client = new WebClient();
var jsonFull = client.DownloadString(string.Format("https://url"));
It's working fine. Now, I need to take from this string only a little part of the JSON, so i did:
using var jsonDoc = JsonDocument.Parse(jsonFull);
var jsonParsed = jsonDoc.RootElement;
var myCV = jsonParsed.GetProperty("cv");
CVE is an object of this JSON, and I succesfully take it.
Inside this object, there is another one called CV_data, so I extract this:
var myCVLE = myCV.GetProperty("CV_data_meta");
The result is a var with inside
ValueKind = Object : "{
"ID": "CV-2019",
"ASS": "cv#ms.org"
}"
Now, I have a class like that
public class CV_data_meta
{
[JsonPropertyName ("ID")]
public string ID { get; set; }
[JsonPropertyName("ASS")]
public string ASS { get; set; }
}
The question is: how i can put the value in the var myCVLE in the class CV_data_meta?
I tried with
var myCVClass = JsonSerializer.Deserialize<CV_data_meta>(myCVLE);
But I get an error.
Note: I can't deserialize all the string JSON into an object, because there are a lot of information that I don't need.
Thanks in advance all!
As I understand from your question, it follows:
You first need to create the JSON object mapping (class) that the API URL will return.
Then consume the API url like this:
var client = new WebClient();
var reply =
client.DownloadString(
string.Format("https://www.yourapi.com/yourpath?yourkey={0}", yourkey));
receive and map object with mapped class
var yourvar = JsonConvert.DeserializeObject<yourclass>(reply);
Now you have the API return mapped to a class in your application, you can do whatever you want with it, including saving to a database.

Authentication in Dialogflow API V2 using C#

I have .NET Web API Project for the fulfillment API as our webhook in my Dialogflow agent. In our Post method of the controller, after getting the request from Dialogflow, I implement the explicit authentication as shown in the Google Cloud documentation for C#.
//jsonFileName is the name of the serviceAccountKey json generated from the Google Cloud Platform that's encrypted internally
public bool AuthExplicit(string projectId, string jsonFileName)
{
try
{
string JsonCredential = DecryptHelper.Decrypt(jsonFileName);
var credential = GoogleCredential.FromJson(JsonCredential).CreateScoped(LanguageServiceClient.DefaultScopes);
var channel = new Grpc.Core.Channel(
LanguageServiceClient.DefaultEndpoint.ToString(),
credential.ToChannelCredentials());
var client = LanguageServiceClient.Create(channel);
AnalyzeSentiment(client);
if (client != null)
{
return true;
}
else
{
return false;
}
}
internal void AnalyzeSentiment(LanguageServiceClient client)
{
var response = client.AnalyzeSentiment(new Document()
{
Content = "Authenticated.",
Type = Document.Types.Type.PlainText
});
var sentiment = response.DocumentSentiment;
string score = $"Score: {sentiment.Score}";
string magnitude = $"Magnitude: {sentiment.Magnitude}";
}
The difference with the code is that after getting the client, when we call the AnalyzeSentiment() method, it doesn't do anything, and the projectId parameter is never used to authenticate. GCP docs are quite confusing, since when there is an AuthExplicit() that uses projectId, it uses it as a parameter for the buckets and only prints this on the console.
It works fine, until we test the service account key with a different agent. Expected output is that authentication would fail, but somehow it still passes.
Once the Post method goes through the AuthExplicit() method, it would only return a boolean. Is this the right way to authenticate? Or is there something else needed to invoke?
The difference with the code is that after getting the client, when we call the AnalyzeSentiment() method, it doesn't do anything,
Does client.AnalyzeSentiment() return an empty response? Does the call hang forever?
It works fine, until we test the service account key with a different agent.
What is a different agent? A different User-Agent header?
Once the Post method goes through the AuthExplicit() method, it would only return a boolean. Is this the right way to authenticate? Or is there something else needed to invoke?
What does 'the Post method' refer to? What is the 'it' that would only return a boolean?

Getting country name from visitors in a website

I would like to know a way that I can get the Country Name of all the visitors who are visiting a website (my website). I have seen maxmind.com and it's so complicated to set it up as I am a beginner. Hope will get some good answers. I have already tried lots of things in this website and could not come up with a solution.
GeoServiceReference.GeocodeServiceClient client = new GeoServiceReference.GeocodeServiceClient();
var countries = new List<string>();
for (double lat = 0; lat < 360; lat+=0.1)
for(double lon = 0; lon < 360; lon+=0.1)
{
var result = client.ReverseGeocode(new GeoServiceReference.ReverseGeocodeRequest
{
Location = new GeoServiceReference.Location
{
Latitude = lat,
Longitude = lon
}
});
if (!countries.Contains(result.Results.First().Address.CountryRegion))
{
Console.WriteLine(result.Results.First().Address.CountryRegion);
countries.Add(result.Results.First().Address.CountryRegion);
}
}
As an alternative to Maxmind, freegeoip.net offers a free REST service that is based on Maxmind's legacy databases. It is very easy to use - you just need to issue an HTTP GET request to a URL in the following format:
http://freegeoip.net/json/{ip_or_hostname}
You could use a library like RestSharp - again, very easy to use - to issue this request and parse the result.
Here's a simple example that should point you in the right direction:
public Geolocation GetGeolocationData(string ipAddress)
{
var client = new RestClient("http://freegeoip.net/");
var request = new RestRequest("json/{ip}");
request.AddUrlSegment("ip", ipAddress);
var response = client.Execute<Geolocation>(request);
return response.Data;
}
Here, I assume that Geolocation is a class with some properties that match the names of those in the JSON result returned by the REST service, e.g.:
public class Geolocation
{
public string CountryName { get; set; }
...
}
The most handy tool is API or if you want to host the data and perform lookup at your server then you can consider to get a copy of database.
http://www.ipinfodb.com

Bing Maps Api: Deserialise Json result

I am using the Bing Maps Api to calculate the route between two points.
I use the Rest Services in combination with the RestSharp library.
Problem is that I don't know how I can access the Route results.
The results are of type Resource. Route derives of Resource.
The Resource class is decorated with the KnownType attribute.
FYI I use the JSON datacontracts from msdn
Can someone help me?
Here is my code to calculate the route:
public static double CalculateDistanceKm(string street, string postalCode, string city, string country)
{
var client = new RestClient(BingMapsApiUrl);
var request = new RestRequest("Routes/Driving", Method.GET);
request.AddParameter("wp.0", Address);
request.AddParameter("wp.1", String.Format("{0},{1} {2},{3}", street, postalCode, city, country));
request.AddParameter("ul", "50.7541313,4.2486601");
request.AddParameter("key", BingMapsApiKey);
var response = client.Execute(request);
if (response.ResponseStatus == ResponseStatus.Completed)
{
var result = JsonConvert.DeserializeObject<Response>(response.Content);
if (result != null && result.StatusCode == 200 & result.ResourceSets.Any() && result.ResourceSets[0].Resources.Any())
{
//How to get to the Route instead of just Resource...
var test = result.ResourceSets.First().Resources.First();
}
}
return 0;
}
I switched the api from Bing to Google Maps.
The api is a lot easier to use and it gave me the right results.
With Bing I had a 9/10 change to get a "Not_found" error, tested with the SAME address!
So sometimes it works (1/10 chance).
With Google I get a correct result on each try...
Don't make the same mistake as I did, if you want to lookup address in another language than english then use Google Maps API.

Caching JSON Data in C# MVC3

I am developing an application that presents a company's twitter feed on a Facebook application. This is a large company with lots of traffic to the FB App so I need to cache the Twitter data I receive (from the twitter API) so that I can avoid their rate limits.
In my code, I use LinqToTwitter to call the API and then I construct a string of JSON with the results. That string is then fed to the user's browser via AJAX.
The rate limit for Twitter API calls is 150 per hour, so I figure I will just place the string of JSON data I construct in a cache object and only refresh it once per minute leaving me well below the Twitter rate limit.
The problem is that I am fairly new to MVC for .NET and can't seem to use System.Web.Caching like I could do in a webforms application.
In older webforms apps I simply did something like:
private string KeyTwitterData;
...
string data = null;
if (Cache[KeyTwitterData] == null)
{
var url = LinqToTwitter.Request.Url;
data = ServiceMethods.GetConversation(url);
Cache.Insert(KeyTwitterData, data);
}
else
{
data = (string)Cache[KeyTwitterData];
}
Can someone please tell me how to accomplish this in MVC3?
Thanks!
Matt
In ASP.NET MVC 3 if you want to cache the result of a controller action you could decorate it with the [OutputCache] attribute:
[OutputCache(Duration = 3600, Location = OutputCacheLocation.Server, VaryByParam = "none")]
public ActionResult Foo()
{
var model = SomeExpensiveOperationToFetchData();
return View(model);
}
If you don't want to cache the entire output of a controller action you could use the MemoryCache class:
var data = MemoryCache.Default[KeyTwitterData];
if (data == null)
{
data = SomeExpensiveOperationToFetchData();
MemoryCache.Default.Add(KeyTwitterData, data, DateTime.Now.AddMinutes(5));
}
// use the data variable here
Use HttpContext.Cache in your controller
string data = null;
if (HttpContext.Cache[KeyTwitterData] == null)
{
var url = LinqToTwitter.Request.Url;
data = ServiceMethods.GetConversation(url);
HttpContext.Cache.Insert(KeyTwitterData, data);
}
else
{
data = (string)HttpContext.Cache[KeyTwitterData];
}

Categories

Resources