微信平台接入Web页面功能接口(C#)
微信平台接入web页面功能接口
今年因工作需要,通过微信平台接入公司的Wap页面,回忆下,记录内容,方面以后使用。
1.成为开发者后,你才可以使用公众平台的开发功能。需要填写URL和ToKen,接口配置信息。
2.服务器端开发如下接口,等待微信服务器调用。
URL:
用来接收微信服务器数据的接口URL,
http://192.168.0.199/weixin/****.ashx(该地址不固定,可以由后台开发者根据实际情况自己拟定,但只支持80端口)
Token:
开发者可以任意拟定,已备用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)。
请求方式:
Get
接收参数:
参数 |
描述 |
signature |
微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。 |
timestamp |
时间戳 |
nonce |
随机数 |
echostr |
随机字符串 |
响应微信服务器:
开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,否则接入失败。
加密/校验流程如下:
1. 将token、timestamp、nonce三个参数进行字典序排序 2. 将三个参数字符串拼接成一个字符串进行sha1加密 3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信 |
3. 在公众平台网站的高级功能 – 开发模式页,点击“成为开发者”按钮,填写URL和Token。提交信息后,微信服务器将发送GET请求到填写的URL上,进行接入验证。
4.C#代码
object signature = context.Request.QueryString["signature"]; object timestamp = context.Request.QueryString["timestamp"]; object nonce = context.Request.QueryString["nonce"]; object echoStr = context.Request.QueryString["echoStr"]; if (signature != null && signature.ToString() != "" && timestamp != null && timestamp.ToString() != "" && nonce != null && nonce.ToString() != "" && echoStr != null && echoStr.ToString() != "") { CheckSignature(signature.ToString(), timestamp.ToString(), nonce.ToString(), echoStr.ToString(), token); } /// <summary> /// 验证微信 字典排序后 返回随机数 /// </summary> /// 将token、timestamp、nonce三个参数进行字典排序 /// 将三个参数字符串拼接成一个字符串sha1加密 /// 获取加密后的字符串可与signature 对比 如果为true则返回随数 /// <returns></returns> private void CheckSignature(string signature, string timestamp, string nonce, string echoStr, string Token) { string[] ArrTmp = { Token, timestamp, nonce }; Array.Sort(ArrTmp); //首º¡Á先¨¨字Á?典Ì?排?序¨° string tmpStr = string.Join("", ArrTmp); tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1"); //sha1 tmpStr = tmpStr.ToLower(); if (tmpStr == signature) { if (!string.IsNullOrEmpty(echoStr)) { System.Web.HttpContext.Current.Response.Write(echoStr); System.Web.HttpContext.Current.Response.End(); } } }
5.验证通过后,就可以得到appid 和secret参数了
6.创建菜单
(1)目前自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替。请注意,创建自定义菜单后,由于微信客户端缓存,需要24小时微信客户端才会展现出来。建议测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果。
目前自定义菜单接口可实现两种类型按钮,如下:
click:
用户点击click类型按钮后,微信服务器会通过消息接口推送消息类型为event 的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值与用户进行交互;
view:
用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的url值 (即网页链接),达到打开网页的目的,建议与网页授权获取用户基本信息接口结合,获得用户的登入个人信息。
(2)示例:
接口调用请求说明
http请求方式:POST(请使用https协议)
https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
请求示例
{ "button":[ { "type":"click", "name":"今日歌曲", "key":"V1001_TODAY_MUSIC" }, { "type":"click", "name":"歌手简介", "key":"V1001_TODAY_SINGER" }, { "name":"菜单", "sub_button":[ { "type":"view", "name":"搜索", "url":"http://www.soso.com/" }, { "type":"view", "name":"视频", "url":"http://v.qq.com/" }, { "type":"click", "name":"赞一下我们", "key":"V1001_GOOD" }] }] } |
参数说明
参数 |
是否必须 |
说明 |
button |
是 |
一级菜单数组,个数应为1~3个 |
sub_button |
否 |
二级菜单数组,个数应为1~5个 |
type |
是 |
菜单的响应动作类型,目前有click、view两种类型 |
name |
是 |
菜单标题,不超过16个字节,子菜单不超过40个字节 |
key |
click类型必须 |
菜单KEY值,用于消息接口推送,不超过128字节 |
url |
view类型必须 |
网页链接,用户点击菜单可打开链接,不超过256字节 |
返回结果
正确时的返回JSON数据包如下:
{"errcode":0,"errmsg":"ok"}
错误时的返回JSON数据包如下(示例为无效菜单名长度):
{"errcode":40018,"errmsg":"invalid button name size"}
(3)代码
/// <summary> ///创建菜单 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void btnCreateMenu_Click(object sender, EventArgs e) { string postUrl = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token={0}"; postUrl = string.Format(postUrl, GetAccessToken()); string menuInfo = getMenuInfo(); lblResult.Text = "结¨¢果?:êo" + PostWebRequest(postUrl, menuInfo); } /// <summary> /// 获取微信 access_token /// </summary> /// <returns></returns> protected string GetAccessToken() { string accessToken = string.Empty; string getUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}"; getUrl = string.Format(getUrl, "你的appid", "你的secret"); Uri uri = new Uri(getUrl); HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(uri); webReq.Method = "POST"; //获取返回信息 HttpWebResponse response = (HttpWebResponse)webReq.GetResponse(); StreamReader streamReader = new StreamReader(response.GetResponseStream(), Encoding.Default); string returnJason = streamReader.ReadToEnd(); JavaScriptSerializer serializer = new JavaScriptSerializer(); Dictionary<string, object> json = (Dictionary<string, object>)serializer.DeserializeObject(returnJason); object value; if (json.TryGetValue("access_token", out value)) { accessToken = value.ToString(); } return accessToken; } /// <summary> ///菜单内容 /// </summary> /// <returns></returns> private string getMenuInfo() { //现暂时写死 string menu = "{" + ""button":[" + "{" + ""name":"服务"," + ""sub_button":[" + "{" + ""type":"view"," + ""name":"更多服务"," + ""url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid= appid&redirect_uri=http://192.168.0.199/weixin/WeixinCommon.ashx?action=6&response_type=code&scope=snsapi_base&state=6#wechat_redirect"" + "}," + "{" + ""type":"view"," + ""name":"更多服务1"," + ""url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=http://192.168.0.199/weixin/WeixinCommon.ashx?action=10&response_type=code&scope=snsapi_base&state=10#wechat_redirect"" + "}," + "{" + ""type":"view"," + ""name":" 更多服务2"," + ""url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=http://192.168.0.199/weixin/WeixinCommon.ashx?action=11&response_type=code&scope=snsapi_base&state=11#wechat_redirect"" + "}," + "{" + ""type":"view"," + ""name":"更多服务3"," + ""url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=http://192.168.0.199/weixin/WeixinCommon.ashx?action=6&response_type=code&scope=snsapi_base&state=6#wechat_redirect"" + "}," + "{" + ""type":"view"," + ""name":"更多服务4 "," + ""url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=http://192.168.0.199/weixin/WeixinCommon.ashx?action=6&response_type=code&scope=snsapi_base&state=6#wechat_redirect"" + "}]}," + "{" + ""name":"业务"," + ""sub_button":[" + "{" + ""type":"view"," + ""name":"业务1"," + ""url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=http://192.168.0.199/weixin/WeixinCommon.ashx?action=5&response_type=code&scope=snsapi_base&state=5#wechat_redirect"" + "}," + "{" + ""type":"view"," + ""name":"业务2"," + ""url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=http://192.168.0.199/weixin/WeixinCommon.ashx?action=6&response_type=code&scope=snsapi_base&state=6#wechat_redirect"" + "}," + "{" + ""type":"view"," + ""name":"业务3"," + ""url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=http://192.168.0.199/weixin/WeixinCommon.ashx?action=7&response_type=code&scope=snsapi_base&state=7#wechat_redirect"" + "}," + "{" + ""type":"view"," + ""name":"业务4"," + ""url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=http://192.168.0.199/weixin/WeixinCommon.ashx?action=8&response_type=code&scope=snsapi_base&state=8#wechat_redirect"" + "}]" + "}," + "{" + ""name":"办理"," + ""sub_button":[" + "{" + ""type":"view"," + ""name":"办理1 "," + ""url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=http://192.168.0.199/weixin/WeixinCommon.ashx?action=14&response_type=code&scope=snsapi_base&state=14#wechat_redirect"" + "}," + "{"+ ""type":"view","+ ""name":"办理2","+ ""url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=http://192.168.0.199/weixin/WeixinCommon.ashx?action=1&response_type=code&scope=snsapi_base&state=1#wechat_redirect"" + "},"+ "{"+ ""type":"view","+ ""name":"办理3","+ ""url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=http://192.168.0.199/weixin/WeixinCommon.ashx?action=2&response_type=code&scope=snsapi_base&state=2#wechat_redirect"" + "},"+ "{"+ ""type":"view","+ ""name":"办理4","+ ""url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=http://192.168.0.199/weixin/WeixinCommon.ashx?action=3&response_type=code&scope=snsapi_base&state=3#wechat_redirect"" + "},"+ "{"+ ""type":"view","+ ""name":"办理5","+ ""url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=http://192.168.0.199/weixin/WeixinCommon.ashx?action=4&response_type=code&scope=snsapi_base&state=4#wechat_redirect"" + "}]}]}"; return menu; } /// <summary> /// 写入 /// </summary> /// <param name="postUrl"></param> /// <param name="menuInfo"></param> /// <returns></returns> private string PostWebRequest(string postUrl, string menuInfo) { string returnValue = string.Empty; try { byte[] byteData = Encoding.UTF8.GetBytes(menuInfo); Uri uri = new Uri(postUrl); HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(uri); webReq.Method = "POST"; webReq.ContentType = "application/x-www-form-urlencoded"; webReq.ContentLength = byteData.Length; //定义Stream信息 Stream stream = webReq.GetRequestStream(); stream.Write(byteData, 0, byteData.Length); stream.Close(); //获取返回信息 HttpWebResponse response = (HttpWebResponse)webReq.GetResponse(); StreamReader streamReader = new StreamReader(response.GetResponseStream(), Encoding.Default); returnValue = streamReader.ReadToEnd(); //关闭 streamReader.Close(); response.Close(); stream.Close(); } catch (Exception ex) { lblResult.Text = ex.ToString(); } return returnValue; } /// <summary> ///删除菜单 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void btnDeleteMenu_Click(object sender, EventArgs e) { string postUrl = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token={0}"; postUrl = string.Format(postUrl, GetAccessToken()); string menuInfo = getMenuInfo(); lblResult.Text = "结¨¢果?:êo" + PostWebRequest(postUrl, menuInfo); } Aspx视图中 <asp:Button ID="btnCreateMenu" runat="server" Text="创ä¡ä建¡§菜?单Ì£¤" onclick="btnCreateMenu_Click" /> <asp:Button ID="btnDeleteMenu" runat="server" Text="删¦?除y菜?单Ì£¤" onclick="btnDeleteMenu_Click" /> <asp:Label ID="lblResult" runat="server" Text="结¨¢果?"></asp:Label> </form>