微信JS SDK开发的简单封装_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 微信JS SDK开发的简单封装

微信JS SDK开发的简单封装

 2015/1/13 17:44:43  nextuntil  程序员俱乐部  我要评论(0)
  • 摘要:最近在做webapp小项目的开发,涉及到微信的分享(分享到朋友圈/发送给朋友等)元旦之前就基本上完成功能开发了,当时微信并未开放分享等API于是用了网上找到的一些方法去实现,但是元旦左右就不能再正常使用了前几天微信官方上线了JSSDK以及文档说明,地址:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html主要步骤如下:1、通过appid和appsecret获取access_token;2
  • 标签:SDK 开发 JS

最近在做webapp小项目的开发,涉及到微信的分享(分享到朋友圈/发送给朋友等)

元旦之前就基本上完成功能开发了,当时微信并未开放分享等API

于是用了网上找到的一些方法去实现,但是元旦左右就不能再正常使用

 

前几天微信官方上线JS SDK以及文档说明,地址:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html

主要步骤如下:

1、通过appid和appsecret获取access_token;

2、通过access_token获取jsapi_ticket;

3、实现签名算法

4、初始化wx.config参数信息;

5、在wx.ready内进行相关API调用

虽然相比之前调用起来麻烦了一些,但是更安全稳定,于是马上对之前的代码做了调整,分享如下

【部分代码基于项目的基类,如缓存和日志等,此处不贴出,比较简单,可自己实现】

 

以下是后台代码部分: 

class="brush:csharp;gutter:true;">/*
 *nextuntil
 *微信JS SDK调用简单封装
 *2015-01-12
 */
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using KK.Utility;
using KK.Utility.Extensions;

namespace M {
    public static class WeixinHelper {

        #region Get请求的简单封装

        /// <summary>发起GET请求</summary>
        /// <param name="url">请求URL</param>
        /// <param name="errmsg">错误信息</param>
        /// <param name="parameters">请求参数</param>
        /// <returns></returns>
        public static string Get(string url, out string errmsg, Dictionary<string, object> parameters) {
            errmsg = null;
            var strUrl = new StringBuilder(url);
            if (parameters != null && parameters.Count > 0) {
                //拼接参数
                strUrl.Append("?");
                foreach (KeyValuePair<string, object> keyValuePair in parameters) {
                    strUrl.AppendFormat("{0}={1}&",
                        HttpUtility.UrlEncode(keyValuePair.Key, Encoding.UTF8),
                        HttpUtility.UrlEncode(keyValuePair.Value.ToString(), Encoding.UTF8));
                }
                strUrl.Remove(strUrl.Length - 1, 1);//移除最后一位多出的“&”
            }
            var request = (HttpWebRequest)WebRequest.Create(strUrl.ToString());
            request.Method = "GET";
            request.Timeout = 10000;
            try {
                var response = (HttpWebResponse)request.GetResponse();
                using (Stream stream = response.GetResponseStream()) {
                    if (stream != null) {
                        var reader = new StreamReader(stream);
                        return reader.ReadToEnd();
                    }
                }
            } catch (Exception ex) {
                errmsg = "请求异常:" + ex.Message;
            }
            return null;
        }

        #endregion

        #region SHA1加密算法

        /// <summary>
        /// SHA1加密算法
        /// </summary>
        /// <param name="str">要加密的字符串</param>
        /// <returns></returns>
        public static string GetSha1Str(string str) {
            byte[] strRes = Encoding.UTF8.GetBytes(str);
            HashAlgorithm iSha = new SHA1CryptoServiceProvider();
            strRes = iSha.ComputeHash(strRes);
            var enText = new StringBuilder();
            foreach (byte iByte in strRes) {
                enText.AppendFormat("{0:x2}", iByte);
            }
            return enText.ToString();
        }

        #endregion

        /// <summary>
        /// 获取调用JS SDK时所需的access_token
        /// 文档地址:http://mp.weixin.qq.com/wiki/15/54ce45d8d30b6bf6758f68d2e95bc627.html
        /// </summary>
        /// <returns></returns>
        public static string GetAccessToken() {
            //获取access_token在2小时内有效,由于1天内获取次数有限制(2000次),因此缓存2小时
            return KK.Cache.MyCache.Instance.Get<string>("wxapi/jssdk/accesstoken", () => {
                string errmsg;
                string apiUrl = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", Utils.GetAppId(), Utils.GetAppSecret());
                string responseStr = Get(apiUrl, out errmsg, null);
                if (responseStr == null) {
                    KK.Core.Log.TraceLogger.Info("获取access_token失败,响应内容为空", null);
                } else {
                    var dic = responseStr.JSONDeserialize<Dictionary<string, object>>();
                    if (dic.ContainsKey("access_token")) {
                        return dic["access_token"];
                    } else {
                        KK.Core.Log.TraceLogger.Info("获取access_token失败,响应内容:" + responseStr, null);
                    }
                }
                return null;
            }, 120);
        }

        /// <summary>
        /// 获取调用JS SDK时所需的票据
        /// 文档地址:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD.951-JS-SDK.E4.BD.BF.E7.94.A8.E6.9D.83.E9.99.90.E7.AD.BE.E5.90.8D.E7.AE.97.E6.B3.95
        /// </summary>
        /// <returns></returns>
        public static string GetJsApiTicket() {
            //获取的ticket在2小时内有效,由于1天内获取次数有限制(2000次),因此缓存2小时
            return KK.Cache.MyCache.Instance.Get<string>("wxapi/jssdk/jsapiticket", () => {
                string errmsg;
                string apiUrl = string.Format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi", GetAccessToken());
                string responseStr = Get(apiUrl, out errmsg, null);
                if (responseStr == null) {
                    KK.Core.Log.TraceLogger.Info("获取ticket失败", null);
                } else {
                    var dic = responseStr.JSONDeserialize<Dictionary<string, object>>();
                    if (dic.ContainsKey("ticket")) {
                        return dic["ticket"];
                    }
                }
                return null;
            }, 120);
        }

        /// <summary>
        /// JS SDK使用权限签名算法
        /// </summary>
        /// <param name="jsapiTicket">The jsapi_ticket.</param>
        /// <param name="url">The URL.</param>
        /// <returns></returns>
        public static Dictionary<string, string> Sign(string jsapiTicket, string url) {
            string nonceStr = Guid.NewGuid().ToString().Replace("-", "");
            string timestamp = ConvertHelper.DateToUnix(DateTime.Now,2).ToString();
            string str = string.Format("jsapi_ticket={0}&noncestr={1}&timestamp={2}&url={3}", jsapiTicket, nonceStr, timestamp, url);
            string signature = GetSha1Str(str);//SHA1加密
            return new Dictionary<string, string>{
                {"url", url},
                {"jsapi_ticket", jsapiTicket},
                {"noncestr", nonceStr},
                {"timestamp", timestamp},
                {"signature", signature}
            };
        }

    }
}

  

 

网页代码[我的项目是webform]:

javascript;gutter:true;"><script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script type="text/javascript"> 
        <%
    string jsapiTicket = M.WeixinHelper.GetJsApiTicket();
    Dictionary<string, string> dic = M.WeixinHelper.Sign(jsapiTicket, Request.Url.AbsoluteUri);
        %>
    wx.config({
        debug: true, 
        appId: '你的appid', 
        timestamp: <%=dic["timestamp"]%>, 
        nonceStr: '<%=dic["noncestr"]%>', 
        signature: '<%=dic["signature"]%>',
        jsApiList: [
            'onMenuShareTimeline',
            'onMenuShareAppMessage',
            'onMenuShareQQ',
            'onMenuShareWeibo'
        ]
    });
    wx.ready(function() {
        wx.onMenuShareTimeline({
            title: '分享标题', 
            link: '链接地址',
            imgUrl: '图片地址',
            success: function () { 
                // 用户确认分享后执行的回调函数
            },
            cancel: function () { 
                // 用户取消分享后执行的回调函数
            }
        });
    });
</script>

  

程序调试过程中也碰到一些小问题,不知道大家有没有解决方案:

1、发送给好友的自定义内容中,描述信息是否能换行(一般是摘要,不考虑,如果是名片,希望可以分行显示,已试过<br>和\r\n等,均无效);

2、分享的URL不能是重写过的URL(开启调试,提示签名无效,调试多次发现是URL的问题)

发表评论
用户名: 匿名