微信分享网页时自定义缩略图和简介(.net版本)

要实现微信分享网页时自定义缩略图和简介,需开发者在公众平台网站中创建公众号、获取接口权限后,通过微信JS-SDK的分享接口,来实现微信分享功能。

 

下面来说明实现步骤。

第一部分 准备步骤

步骤一:注册微信公众号。

申请公众号网址

微信分享网页时自定义缩略图和简介(.net版本)_第1张图片

 

步骤二:认证微信公众号。

 通过左侧导航“设置”--“微信认证”进入。不进行认证,无法使用微信JS-SDK分享接口。详见接口权限说明文档。

开通微信认证需准备如下图所示材料,具体认证流程详见微信认证申请流程(企业类型)文档。

 

 微信分享网页时自定义缩略图和简介(.net版本)_第2张图片

 

 

步骤三:设置IP白名单。获取AppID和AppSecret。

通过左侧导航“开发”--“基本配置”进入。通过开发者ID及密码调用获取access_token接口时,需要设置访问来源IP为白名单。可将服务器ip、开发机ip、测试机ip都进行设置。

微信分享网页时自定义缩略图和简介(.net版本)_第3张图片

 

步骤四:配置JS接口安全域名。

通过左侧导航“设置”--“公众号设置”--“功能设置”进入。设置JS接口安全域名后,公众号开发者才可在该域名下调用微信开放的JS接口。具体设置步骤如下图所示。

微信分享网页时自定义缩略图和简介(.net版本)_第4张图片

 

 

步骤五:填写服务器配置。(可选)

通过左侧导航“开发”--“基本配置”进入。仅仅是为了实现分享功能的话,不是必填项,但为了实现其他功能(如回复消息),需进行配置。服务器配置是为了正确响应微信发送的Token验证等信息。详见入门指引文档中“1.4开发者基本配置”部分。

 微信分享网页时自定义缩略图和简介(.net版本)_第5张图片

 

 

  

第二部分 开发步骤

步骤1:通过公众号里的AppID和AppSecret获取access_token(接口调用凭据),并进行缓存(有效期为2小时)

公众平台以access_token为接口调用凭据,来调用接口,所有接口的调用需要先获取access_token,access_token在2小时内有效,过期需要重新获取,但1天内获取次数有限,开发者需自行存储,详见获取接口调用凭据(access_token)文档。

public static string GetAccess_token()
{
    string access_token = string.Empty;
    //从缓存获取
    string cacheName = "Weixin_access_token";
    object obj = CacheHelper.GetCache(cacheName);
    if (obj != null)
    {
        access_token = obj.ToString();
    }
    //从接口获取
    else
    {
        string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + AppID + "&secret=" + AppSecret;
        access_token = SubmitHttpWebRequest(url, "access_token");
        //设置缓存
        //7200秒内有效,不可无限次调取微信接口
        CacheHelper.SetCache(cacheName, access_token, 7200);
    }
    return access_token;
}

 

 步骤2:获取jsapi_ticket,并进行缓存(有效期为2小时)。jsapi_ticket是公众号用于调用微信JS接口的临时票据

public static string GetJsapi_Ticket()
{
    string jsapi_ticket = string.Empty;
    //从缓存获取
    string cacheName = "Weixin_jsapi_ticket";
    object obj = CacheHelper.GetCache(cacheName);
    if (obj != null)
    {
        jsapi_ticket = obj.ToString();
    }
    //从接口获取
    else
    {
        string access_token = GetAccess_token();
        string url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=" + access_token;
        jsapi_ticket = SubmitHttpWebRequest(url, "ticket");
        //设置缓存
        //7200秒内有效,不可无限次调取微信接口
        CacheHelper.SetCache(cacheName, jsapi_ticket, 7200);
    }
    return jsapi_ticket;
}

 

步骤3:生成JS-SDK权限验证的签名信息,并通过接口调用

签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。

public static string[] GetSignature(string url)
{
    //JSAPI调用凭证
    string jsapi_ticket = GetJsapi_Ticket();

    //随机生成的字符串
    string noncestr = CreateRandCode();

    //当前时间戳            
    TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0);
    string timestamp = ((Int64)ts.TotalSeconds).ToString();
    //string timestamp = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();//.net framework4.6

    //url
    if (url.IndexOf("#") > 0)
    {
        url = url.Substring(0, url.IndexOf("#"));
    }

    //签名
    StringBuilder string1 = new StringBuilder();
    string1.AppendFormat("jsapi_ticket={0}&noncestr={1}×tamp={2}&url={3}", jsapi_ticket, noncestr, timestamp, url);
    string signature = GetSHA1(string1.ToString());

    //返回相关信息
    string[] rtn = new string[] { AppID, noncestr, timestamp, signature };
    return rtn;
}

 通过接口调用(公众平台接口调用仅支持80端口。)

public class WeixinController : ApiController
{
    /// 
    /// 获取签名信息
    /// 
    /// 
    /// 
    [HttpGet]
    [AllowAnonymous]
    public WeixinSignatureConfig GetSignature(string url)
    {
        //微信配置
        string[] weixin = Tencent.WeixinConfig.GetSignature(url);
        WeixinSignatureConfig weixinConfig = new WeixinSignatureConfig
        {
            appId = weixin[0],
            nonceStr = weixin[1],
            timestamp = weixin[2],
            signature = weixin[3]
        };
        return weixinConfig;
    }
}

 

相关方法:

提交网络请求 SubmitHttpWebRequest(string url, string para = "")

private static string SubmitHttpWebRequest(string url, string para = "")
{
    string retString = string.Empty;

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "GET";
    request.ContentType = "application/json";
    request.Timeout = 10000;
    try
    {
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        string encoding = response.ContentEncoding;
        if (encoding == null || encoding.Length < 1)
        {
            encoding = "UTF-8"; //默认编码  
        }
        using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding)))
        {
            retString = reader.ReadToEnd();

            if (para != "")
            {
                JObject jsonObj = (JObject)JsonConvert.DeserializeObject(retString);
                if (jsonObj[para] != null)
                {
                    retString = jsonObj[para].ToString();
                }
            }
        }
    }
    catch (WebException ex)
    {
        retString = null;
    }
    return retString;
}
View Code

 

生成随机字符串CreateRandCode(int codeLen = 16)

public static string CreateRandCode(int codeLen = 16)
{
    string codeSerial = "2,3,4,5,6,7,a,c,d,e,f,h,i,j,k,m,n,p,r,s,t,A,C,D,E,F,G,H,J,K,M,N,P,Q,R,S,U,V,W,X,Y,Z";
    if (codeLen == 0)
    {
        codeLen = 16;
    }
    string[] arr = codeSerial.Split(',');
    string code = "";
    int randValue = -1;
    Random rand = new Random(unchecked((int)DateTime.Now.Ticks));
    for (int i = 0; i < codeLen; i++)
    {
        randValue = rand.Next(0, arr.Length - 1);
        code += arr[randValue];
    }
    return code;
}
View Code

 

SHA1加密GetSHA1(string string1)

private static string GetSHA1(string string1)
{
    SHA1 sha;
    ASCIIEncoding enc;
    string hash = "";
    sha = new SHA1CryptoServiceProvider();
    enc = new ASCIIEncoding();
    byte[] dataToHash = enc.GetBytes(string1);
    byte[] dataHashed = sha.ComputeHash(dataToHash);
    hash = BitConverter.ToString(dataHashed).Replace("-", "");
    hash = hash.ToLower();
    return hash;
}
View Code

 

缓存设置CacheHelper.cs

using System;
using System.Collections;
using System.Web;
using System.Web.Caching;

namespace WeixinShare
{
    /// 
    /// Caching 的摘要说明
    /// 
    public class CacheHelper
    {
        /// 
        /// 获取当前应用程序指定CacheKey的Cache值
        /// 
        /// 
        /// y
        public static object GetCache(string CacheKey)
        {
            System.Web.Caching.Cache objCache = HttpRuntime.Cache;
            return objCache[CacheKey];
        }

        /// 
        /// 设置当前应用程序指定CacheKey的Cache值
        /// 
        /// 
        /// 
        public static void SetCache(string CacheKey, object objObject)
        {
            System.Web.Caching.Cache objCache = HttpRuntime.Cache;
            objCache.Insert(CacheKey, objObject);
        }


        /// 
        /// 设置当前应用程序指定CacheKey的Cache值
        /// 
        /// 
        /// 
        public static void SetCache(string CacheKey, object objObject, DateTime absoluteExpiration, TimeSpan slidingExpiration)
        {
            System.Web.Caching.Cache objCache = HttpRuntime.Cache;
            objCache.Insert(CacheKey, objObject, null, absoluteExpiration, slidingExpiration);
        }

        ///   
        /// 设置数据缓存  
        ///  
        public static void SetCache(string CacheKey, object objObject, int timeout = 7200)
        {
            try
            {
                if (objObject == null) return;
                var objCache = HttpRuntime.Cache;
                //相对过期  
                //objCache.Insert(cacheKey, objObject, null, DateTime.MaxValue, timeout, CacheItemPriority.NotRemovable, null);  
                //绝对过期时间  
                objCache.Insert(CacheKey, objObject, null, DateTime.Now.AddSeconds(timeout), TimeSpan.Zero, CacheItemPriority.High, null);
            }
            catch (Exception)
            {
                //throw;  
            }
        }

        /// 
        /// 清除单一键缓存
        /// 
        /// 
        public static void RemoveKeyCache(string CacheKey)
        {
            try
            {
                System.Web.Caching.Cache objCache = HttpRuntime.Cache;
                objCache.Remove(CacheKey);
            }
            catch { }
        }

        ///// 
        ///// 清除所有缓存
        ///// 
        //public static void RemoveAllCache()
        //{
        //    System.Web.Caching.Cache _cache = HttpRuntime.Cache;
        //    IDictionaryEnumerator CacheEnum = _cache.GetEnumerator();
        //    if (_cache.Count > 0)
        //    {
        //        ArrayList al = new ArrayList();
        //        while (CacheEnum.MoveNext())
        //        {
        //            al.Add(CacheEnum.Key);
        //        }
        //        foreach (string key in al)
        //        {
        //            _cache.Remove(key);
        //        }
        //    }
        //}

        ///   
        /// 清除所有缓存
        ///   
        public static void RemoveAllCache()
        {
            var cache = HttpRuntime.Cache;
            var cacheEnum = cache.GetEnumerator();
            while (cacheEnum.MoveNext())
            {
                cache.Remove(cacheEnum.Key.ToString());
            }
        }

        /// 
        /// 以列表形式返回已存在的所有缓存 
        /// 
        ///  
        public static ArrayList ShowAllCache()
        {
            ArrayList al = new ArrayList();
            System.Web.Caching.Cache _cache = HttpRuntime.Cache;
            if (_cache.Count > 0)
            {
                IDictionaryEnumerator CacheEnum = _cache.GetEnumerator();
                while (CacheEnum.MoveNext())
                {
                    al.Add(CacheEnum.Key);
                }
            }
            return al;
        }
    }
}
View Code

 

Models,WeixinSignatureConfig

namespace WeixinShare.Models
{
    public class WeixinSignatureConfig
    {
        public string appId { get; set; }
        public string nonceStr { get; set; }
        public string timestamp { get; set; }
        public string signature { get; set; }
    }
}
View Code

 

步骤4:网页前端调用微信JSSDK

 

微信JS-SDK是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包。

 

通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。

 

@*微信分享接口*@


  方法封装:WeixinShare.js

function WeixinShare(title, desc, link, imgUrl, jsApiList) {
    $(document).ready(function () {
        //分享链接处理
        if (link.indexOf("#") > 0) {
            link = link.substring(0, link.indexOf("#"));
        }
        //通过Ajax获取签名信息,不影响主页面的加载逻辑
        $.ajax({
            url: "/apiaction/Weixin/GetSignature",
            data: "url=" + encodeURIComponent(link),
            type: "GET",
            dataType: "json",
            success: function (data) {
                //注入配置信息
                wx.config({
                    debug: false,// 开启调试模式,调用的所有api的返回值会在客户端alert出来
                    appId: data.appId,// 必填,公众号的唯一标识
                    timestamp: parseInt(data.timestamp),// 必填,生成签名的时间戳
                    nonceStr: data.nonceStr,// 必填,生成签名的随机串
                    signature: data.signature,// 必填,签名
                    jsApiList: ['updateAppMessageShareData', 'updateTimelineShareData']// 必填,需要使用的JS接口列表
                });

                //config验证成功后调用微信接口
                wx.ready(function () {
                    //分享给朋友
                    wx.updateAppMessageShareData({
                        title: title, desc: desc, link: link, imgUrl: imgUrl,
                        success: function () { }
                    });
                    //分享到朋友圈
                    wx.updateTimelineShareData({
                        title: title, desc: desc, link: link, imgUrl: imgUrl,
                        success: function () { }
                    });
                });
                wx.error(function (res) {
                    console.log(res);
                });
            }
        });
    });
}

 

 

完整代码下载:

   https://github.com/coolxiaoyi/WeixinShare-JSSDK

 

总结:

虽然是很简单的一个分享功能,但是步骤较多,涉及到公众号注册、认证、ip配置、域名配置,和获取凭证access_token、jsapi_ticket、SHA1加密算法、config验证等,再加上微信开发文档不够明了,所以大家在开发时会有各种困扰。现在将实现步骤整理出来,希望这篇文章能帮助到大家!

 

转载于:https://www.cnblogs.com/coolxiaoyi/p/11321736.html

你可能感兴趣的:(微信分享网页时自定义缩略图和简介(.net版本))