Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How to Implement OpenWeatherMap API in ASP.NET MVC

0.00/5 (No votes)
19 Oct 2018 1  
Tutorial on implementing OpenWeatherMap API in ASP.NET MVC. It will teach how to get real time weather data of any city of the world.

Introduction

OpenWeatherMap API is a great way to get the real time weather reports of any city of the world. You can use this API free of charge in your application. In order to use OpenWeatherMap API, you need to create your API key from here.

Here in this article, I will implement this API in an ASP.NET MVC website.

Who will Benefit from this Article

This article will benefit all programmers who wish to learn how to implement an API. Programmers who are in the learning stages of ASP.NET MVC will also be benefited as I will explain to you in steps about working in ASP.NET MVC.

Background

The API calls are made to this URL:

http://api.openweathermap.org/data/2.5/weather?id=CITYIDappid=APIKEY&units=metric

You can clearly see that you need to pass the CITYID and APIKEY to this URL.

The CITYID of every city of the world is available from here.

OpenWeatherMap API Response JSON

The OpenWeatherMap API response is in JSON whose format is:

{"coord":{"lon":139,"lat":35},
"sys":{"country":"JP","sunrise":1369769524,"sunset":1369821049},
"weather":[{"id":804,"main":"clouds",
"description":"overcast clouds","icon":"04n"}],
"main":{"temp":289.5,"humidity":89,
"pressure":1013,"temp_min":287.04,"temp_max":292.04},
"wind":{"speed":7.31,"deg":187.002},
"rain":{"3h":0},
"clouds":{"all":92},
"dt":1369824698,
"id":1851632,
"name":"Shuzenji",
"cod":200}

The Application Summary

OpenWeatherMap API

This application is a single page built in ASP.NET MVC 6 platform. There is one Controller, one View, a model and few helper classes for Serializing API response JSON.

OpenWeatherMap API

Creating the MVC Application

Let us build this application in a step by step manner.

STEP 1 – Add Model

In MVC, the Model is a class that resides inside the Models folder and does the communication between Controller and View.

So, right click the Models folder and add a new class. Name that class OpenWeatherMap and add the below code to it:

public class OpenWeatherMap
{
    public string apiResponse { get; set; }

    public Dictionary<string, string=""> cities
    {
        get; set;
    }
}

This model has 2 properties – a string and another dictionary.

The string property (apiResponse) will contain the API response. Actually, I will serialize the response JSON and convert it to HTML (in the controller) before setting it in this property.

In the dictionary property, I will add the city name and their ids. These are:

Melbourne 7839805
Auckland 2193734
New Delhi 1261481
Abu Dhabi 292968
Lahore 1172451

STEP 2: Add Helper Classes

Create a new folder in your application and name it Class. Now add the below helper classes to it.

public class Coord
{
    public double lon { get; set; }
    public double lat { get; set; }
}

public class Weather
{
    public int id { get; set; }
    public string main { get; set; }
    public string description { get; set; }
    public string icon { get; set; }
}

public class Main
{
    public double temp { get; set; }
    public int pressure { get; set; }
    public int humidity { get; set; }
    public int temp_min { get; set; }
    public int temp_max { get; set; }
}

public class Wind
{
    public double speed { get; set; }
    public int deg { get; set; }
}

public class Clouds
{
    public int all { get; set; }
}

public class Sys
{
    public int type { get; set; }
    public int id { get; set; }
    public double message { get; set; }
    public string country { get; set; }
    public int sunrise { get; set; }
    public int sunset { get; set; }
}

public class ResponseWeather
{
    public Coord coord { get; set; }
    public List<Weather> weather { get; set; }
    public string @base { get; set; }
    public Main main { get; set; }
    public int visibility { get; set; }
    public Wind wind { get; set; }
    public Clouds clouds { get; set; }
    public int dt { get; set; }
    public Sys sys { get; set; }
    public int id { get; set; }
    public string name { get; set; }
    public int cod { get; set; }
}

The work of these classes is to serialize the JSON response. Let me tell you creating these classes for a JSON is very hard and lengthy, but fortunately, I create these classes within seconds using an online tool json2csharp. You can use this tool to create these classes for any JSON you have. All you have to do is to add your JSON and click the generate button.

STEP 3: Create a Controller

In MVC, controller is the brain of the application where you create your logic. All controllers are placed inside the Controllers folder.

So, right click the Controllers folder and add a new controller to it. Name this controller OpenWeatherMapMvcController.

STEP 4: Add a Function to the Controller

Add a new function to the controller and name it FillCity(). The work of this function is to add the city names and their ids to the dictionary property of the Model.

The code of FillCity() function is:

public OpenWeatherMap FillCity()
{
    OpenWeatherMap openWeatherMap = new OpenWeatherMap();
    openWeatherMap.cities = new Dictionary<string, string>();
    openWeatherMap.cities.Add("Melbourne", "7839805");
    openWeatherMap.cities.Add("Auckland", "2193734");
    openWeatherMap.cities.Add("New Delhi", "1261481");
    openWeatherMap.cities.Add("Abu Dhabi", "292968");
    openWeatherMap.cities.Add("Lahore", "1172451");
    return openWeatherMap;
} 

STEP 5: Add Code to Get ActionResult Index

The controller will already contain the Get ActionResult Index. So just change the code inside it to the one below:

public ActionResult Index()
{
    OpenWeatherMap openWeatherMap = FillCity();
    return View(openWeatherMap);
}

Let me explain that the Get ActionResult Index will be called whenever the Index view will load (and not reload when button is clicked).

In this, I am calling the FillCity() method to add city names and their ids to the dictionary property of the model.

Finally, I return this model. This returns the model (and its values) to the index view.

STEP 6: Add Post ActionResult Index

The Post ActionResult Index will be called whenever the page is postback (through the button click).

Actually in my View, I will have cities that a user can select in radio input control, and a button which when clicked should do the API call and fetch the selected city’s weather.

So this means on clicking the button, this Post ActionResult will be called.

Add the below code to your Controller.

[HttpPost]
public ActionResult Index(OpenWeatherMap openWeatherMap, string cities)
{
    openWeatherMap = FillCity();

    if (cities != null)
    {
        /*Calling API http://openweathermap.org/api */
        string apiKey = "Your API KEY";
        HttpWebRequest apiRequest =
        WebRequest.Create("http://api.openweathermap.org/data/2.5/weather?id=" +
        cities + "&appid=" + apiKey + "&units=metric") as HttpWebRequest;

        string apiResponse = "";
        using (HttpWebResponse response = apiRequest.GetResponse() as HttpWebResponse)
        {
            streamReader reader = new StreamReader(response.GetResponseStream());
            apiResponse = reader.ReadToEnd();
        }
        /*End*/

        /*http://json2csharp.com*/
        ResponseWeather rootObject = JsonConvert.DeserializeObject<ResponseWeather>(apiResponse);

        StringBuilder sb = new StringBuilder();
        sb.Append("<table><tr><th>Weather Description</th></tr>");
        sb.Append("<tr><td>City:</td><td>" +
        rootObject.name + "</td></tr>");
        sb.Append("<tr><td>Country:</td><td>" +
        rootObject.sys.country + "</td></tr>");
        sb.Append("<tr><td>Wind:</td><td>" +
        rootObject.wind.speed + " Km/h</td></tr>");
        sb.Append("<tr><td>Current Temperature:</td><td>" +
        rootObject.main.temp + " °C</td></tr>");
        sb.Append("<tr><td>Humidity:</td><td>" +
        rootObject.main.humidity + "</td></tr>");
        sb.Append("<tr><td>Weather:</td><td>" +
        rootObject.weather[0].description + "</td></tr>");
        sb.Append("</table>");
        openWeatherMap.apiResponse = sb.ToString();
    }
    else
    {
        if (Request.Form["submit"] != null)
        {
            openWeatherMap.apiResponse = "► Select City";
        }
    }
    return View(openWeatherMap);
}

Explanation – This ActionResult has 1 parameters string cities. That means the cities Parameter will get me the city Id of the selected city from the view (on button click, of course).

Next, I am making the OpenWeatherMap API call using C# classes, HttpWebRequest & HttpWebResponse. You need to add the namespace using System.Net; to your controller on the top.

I am also using StreamReader class (namespace System.IO) to read the response (JSON).

I now have the JSON so let us serialize it. The serialization is done by the JsonConvert class. You can add the reference to this from NuGet Package Manager – see here.

My this line of code (ResponseWeather rootObject = JsonConvert.DeserializeObject<responseweather>(apiResponse);) I will fetch values from the JSON and add them to my Helper class. All this in 1 line of code and that purely due to the magic of JsonConvert class.

Next, I am creating an HTML Table that contains the city weather details using StringBuilder (namespace System.Text). The StingBuilder value is added to model apiResponse property.

Explanation of the if Condition

I check, if cities is not null, only then I call the API. This is done so that user is bound to select at least one city radio input.

The If statement code that does this work is:

if (cities != null)
{
    //API implementation
}
else
{
    if (Request.Form["submit"] != null)
    {
        openWeatherMap.apiResponse = "► Select City";
    }
}

I also have 2 buttons – one submit button and another reset button. Click of both buttons will call the post ActionResult.

To know if the submit button is clicked, I used the if condition (if (Request.Form["submit"] != null)).

If cities value is null and button submit is clicked (when a user does not selects any city and clicks submit button), I put “"► Select City” text inside the apiResponse property of the modal.

In the view, I will show that message to the user.

STEP 7: Add Index View

A view forms the UI of MVC application. To add the index view, right click the Get ActionResult Index in the Controller and select Add View.

Add the following code to your View:

@model demo.MVC.Models.OpenWeatherMap
<style>
    #apiDiv {
        padding-left: 20px;
    }

        #apiDiv select, #apiDiv button {
            font-size: 25px;
        }

        #apiDiv h4 {
            margin: 10px 0;
        }

        #apiDiv #message table {
            width: 100%;
            border: double 1px #00ffff;
            background: #ff6a00;
        }

            #apiDiv #message table th {
                text-align: left;
                background: #4CAF50;
            }
</style>
<h1>Implement OpenWeatherMap API in ASP.NET MVC</h1>
@using (Html.BeginForm())
{<button id="reset" name="reset">Reset »</button>}
<div id="apiDiv">
    <h4>Select the City for Weather Report</h4>
    @using (Html.BeginForm())
    {
        foreach (var city in Model.cities)
        {
            <span>
                @Html.RadioButtonFor(m => m.cities, city.Value) @city.Key
            </span>
        }

        <button name="submit">Submit</button>
    }
    <div id="message">@(new HtmlString(Model.apiResponse))</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script>
    $(document).ready(function () {
        $("input[id='cities']").change(function () {
            $(this).parents("#apiDiv").find
            ("span").css("background", "none");
            $(this).parent().css("background", "#4CAF50");
        });
    });
</script>

Explanation – Starting with the first line, I added the reference to the Model class @model demo.MVC.Models.OpenWeatherMap. This is because the model class will transfer values from the controller to the view.

Next, there are some CSS codes to make the design of this view look good.

Explanation of Html.BeginForm

Below the CSS, you will find this code:

@using (Html.BeginForm())
{<button id="reset" name="reset">Reset »</button>}</h2>

This code is for creating a form and inside it, adding my reset button. In MVC, form is created with Html.BeginForm().

Note that in MVC when the form contains a button, only then the button will causes the postback.

Explanation of the Creation of City Radio Input Controls:

Next, I create the apiDiv div and inside it, I created another form that contains the city radio input controls and a submit button.

To create the city radio button, I am looping through the dictionary property of the model (cities). Then I am creating them using an MVC premade function - Html.RadioButtonFor(m => m.cities, city.Value).

@city.Key will show the city names on the view.

The code:

@(new HtmlString(Model.apiResponse))

will show the HTML table or text “► Select City” inside the message div.

That means the message div will show the weather details of the selected city to the users.

Explanation of jQuery Code

I did add few lines of jQuery code:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script>
$(document).ready(function () {
    $("input[id='cities']").change(function () {
        $(this).parents("#apiDiv").find("span").css("background", "none");
        $(this).parent().css("background", "#4CAF50");
    });
});
</script> 

The work of this code is to show green background color around the selected city radio control.

Conclusion

The OpenWeather API application is finally completed. I hope you like and enjoy my explanation to all areas of the code.

I created the same application in HTML page using only jQuery. Do check this article too - OpenWeatherMap API using jQuery Post.

If you have any confusion regarding any line of code – please ask me through the comments section below.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here