zoukankan      html  css  js  c++  java
  • 微信开发】【Asp.net MVC】-- 微信分享功能

    【微信开发】【Asp.net MVC】-- 微信分享功能

    2017-01-15 09:09 by stoneniqiu, 12886 阅读, 15 评论, 收藏编辑

    内嵌在微信中的网页,右上角都会有一个默认的分享功能。如下图所示,第一个为自定义的效果,第二个为默认的效果。实现了自定义的分享链接是不是更让人有点击的欲望?下面讲解下开发的过程。

    一、准备,设置js接口安全域名

    这需要使用微信的jssdk,先需要在微信公众号后台进行设置:公众号设置-->功能设置-->JS接口安全域名。打开这个页面之后你会看到下面的提示。需要先下载这个文件并上传到指定域名的根目录。

    这个文件里面是一个字符串,从名称看是用来校验用的。先上传了这个文件,你才能保存成功。这样你就可以使用jssdk了。

     二、前端配置

     首先要说明的是分享功能是一个配置功能,绑定在按钮的click事件中是没有效果的。也就是说只有点击右上角的分享才有效果(有的文字内容分享不知道是怎么实现的)。官方的js有四个步骤,首先是引入jssdk:

    <script src="http://res.wx.qq.com/open/js/jweixin-1.1.0.js"></script>

    根据官方的配置参数,我们可以定义一个WXShareModel对象:

    复制代码
       public class WXShareModel
        {
            public string appId { get; set; }
            public string nonceStr { get; set; }
            public long timestamp { get; set; }
    
            public string signature { get; set; }
    
            public string ticket { get; set; }
            public string url { get; set; }
    
            public void MakeSign()
            {
                 var string1Builder = new StringBuilder();
                 string1Builder.Append("jsapi_ticket=").Append(ticket).Append("&")
                              .Append("noncestr=").Append(nonceStr).Append("&")
                              .Append("timestamp=").Append(timestamp).Append("&")
                              .Append("url=").Append(url.IndexOf("#") >= 0 ? url.Substring(0, url.IndexOf("#")) : url);
                var string1 = string1Builder.ToString();
                signature = Util.Sha1(string1, Encoding.Default);
    
            }
        }
    复制代码

    然后是进行配置:

    复制代码
    wx.config({
            debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
            appId: '@Model.appId', // 必填,公众号的唯一标识
            timestamp: '@Model.timestamp', // 必填,生成签名的时间戳
            nonceStr: '@Model.nonceStr', // 必填,生成签名的随机串
            signature: '@Model.signature',// 必填,签名,见附录1
            jsApiList: ["checkJsApi", "onMenuShareTimeline", "onMenuShareAppMessage", "onMenuShareQQ", "onMenuShareQZone"] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
        });
    
        wx.ready(function () {
            document.querySelector('#checkJsApi').onclick = function () {
                wx.checkJsApi({
                    jsApiList: [
                'getNetworkType',
                'previewImage'
                    ],
                    success: function (res) {
                        alert(JSON.stringify(res));
                    }
                });
            };
        //朋友圈
            wx.onMenuShareTimeline({
                title: '暖木科技', // 分享标题
                link: 'http://www.warmwood.com/home/lampindex', // 分享链接
                imgUrl: 'http://www.warmwood.com/images/s1.jpg',
                success: function (res) {
                    alert('已分享');
                },
                cancel: function (res) {
                    alert('已取消');
                },
                fail: function (res) {
                    alert(JSON.stringify(res));
                }
            });
            //朋友
            wx.onMenuShareAppMessage({
                title: '暖木科技', // 分享标题
                desc: '宝宝的睡眠很重要,你的睡眠也很重要', // 分享描述
                link: 'http://www.warmwood.com/home/lampindex', // 分享链接
                imgUrl: 'http://www.warmwood.com/images/s1.jpg', // 分享图标
                type: '', // 分享类型,music、video或link,不填默认为link
                dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
                success: function () {
                    // 用户确认分享后执行的回调函数
                    alert("分享");
                },
                cancel: function () {
                    // 用户取消分享后执行的回调函数
                    alert("取消分享");
                }
            });
        });
    复制代码

    然后剩下就是后端的事情了。后端的关键是获取access_token和jsapi_ticket以及生成正确的签名。另外如果要统计分享的数量,最好就是在success方法中进行统计了。

    三、生成签名

    1.access_token 

    获取access_token方法全平台都是一致的。

    public const string AccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";
    复制代码
     public TokenResult GetAccessToken()
            {
                var url = string.Format(WxDeviceConfig.AccessTokenUrl, WxDeviceConfig.AppId, WxDeviceConfig.APPSECRET);
                var res = SendHelp.Send<TokenResult>(null, url, null, CommonJsonSendType.GET);
                return res;
            }
    复制代码

    access_token的超时时间是7200秒,所以先可以缓存起来。SendHelp文章末尾可下载

    2.获取jsapi_ticket

    access_token的作用就是为了获取jsapi_ticket。用get方式获取,url:https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi,返回的JSON对象如下。

    复制代码
    {
    "errcode":0,
    "errmsg":"ok",
    "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
    "expires_in":7200
    }
    复制代码

    所以可以定义一个模型:

    复制代码
    public class jsapiTicketModel
        {
            public string errcode { get; set; }
            public string errmsg { get; set; }
    
            public string ticket { get; set; }
    
            public string expires_in { get; set; }
        }
    复制代码

    再完成获取ticket的方法:

     public jsapiTicketModel GetJsApiTicket(string accessToken)
            {
                var url = string.Format(WxPayConfig.Jsapi_ticketUrl, accessToken);
                return SendHelp.Send<jsapiTicketModel>(accessToken, url, "", CommonJsonSendType.GET);
            }

    ticket过期时间也是7200秒,并且不能频繁的请求,所以也需要再服务端缓存起来。

     private void setCacheTicket(string cache)
            {
                _cacheManager.Set(tokenKey, cache, 7200);
            }

    MemoryCacheManager:

    View Code

    3.签名

    终于到这一步了,然后你在文档中看到让你失望的一幕:

    么有C#的demo,支付那边都提供了,为啥jssdk没有提供,好吧先不吐槽了。官方也说明白签名的规则。一开始我使用的是https://github.com/night-king/weixinSDK中的签名:

    复制代码
     public static string Sha1(string orgStr, string encode = "UTF-8")
            {
                var sha1 = new SHA1Managed();
                var sha1bytes = System.Text.Encoding.GetEncoding(encode).GetBytes(orgStr);
                byte[] resultHash = sha1.ComputeHash(sha1bytes);
                string sha1String = BitConverter.ToString(resultHash).ToLower();
                sha1String = sha1String.Replace("-", "");
                return sha1String;
            }//错误示例
    复制代码

    得出的结果和官方校验的不一致,一直提示签名错误。

     

     正确的写法是:

    复制代码
    public static string Sha1(string orgStr, Encoding encode)
            {
                SHA1 sha1 = new SHA1CryptoServiceProvider();
                byte[] bytes_in = encode.GetBytes(orgStr);
                byte[] bytes_out = sha1.ComputeHash(bytes_in);
                sha1.Dispose();
                string result = BitConverter.ToString(bytes_out);
                result = result.Replace("-", "");
                return result;  
            }
    复制代码

    和官方校验的结果一直后,就ok了(忽略大小写)。另外一个需要注意的地方是签名中的url。如果页面有参数,model中的url也需要带参数,#号后面的不要。不然也是会报签名错误。

    复制代码
     public ActionResult H5Share()
            {
                var model = new WXShareModel();
                model.appId = WxPayConfig.APPID;
                model.nonceStr = WxPayApi.GenerateNonceStr();
                model.timestamp = Util.CreateTimestamp();
                model.ticket = GetTicket();
                model.url = "http://www.warmwood.com/AuthWeiXin/share";// domain + Request.Url.PathAndQuery;
                model.MakeSign();
                Logger.Debug("获取到ticket:" + model.ticket);
                Logger.Debug("获取到签名:" + model.signature);
                return View(model);
            }
    复制代码

    四、小结

    wx.config中的debug为true会alert各种操作结果。参数正确之后界面会提示:

     

    至此,分享的功能就ok了。也就打开了调用其他jssdk的大门。另外文中的SendHelp对象是用的Senparc (基于.net4.5)的dll。

    参考资料:

    签名校验:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign

    官方文档:https://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html

  • 相关阅读:
    python爬虫 --- 简书评论
    python 爬虫 伪装
    pygal的简单使用
    anaconda安装不存在的包
    python爬虫 赶集网
    my.conf 修改编码
    python3.6 使用 pymysql 连接 Mysql 数据库及 简单的增删改查操作
    基于visual Studio2013解决C语言竞赛题之1021九九乘法表
    基于visual Studio2013解决C语言竞赛题之1020订票
    基于visual Studio2013解决C语言竞赛题之1019填数
  • 原文地址:https://www.cnblogs.com/zxtceq/p/10489880.html
Copyright © 2011-2022 走看看