利用.net4.0的dynamic特性制造的超级简单的微信SDK
1.基础支持API
/*-------------------------------------------------------------------------- * BasicAPI.cs *Auth:deepleo * Date:2013.12.31 * Email:2586662969@qq.com *--------------------------------------------------------------------------*/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Http; using Codeplex.Data; using System.IO; namespace Deepleo.Weixin.SDK { /// <summary> /// 对应微信API的 "基础支持" /// </summary> public class BasicAPI { /// <summary> /// 检查签名是否正确: /// http://mp.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97 /// </summary> /// <param name="signature"></param> /// <param name="timestamp"></param> /// <param name="nonce"></param> /// <param name="token">AccessToken</param> /// <returns> /// true: check signature success /// false: check failed, 非微信官方调用! /// </returns> public static bool CheckSignature(string signature, string timestamp, string nonce, string token, out string ent) { var arr = new[] { token, timestamp, nonce }.OrderBy(z => z).ToArray(); var arrString = string.Join("", arr); var sha1 = System.Security.Cryptography.SHA1.Create(); var sha1Arr = sha1.ComputeHash(Encoding.UTF8.GetBytes(arrString)); StringBuilder enText = new StringBuilder(); foreach (var b in sha1Arr) { enText.AppendFormat("{0:x2}", b); } ent = enText.ToString(); return signature == enText.ToString(); } /// <summary> /// 获取AccessToken /// http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96access_token /// </summary> /// <param name="grant_type"></param> /// <param name="appid"></param> /// <param name="secrect"></param> /// <returns>access_toke</returns> public static dynamic GetAccessToken( string appid, string secrect) { var url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type={0}&appid={1}&secret={2}", "client_credential", appid, secrect); var client = new HttpClient(); var result = client.GetAsync(url).Result; if (!result.IsSuccessStatusCode) return string.Empty; var token = DynamicJson.Parse(result.Content.ReadAsStringAsync().Result); return token; } /// <summary> /// 上传多媒体文件 /// http://mp.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E4%B8%8B%E8%BD%BD%E5%A4%9A%E5%AA%92%E4%BD%93%E6%96%87%E4%BB%B6 /// 1.上传的媒体文件限制: ///图片(image) : 1MB,支持JPG格式 ///语音(voice):1MB,播放长度不超过60s,支持MP4格式 ///视频(video):10MB,支持MP4格式 ///缩略图(thumb):64KB,支持JPG格式 ///2.媒体文件在后台保存时间为3天,即3天后media_id失效 /// </summary> /// <param name="token"></param> /// <param name="type"></param> /// <param name="file"></param> /// <returns>media_id</returns> public static string UploadMedia(string token, string type, string file) { var url = string.Format("http://api.weixin.qq.com/cgi-bin/media/upload?access_token={0}&type={1}&filename={2}", token, type, Path.GetFileName(file)); var client = new HttpClient(); var result = client.PostAsync(url, new StreamContent(new FileStream(file, FileMode.Open, FileAccess.Read))); if (!result.Result.IsSuccessStatusCode) return string.Empty; var media = DynamicJson.Parse(result.Result.Content.ReadAsStringAsync().Result); return media.media_id; } } }
2.接收消息
/*-------------------------------------------------------------------------- * AcceptMessageAPI.cs *Auth:deepleo * Date:2013.12.31 * Email:2586662969@qq.com *--------------------------------------------------------------------------*/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Dynamic; using System.Xml.Linq; using System.Xml; using Codeplex.Data; namespace Deepleo.Weixin.SDK { /// <summary> /// 对应微信API的 "接收消息" /// </summary> public class AcceptMessageAPI { /// <summary> /// 解析微信服务器推送的消息 /// http://mp.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E6%94%B6%E6%99%AE%E9%80%9A%E6%B6%88%E6%81%AF /// http://mp.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E6%94%B6%E4%BA%8B%E4%BB%B6%E6%8E%A8%E9%80%81 /// </summary> /// <param name="message"></param> /// <returns></returns> public static WeixinMessage Parse(string message) { var msg = new WeixinMessage(); msg.Body = new DynamicXml(message); string msgType = msg.Body.MsgType.Value; switch (msgType) { case "text": msg.Type = WeixinMessageType.Text; break; case "image": msg.Type = WeixinMessageType.Image; break; case "voice": msg.Type = WeixinMessageType.Voice; break; case "video": msg.Type = WeixinMessageType.Video; break; case "location": msg.Type = WeixinMessageType.Location; break; case "link": msg.Type = WeixinMessageType.Link; break; case "event": msg.Type = WeixinMessageType.Event; break; default: throw new Exception("does not support this message type:" + msgType); } return msg; } } }
3.发送消息
/*-------------------------------------------------------------------------- * SendMessageAPI.cs *Auth:deepleo * Date:2013.12.31 * Email:2586662969@qq.com *--------------------------------------------------------------------------*/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using Codeplex.Data; using System.Net; using System.Net.Http; namespace Deepleo.Weixin.SDK { /// <summary> /// 对应微信API的 "发送消息” /// </summary> public class SendMessageAPI { /// <summary> /// 被动回复消息 /// </summary> /// <param name="message">微信服务器推送的消息</param> /// <param name="executor">用户自定义的消息执行者</param> /// <returns></returns> public static string Relay(WeixinMessage message, IWeixinExecutor executor) { return executor.Execute(message); } /// <summary> /// 主动发送客服消息 /// http://mp.weixin.qq.com/wiki/index.php?title=%E5%8F%91%E9%80%81%E5%AE%A2%E6%9C%8D%E6%B6%88%E6%81%AF /// 当用户主动发消息给公众号的时候 /// 开发者在一段时间内(目前为24小时)可以调用客服消息接口,在24小时内不限制发送次数。 /// </summary> /// <param name="token"></param> /// <param name="msg">json格式的消息,具体格式请参考微信官方API</param> /// <returns></returns> public static bool Send(string token, string msg) { var client = new HttpClient(); var task = client.PostAsync(string.Format("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={0}", token), new StringContent(msg)).Result; return task.IsSuccessStatusCode; } } }
4.用户管理
/*-------------------------------------------------------------------------- * UserAdminAPI.cs *Auth:deepleo * Date:2013.12.31 * Email:2586662969@qq.com *--------------------------------------------------------------------------*/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Http; using Codeplex.Data; namespace Deepleo.Weixin.SDK { /// <summary> /// 对应微信API的 "用户管理" /// 注意: /// 1.以下API未实现 : /// "分组管理接口",“网页授权获取用户基本信息” /// 2.获取用户"地理位置"API 见AcceptMessageAPI实现, /// “地理位置”获取方式有两种:一种是仅在进入会话时上报一次,一种是进入会话后每隔5秒上报一次,公众号可以在公众平台网站中设置。 /// </summary> public class UserAdminAPI { /// <summary> /// 获取用户基本信息 /// </summary> /// <param name="token"></param> /// <param name="openId"></param> /// <returns></returns> public static dynamic GetInfo(string token, string openId) { var client = new HttpClient(); var result = client.GetAsync(string.Format("https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}", token, openId)).Result; if (!result.IsSuccessStatusCode) return null; return DynamicJson.Parse(result.Content.ReadAsStringAsync().Result); } /// <summary> /// 获取订阅者信息 /// </summary> /// <param name="token"></param> /// <returns></returns> public static dynamic GetSubscribes(string token) { var client = new HttpClient(); var result = client.GetAsync(string.Format("https://api.weixin.qq.com/cgi-bin/user/get?access_token={0}", token)).Result; if (!result.IsSuccessStatusCode) return null; return DynamicJson.Parse(result.Content.ReadAsStringAsync().Result); } /// <summary> /// 获取订阅者信息 /// </summary> /// <param name="token"></param> /// <param name="nextOpenId"></param> /// <returns></returns> public static dynamic GetSubscribes(string token, string nextOpenId) { var client = new HttpClient(); var result = client.GetAsync(string.Format("https://api.weixin.qq.com/cgi-bin/user/get?access_token={0}&next_openid={1}", token, nextOpenId)).Result; if (!result.IsSuccessStatusCode) return null; return DynamicJson.Parse(result.Content.ReadAsStringAsync().Result); } } }
5.自定义菜单
/*-------------------------------------------------------------------------- * CustomMenu.cs *Auth:deepleo * Date:2013.12.31 * Email:2586662969@qq.com *--------------------------------------------------------------------------*/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Http; using Codeplex.Data; namespace Deepleo.Weixin.SDK { /// <summary> /// 对应微信API的 "自定义菜单” /// 注意:自定义菜单事件推送接口见:AcceptMessageAPI /// </summary> public class CustomMenuAPI { /// <summary> /// 自定义菜单创建接口 /// </summary> /// <param name="token"></param> /// <param name="content"></param> /// <returns></returns> public static bool Create(string token, string content) { var client = new HttpClient(); var result = client.PostAsync(string.Format("https://api.weixin.qq.com/cgi-bin/menu/create?access_token={0}", token), new StringContent(content)).Result; return DynamicJson.Parse(result.Content.ReadAsStringAsync().Result).errcode == 0; } /// <summary> /// 自定义菜单查询接口 /// </summary> /// <param name="token"></param> /// <returns></returns> public static dynamic Query(string token) { var client = new HttpClient(); var result = client.GetAsync(string.Format("https://api.weixin.qq.com/cgi-bin/menu/get?access_token={0}", token)).Result; if (!result.IsSuccessStatusCode) return null; return DynamicJson.Parse(result.Content.ReadAsStringAsync().Result); } /// <summary> /// 自定义菜单删除接口 /// </summary> /// <param name="token"></param> /// <returns></returns> public static bool Delete(string token) { var client = new HttpClient(); var result = client.GetAsync(string.Format("https://api.weixin.qq.com/cgi-bin/menu/delete?access_token={0}", token)).Result; if (!result.IsSuccessStatusCode) return false; return DynamicJson.Parse(result.Content.ReadAsStringAsync().Result).errmsg == "ok"; } } }
详细:https://github.com/night-king/weixinSDK
关于DynamicJson和Dynamicxml请参考:上一篇文章:http://www.cnblogs.com/deepleo/p/weixinSDK.html
QQ互助交流群:173564082
阿里云9折优惠码:3RRWQH,第一次购买云服务器或云数据库可享受原价9折优惠,还可多人使用,拿走不谢。