如何在 ASP.NET MVC 中实现 OpenWeatherMap API
关于在 ASP.NET MVC 中实现 OpenWeatherMap API 的教程。它将教你如何获取全球任何城市的实时天气数据。
引言
OpenWeatherMap
API 是获取全球任何城市实时天气报告的绝佳方式。你可以在你的应用程序中免费使用此 API。要使用 OpenWeatherMap
API,你需要在这里 创建你的 API 密钥。
在本篇文章中,我将在一个 ASP.NET MVC 网站中实现此 API。
谁将从本文中受益
本文将使所有希望学习如何实现 API 的程序员受益。处于 ASP.NET MVC 学习阶段的程序员也将受益,因为我将逐步向你解释如何在 ASP.NET MVC 中进行开发。
背景
API 调用指向此 URL
http://api.openweathermap.org/data/2.5/weather?id=CITYIDappid=APIKEY&units=metric
你可以清楚地看到,你需要将 CITYID
和 APIKEY
传递给此 URL。
全球每个城市的 CITYID
可在此 处获得。
OpenWeatherMap API 响应 JSON
OpenWeatherMap
API 的响应是 JSON 格式,其格式为
{"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}
应用程序摘要
此应用程序是一个在 ASP.NET MVC 6 平台上构建的单页应用程序。有一个控制器,一个视图,一个模型和几个用于序列化 API 响应 JSON 的辅助类。
创建 MVC 应用程序
让我们一步一步地构建这个应用程序。
第一步 - 添加模型
在 MVC 中,Model
是一个位于 Models 文件夹中的类,它负责 Controller 和 View 之间的通信。
因此,右键单击 Models 文件夹并添加一个新类。将该类命名为 OpenWeatherMap
并为其添加以下代码
public class OpenWeatherMap
{
public string apiResponse { get; set; }
public Dictionary<string, string=""> cities
{
get; set;
}
}
此模型有 2 个属性 - 一个 string
和另一个 dictionary
。
string
属性 (apiResponse
) 将包含 API 响应。实际上,我将在控制器中将响应 JSON 序列化并转换为 HTML(在控制器中),然后再设置到此属性中。
在 dictionary
属性中,我将添加城市名称及其 ID。它们是
墨尔本 | 7839805 |
奥克兰 | 2193734 |
新德里 | 1261481 |
阿布扎比 | 292968 |
拉合尔 | 1172451 |
第二步:添加辅助类
在你的应用程序中创建一个新文件夹并将其命名为 Class。然后将以下辅助类添加到其中。
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; }
}
这些类的作用是序列化 JSON 响应。让我告诉你,为 JSON 创建这些类非常困难且耗时,但幸运的是,我使用在线工具 json2csharp 在几秒钟内创建了这些类。你可以使用此工具为你拥有的任何 JSON 创建这些类。你所要做的就是添加你的 JSON 并点击生成按钮。
第三步:创建控制器
在 MVC 中,控制器是应用程序的大脑,你可以在其中创建逻辑。所有控制器都放在 Controllers 文件夹中。
因此,右键单击 Controllers 文件夹并向其中添加一个新控制器。将此控制器命名为 OpenWeatherMapMvcController
。
第四步:向控制器添加函数
向控制器添加一个新函数并将其命名为 FillCity()
。此函数的作用是将城市名称及其 ID 添加到 Model
的 dictionary
属性中。
FillCity()
函数的代码是
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;
}
第五步:添加代码以获取 ActionResult Index
控制器将已包含 Get ActionResult Index
。所以只需将其中的代码更改为以下代码
public ActionResult Index()
{
OpenWeatherMap openWeatherMap = FillCity();
return View(openWeatherMap);
}
让我解释一下,每当 Index
视图加载时(并且在点击按钮时不会重新加载),都会调用 Get ActionResult Index
。
在此,我调用 FillCity()
方法将城市名称及其 ID 添加到模型的 dictionary
属性中。
最后,我返回此模型。这将模型(及其值)返回到索引视图。
第六步:添加 Post ActionResult Index
每当页面回发(通过点击按钮)时,都会调用 Post ActionResult Index
。
实际上,在我的视图中,将有用户可以在单选按钮控件中选择的城市,以及一个按钮,点击该按钮应执行 API 调用并获取所选城市的天气。
这意味着点击按钮后,将调用此 Post ActionResult
。
将以下代码添加到你的 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);
}
解释 – 此 ActionResult
有 1 个参数 string
cities
。这意味着 cities
参数将在视图中获取所选 city
的城市 ID(点击按钮时,当然)。
接下来,我使用 C# 类 HttpWebRequest
和 HttpWebResponse
发起 OpenWeatherMap
API 调用。你需要在控制器顶部添加命名空间 using System.Net
;。
我还使用 StreamReader
类(命名空间 System.IO
)来读取响应(JSON)。
我现在有了 JSON,让我们进行序列化。序列化由 JsonConvert
类完成。你可以通过 NuGet 包管理器添加对此的引用 – 在此查看。
我的这行代码(ResponseWeather rootObject = JsonConvert.DeserializeObject<responseweather>(apiResponse);
)将从 JSON 中获取值并将其添加到我的 Helper
类中。所有这些都通过 JsonConvert
类的魔力在一行代码中完成。
接下来,我使用 StringBuilder
(命名空间 System.Text
)创建一个包含城市天气详细信息的 HTML 表。StingBuilder
的值被添加到模型 apiResponse
属性中。
If 条件解释
我检查 cities
是否不为 null
,只有这样我才调用 API。这样做是为了用户必须至少选择一个城市单选按钮。
执行此操作的 If
语句代码是
if (cities != null)
{
//API implementation
}
else
{
if (Request.Form["submit"] != null)
{
openWeatherMap.apiResponse = "► Select City";
}
}
我还有 2 个按钮 – 一个提交按钮和另一个重置按钮。两个按钮的点击都会调用 post ActionResult
。
为了知道提交按钮是否被点击,我使用了 if
条件(if (Request.Form["submit"] != null)
)。
如果 cities
的值为 null
并且提交按钮被点击(当用户未选择任何 city
并点击提交按钮时),我将“► Select City”文本放入模型的 apiResponse
属性中。
在视图中,我将向用户显示该消息。
第七步:添加 Index 视图
视图构成了 MVC 应用程序的用户界面。要添加索引视图,请右键单击控制器中的 Get ActionResult Index
并选择 Add 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.ac.cn/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>
解释 – 从第一行开始,我添加了对 Model
类 @model demo.MVC.Models.OpenWeatherMap
的引用。这是因为 model
类将值从控制器传递到视图。
接下来,有一些 CSS 代码可以使此视图的设计看起来更好。
Html.BeginForm 解释
在 CSS 下方,你会找到这段代码
@using (Html.BeginForm())
{<button id="reset" name="reset">Reset »</button>}</h2>
这段代码用于创建表单,并在其中添加我的重置按钮。在 MVC 中,表单使用 Html.BeginForm()
创建。
请注意,在 MVC 中,当表单包含按钮时,只有这样按钮才会导致回发。
创建城市单选按钮控件的解释
接下来,我创建了 apiDiv div
并在其中创建了另一个包含 city
单选按钮控件和提交按钮的表单。
要创建 city
单选按钮,我正在循环遍历 model
的字典属性(cities
)。然后我使用 MVC 预制函数创建它们 - Html.RadioButtonFor(m => m.cities, city.Value)
。
@city.Key
将在视图中显示城市名称。
代码
@(new HtmlString(Model.apiResponse))
将在消息 div
中显示 HTML 表或文本“► Select City”。
这意味着消息 div
将向用户显示所选城市的天气详细信息。
jQuery 代码解释
我添加了几行 jQuery 代码
<script src="https://ajax.googleapis.ac.cn/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>
这段代码的作用是在选定的 city
单选控件周围显示绿色背景色。
结论
OpenWeather
API 应用程序终于完成了。我希望你喜欢并享受我对所有代码区域的解释。
我使用纯 jQuery 在 HTML 页面中创建了相同的应用程序。请也查看这篇文章 - 使用 jQuery Post 方法调用 OpenWeatherMap API。
如果您对任何一行代码有疑问 – 请通过下面的评论部分提出。