Page 16 - MSDN Magazine, September 2018
P. 16
method is empty, so nothing happens. In the next section, I’ll add the code that will call the Web services and retrieve the current weather conditions.
Storing the Data Returned
from the Web Service
Next, I need some local variables in my page to store the data returned from theWebservicecalls.TheRazorpages will bind to these variables so the data can be displayed. These variables get added to the @functions block in the page, like so:
Models.CurrentConditions currentcondition; Models.Alert alerts;
Models.ZipLookup ziplookup;
String imgurl = "";
Adding the ZIP
Code Web Service
Once the user clicks the Get Weather
button, the ZIP code in the input box
must be validated. The first public Web
service is from zippopotam.us. When the http://api.zippopotam.us/ US/<zip> API URL is called, it returns information about the specified ZIP code. The information needed from this Web ser- vice is the name of the city and state. This data will be displayed to the user in the forecast, and the state abbreviation will be used in subsequent Web service calls. The Web service code should look familiar because it uses the familiar HttpClient class.
Calling the ZIP Lookup Web Service The script in Figure 1 downloads the ZIP code info from the API and places it into a local variable called ziplookup. I can use this variable in my Razor code to display the city name. The API will return an exception if the ZIP is invalid. If that happens, an error message is displayed.
Deserializing the ZIP Lookup Data In the previous code snip- pet, I’m retrieving data from the Web service and deserializing it into a Models.ZipLookup class. This is a class I’ve created to match the schema of the JSON data being returned:
public class ZipLookup {
public Place[] places { get; set; }
}
public class Place {
public String city { get; set; }
public String stateabbr { get; set; } }
Much more data is returned, but I’ve only created properties and classes for the data I want to use. The current implementation has issues with dealing with spaces in the JSON field names. As a tem- porary workaround, I’m using String.Replace to remove the spaces.
Displaying the City and State Now that the data has been down- loadedanddeserialized,IcandisplayitintheWebpage.Thefollowing code block displays the city and state abbreviation in the page:
<h1>
@ziplookup.places[0].city, @ziplookup.places[0].stateabbr<br />
</h1>
Figure 6 The Finished Application
Adding the Weather Conditions Web Service
The next Web service will retrieve the current conditions for the ZIP code from the openweathermap.org Web service. You’ll need to create an account in order to receive a special key that’s used when calling the Web service.
Calling the Current Conditions Web Service The call to get the current conditions works much like the previous Web service call. The exception here is the apikey parameter in the call. The openweathermap.org service requires a key to authenticate the caller:
currentcondition = await Http.GetJsonAsync<Models.CurrentConditions>( $"http://api.openweathermap.org/data/2.5/ weather?zip={zip},us&appid=<apikey>");
imgurl = $"http://openweathermap.org/img/w/{currentcondition.weather[0].icon}.png";
The result of the current conditions call is stored in a local vari- able called currentcondition. That result also passes the name of an icon to be displayed that corresponds to the current conditions. The name of the image is encoded into the imgurl variable so it can be displayed in the Web page.
Deserializing Current Conditions Data Once again, the raw JSON data needs to be deserialized into a class so it can be used, as shown in Figure 2. The class definition looks a little odd, but it’s designed to match the schema of the JSON data being returned from the Web service. There’s a lot more data being returned than what’s shown here. Only the properties that are needed have to be implemented.
Converting the Temperatures The temperatures returned from the Web service are in kelvins, so the values need to be converted to degrees Fahrenheit and rounded. The current temperature will be rounded to the nearest tenth of a degree. The high and low tem- peratures will be rounded to the nearest whole degree.
private decimal ConvertKtoF(decimal kelvin, int decimals) {
return Math.Round(kelvin * 9 / 5 - 459.67M, decimals); }
12 msdn magazine
C#