这个程序最大的难点就是找一个合适的天气预报接口,以前没有做过类似的程序,导致70%时间浪费在找接口以及调试接口上,不过也算我运气好,找到了一个免费接口,接口的技术兄弟人也超棒,大大的赞。
在这里分享给大家 https://www.tianqiapi.com/?action=doc(刚两天界面就改版了,差点以为我访问错了)。
作为一个免费的接口,数据详细到这种程度,大大的良心,应付一个大学生的期末作业,简直大材小用。
找接口后,立马开始写代码,由于女学生要的紧,哦,不催得紧,所以代码一切从简,只保留核心功能,锦上添花的东西一律不要,首先搞定http请求类。
public class HttpHelper { /// <summary> /// 发送请求的方法 /// </summary> /// <param name="Url">地址</param> /// <param name="postDataStr">数据</param> /// <returns></returns> private string HttpPost(string Url, string postDataStr) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = Encoding.UTF8.GetByteCount(postDataStr); Stream myRequestStream = request.GetRequestStream(); StreamWriter myStreamWriter = new StreamWriter(myRequestStream, Encoding.GetEncoding("gb2312")); myStreamWriter.Write(postDataStr); myStreamWriter.Close(); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Stream myResponseStream = response.GetResponseStream(); StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")); string retString = myStreamReader.ReadToEnd(); myStreamReader.Close(); myResponseStream.Close(); return retString; } public string HttpGet(string Url, string postDataStr) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr); request.Method = "GET"; request.ContentType = "text/html;charset=UTF-8"; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Stream myResponseStream = response.GetResponseStream(); StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")); string retString = myStreamReader.ReadToEnd(); myStreamReader.Close(); myResponseStream.Close(); return retString; } }
http请求搞定,接下来获取所有的城市,主要为了效验用户的输入,不可能你输入什么我都去查天气,就算你是女学生也不行,大家伙说对不?
https://cdn.huyahaha.com/tianqiapi/city.json 全国所有城市接口。
https://www.tianqiapi.com/api/ 天气接口,下为参数列表。
参数 | 名称 | 备注 |
---|---|---|
version | 版本标识 必填字段 | 目前可用值: v1 |
callback | jsonp参数 | 如: jQuery.Callbacks |
以下参数三选一 | ||
cityid | 城市编号 | 如: 101120201 |
city | 城市名称 | 如: 海淀,青岛,大连 (不要带市和区) |
ip | IP地址 | 此IP地区的天气 |
大家可以自行查看下接口的返回值,简直详细到丧心病狂。
添加几个model类用来序列化json
public class City { public string cityZh { get; set; } public string id { get; set; } } public class Data { public string day { get; set; } public string date { get; set; } public string week { get; set; } public string wea { get; set; } public string air { get; set; } public string air_level { get; set; } public string air_tips { get; set; } public string tem { get; set; } public string tem1 { get; set; } public string tem2 { get; set; } public string win_speed { get; set; } } public class Weather { public string cityid { get; set; } public string update_time { get; set; } public string city { get; set; } public List<Data> data { get; set; } }
准备工作完成,开始调用接口,由于只有两个接口,接口文档又很清楚,对方技术兄弟也很给力。没费什么劲接口调试成功,于是写了下面两个方法。
public class Weather { HttpHelper http = new HttpHelper(); List<City> citys = new List<City>(); public model.Weather GetWeather(string name) { if (!citys.Any(a => a.cityZh == name.Trim())) { throw new KeyNotFoundException("未找到相关城市,请您检查城市名"); } var data = http.HttpGet($"https://www.tianqiapi.com/api/?version=v1&city={name}", "").TrimStart('('); return JsonConvert.DeserializeObject<model.Weather>(data); } public void GetCity() { var data = http.HttpGet(" https://cdn.huyahaha.com/tianqiapi/city.json", ""); citys = JsonConvert.DeserializeObject<List<City>>(data); } }
然后就是界面设计,为了省时间没有使用更强大的wpf,而使用更简单快捷的winform5分钟界面撸完。
为了方便连控件名都没有改(如果在公司这么做,codereview一定会被骂)label3显示当前城市,6个groupbox为6天的天气,一个查询一个退出,界面搞定。
然后编写按钮事件,绑定数据,没什么难度。
public partial class Form1 : Form { public Form1() { InitializeComponent(); AllCity(); } Weather weather = new Weather(); private void Form1_Load(object sender, EventArgs e) { BindData(city_name.Text.Trim()); } private void AllCity() { weather.GetCity(); } private void label1_Click(object sender, EventArgs e) { } private void select_Click(object sender, EventArgs e) { BindData(city_name.Text.Trim()); } private void BindData(string city) { model.Weather w = null; try { w = weather.GetWeather(city); } catch (KeyNotFoundException ex) { MessageBox.Show(ex.Message); } catch (Exception) { MessageBox.Show("查询失败请重试"); } if (w != null) { SetView(w); } } private void SetCurrentCity(string city) { label3.Text = city; } private void SetView(model.Weather model) { SetCurrentCity(model.city); SetLable(model.data); SetGroupBox(model.data); } private void SetLable(List<Data> model) { var d = model[0]; label2.Text = WeaderString(model[0]); label4.Text = WeaderString(model[1]); ; label5.Text = WeaderString(model[2]); ; label6.Text = WeaderString(model[3]); ; label7.Text = WeaderString(model[4]); ; label8.Text = WeaderString(model[5]); ; } private string WeaderString(Data d) { string txt = $"日期:{d.date} 天气:{d.wea} 当前温度:{d.tem} 温度:{d.tem1} - {d.tem2} 空气质量:{d.air_level} 空气指数:{d.air} 风力:{d.win_speed}"; return txt; } private void SetGroupBox(List<Data> model) { groupBox1.Text = model[0].week; groupBox2.Text = model[1].week; groupBox3.Text = model[2].week; groupBox4.Text = model[3].week; groupBox5.Text = model[4].week; groupBox6.Text = model[5].week; } private void button1_Click(object sender, EventArgs e) { Application.Exit(); } }
搞定了,来看下运行效果,界面虽然简单可是功能完美实现。