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

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

    一、准备,设置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。

  • 相关阅读:
    使用tcmalloc编译启动时宕机
    使用tcmalloc编译出现undefined reference to `sem_init'
    使用AddressSanitizer做内存分析(一)——入门篇
    VIM-美化你的标签栏
    Entity Framework Code First (六)存储过程
    Entity Framework Code First (五)Fluent API
    Entity Framework Code First (四)Fluent API
    Entity Framework Code First (三)Data Annotations
    Entity Framework Code First (二)Custom Conventions
    Entity Framework Code First (一)Conventions
  • 原文地址:https://www.cnblogs.com/zxtceq/p/11049627.html
Copyright © 2011-2022 走看看