中国气象局面向网络媒体、手机厂商、第三方气象服务机构等用户,经过 web 方式提供数据气象服务的官方载体。web
在一周前已经申请到appid,可是苦于没有C#版的key 的算法,一直验证不经过,通过几天查询资料,如今提供一份C#版的HMAC-SHA1的加密算法算法
比较简单,分项给你们,你们能够参考一下。json
string GetKey(string appid, string privateKey, string areaId, string date, string type) { //使用SHA1的HMAC HMAC hmac = HMACSHA1.Create(); var publicKey = "http://webapi.weather.com.cn/data/?areaid={0}&type={1}&date={2}&appid={3}"; var data = System.Text.Encoding.UTF8.GetBytes(string.Format(publicKey, areaId, type, date, appid)); //密钥 var key = System.Text.Encoding.UTF8.GetBytes(privateKey); hmac.Key = key; //对数据进行签名 var signedData = hmac.ComputeHash(data); return Convert.ToBase64String(signedData); }
类型和接口已经修改,请看最新的代码:api
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; //项目添加System.Runtime.Serialization引用 using System.Runtime.Serialization.Json; using System.Security.Cryptography; using System.Web; namespace MvcApplication1 { public class Weather { //天气编码对应表 private Dictionary<string, string> weatherInfo = new Dictionary<string, string>(); //风力编码对应表 private Dictionary<string, string> WindInfo = new Dictionary<string, string>(); //风力方向对应表 private Dictionary<string, string> WindInfoDir = new Dictionary<string, string>(); private DataContractJsonSerializer ser; private byte[] buff = new byte[5 * 1024]; public Weather() { #region 初始化编码表 weatherInfo.Add("00", "晴"); weatherInfo.Add("01", "多云"); weatherInfo.Add("02", "阴"); weatherInfo.Add("03", "阵雨"); weatherInfo.Add("04", "雷阵雨"); weatherInfo.Add("05", "雷阵雨伴有冰雹"); weatherInfo.Add("06", "雨夹雪"); weatherInfo.Add("07", "小雨"); weatherInfo.Add("08", "中雨"); weatherInfo.Add("09", "大雨"); weatherInfo.Add("10", "暴雨"); weatherInfo.Add("11", "大暴雨"); weatherInfo.Add("12", "特大暴雨"); weatherInfo.Add("13", "阵雪"); weatherInfo.Add("14", "小雪"); weatherInfo.Add("15", "中雪"); weatherInfo.Add("16", "大雪"); weatherInfo.Add("17", "暴雪"); weatherInfo.Add("18", "雾"); weatherInfo.Add("19", "冻雨"); weatherInfo.Add("20", "沙尘暴"); weatherInfo.Add("21", "小到中雨"); weatherInfo.Add("22", "中到大雨"); weatherInfo.Add("23", "大到暴雨"); weatherInfo.Add("24", "暴雨到大暴雨"); weatherInfo.Add("25", "大暴雨到特大暴雨"); weatherInfo.Add("26", "小到中雪"); weatherInfo.Add("27", "中到大雪"); weatherInfo.Add("28", "大到暴雪"); weatherInfo.Add("29", "浮尘"); weatherInfo.Add("30", "扬沙"); weatherInfo.Add("31", "强沙尘暴"); weatherInfo.Add("53", "雾霾"); weatherInfo.Add("99", "无"); WindInfoDir.Add("0", "无持续风向"); WindInfoDir.Add("1", "东北风"); WindInfoDir.Add("2", "东风"); WindInfoDir.Add("3", "东南风"); WindInfoDir.Add("4", "南风"); WindInfoDir.Add("5", "西南风"); WindInfoDir.Add("6", "西风"); WindInfoDir.Add("7", "西北风"); WindInfoDir.Add("8", "北风"); WindInfoDir.Add("9", "旋转风"); WindInfo.Add("0", "微风"); WindInfo.Add("1", "3-4级"); WindInfo.Add("2", "4-5级"); WindInfo.Add("3", "5-6级"); WindInfo.Add("4", "6-7级"); WindInfo.Add("5", "7-8级"); WindInfo.Add("6", "8-9级"); WindInfo.Add("7", "9-10级"); WindInfo.Add("8", "10-11级"); WindInfo.Add("9", "11-12级"); #endregion ser = new DataContractJsonSerializer(typeof(WeatherJson)); } public void RefreshWeather() { bool update = false; //string baseurl = ""; string baseurl = "http://open.weather.com.cn/data/?areaid={0}&type={1}&date={2}&appid={3}"; var cityCode = "101180901"; //指数:index_f(基础接口);index_v(常规接口) 3天预报:forecast_f(基础接口);forecast_v(常规接口) var weatherType = "forecast_f"; var appID = "appID"; var private_key = "private_key"; string url = GetSmartWeatherApi(baseurl, cityCode, weatherType, DateTime.Now.ToString("yyyyMMddHHmm"), appID, private_key); int l = 0; try { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.UserAgent = @"Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-CN; rv:1.8.1.4) Gecko/20070515 Firefox/2.0.0.4"; //从指定的URL中获取天气信息(JSON数据) HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Stream rs = response.GetResponseStream(); l = rs.Read(buff, 0, buff.Length); rs.Close(); } catch (Exception ex) { //网络链接失败; } //反序列化为实体 var mStream = new MemoryStream(buff, 0, l); WeatherJson w; try { w = (WeatherJson)ser.ReadObject(mStream); if (w != null) { foreach (var item in w.f.f1) { item.fa_des = weatherInfo.ContainsKey(item.fa) ? weatherInfo[item.fa] : string.Empty; item.fb_des = weatherInfo.ContainsKey(item.fb) ? weatherInfo[item.fb] : string.Empty; item.fe_des = WindInfoDir.ContainsKey(item.fe) ? WindInfoDir[item.fe] : string.Empty; item.ff_des = WindInfoDir.ContainsKey(item.ff) ? WindInfoDir[item.ff] : string.Empty; item.fg_des = WindInfo.ContainsKey(item.fg) ? WindInfo[item.fg] : string.Empty; item.fh_des = WindInfo.ContainsKey(item.fh) ? WindInfo[item.fh] : string.Empty; } } } catch (System.Runtime.Serialization.SerializationException) { //反序列化失败 throw; } //获取天气预报 foreach (var item in w.f.f1) { string weather = (item.fa == item.fb) ? item.fa_des : item.fa_des + "转" + item.fb_des; string temperature = item.fc + "℃ ~ " + item.fd + "℃"; string wind = item.fg == "0" ? item.fg_des : item.fe_des + " " + item.fg_des; } } private string GetSmartWeatherApi(string _baseUrl, string _areaId, string _type, string _date, string _appID, string _privateKey) { string publicKey = string.Format(_baseUrl, _areaId, _type, _date, _appID); string fullUrl = string.Format(_baseUrl, _areaId, _type, _date, _appID.Substring(0, 6)); fullUrl = string.Format("{0}&key={1}", fullUrl, GetSmartWeatherKeyCode(publicKey, _privateKey)); return fullUrl; } private string GetSmartWeatherKeyCode(string _publicKey, string _privateKey) { //使用SHA1的HMAC HMAC hmac = HMACSHA1.Create(); Byte[] data = System.Text.Encoding.UTF8.GetBytes(_publicKey); //密钥 Byte[] key = System.Text.Encoding.UTF8.GetBytes(_privateKey); hmac.Key = key; //对数据进行签名 var signedData = hmac.ComputeHash(data); string keyCode = Convert.ToBase64String(signedData); keyCode = System.Web.HttpUtility.UrlEncode(keyCode); return keyCode; } } #region 天气实体类,用于获取气象局json数据反序列化 public class WeatherJson { /// <summary> /// 城市 /// </summary> public WeatherC c { get; set; } /// <summary> /// 预报 /// </summary> public WeatherF f { get; set; } /// <summary> /// 实况 /// </summary> public WeatherL l { get; set; } /// <summary> /// 指数 /// </summary> public WeatherI i { get; set; } } /// <summary> /// 实况,type=observe /// 示例: /// "l":{ /// "l1":8" /// "l2":"38" /// "l3":"6" /// "l4":"3" /// "l7":"11:00" /// } /// </summary> public class WeatherL { /// <summary> /// 当前温度(摄氏度) /// </summary> public string l1 { get; set; } /// <summary> /// 当前湿度(单位%) /// </summary> public string l2 { get; set; } /// <summary> /// 当前风力(单位是级,无需根据风力编码表取值,直接显示便可) /// </summary> public string l3 { get; set; } /// <summary> /// 当前风向编号 /// </summary> public string l4 { get; set; } /// <summary> /// 实况发布时间 /// </summary> public string l7 { get; set; } } /// <summary> /// 指数,type=index /// 示例: /// "i":[ /// { /// "i1":"ct", /// "i2":"穿衣指数", /// "i3":"" , /// "i4":"热”, /// "i5":"天气热,建议着短裙、短裤、短薄外套、T 恤等夏季服装。" /// }, /// ] /// </summary> public class WeatherI { /// <summary> /// 指数简称 /// </summary> public string i1 { get; set; } /// <summary> /// 指数中文名称 /// </summary> public string i2 { get; set; } /// <summary> /// 指数中文别名 /// </summary> public string i3 { get; set; } /// <summary> /// 指数级别 /// </summary> public string i4 { get; set; } /// <summary> /// 指数内容 /// </summary> public string i7 { get; set; } } /// <summary> /// 预报,城市信息,type=forecast3d /// </summary> public class WeatherC { /// <summary> /// 区域 ID /// </summary> public string c1 { get; set; } /// <summary> /// 城市英文名 /// </summary> public string c2 { get; set; } /// <summary> /// 城市英文名 /// </summary> public string c3 { get; set; } /// <summary> /// 城市所在市英文名 /// </summary> public string c4 { get; set; } /// <summary> /// 城市所在市中文名 /// </summary> public string c5 { get; set; } /// <summary> /// 城市所在省英文名 /// </summary> public string c6 { get; set; } /// <summary> /// 城市所在省中文名 /// </summary> public string c7 { get; set; } /// <summary> /// 城市所在国家英文名 /// </summary> public string c8 { get; set; } /// <summary> /// 城市所在国家中文名 /// </summary> public string c9 { get; set; } /// <summary> /// 城市级别 /// </summary> public string c10 { get; set; } /// <summary> /// 城市区号 /// </summary> public string c11 { get; set; } /// <summary> /// 城市区号 /// </summary> public string c12 { get; set; } /// <summary> /// 经度 /// </summary> public string c13 { get; set; } /// <summary> /// 纬度 /// </summary> public string c14 { get; set; } /// <summary> /// 海拔 /// </summary> public string c15 { get; set; } /// <summary> /// 雷达站号 /// </summary> public string c16 { get; set; } } /// <summary> /// 预报,type=forecast3d /// </summary> public class WeatherF { /// <summary> /// 预报发布时间 /// </summary> public string f0 { get; set; } /// <summary> /// 3天的天气预报 /// </summary> public WeatherF1[] f1 { get; set; } } public class WeatherF1 { /// <summary> /// 白每天气现象编号 /// </summary> public string fa { get; set; } public string fa_des { get; set; } /// <summary> /// 晚上天气现象编号 /// </summary> public string fb { get; set; } public string fb_des { get; set; } /// <summary> /// 白每天气温度(摄氏度) /// </summary> public string fc { get; set; } /// <summary> /// 晚上天气温度(摄氏度) /// </summary> public string fd { get; set; } /// <summary> /// 白天风向编号 /// </summary> public string fe { get; set; } public string fe_des { get; set; } /// <summary> /// 晚上风向编号 /// </summary> public string ff { get; set; } public string ff_des { get; set; } /// <summary> /// 白天风力编号 /// </summary> public string fg { get; set; } public string fg_des { get; set; } /// <summary> /// 晚上风力编号 /// </summary> public string fh { get; set; } public string fh_des { get; set; } /// <summary> /// 日出日落时间(中间用|分割) /// </summary> public string fi { get; set; } } #endregion }