当前位置:   article > 正文

C# 实现微信自定义分享

C# 实现微信自定义分享

目录

需求与调整

代码实现

获取令牌

生成合法票据

获取有效签名

客户端准备 

客户端实现

小结


需求与调整

在微信中打开网页应用后,可以选择将地址发送给朋友进行分享,如下图:

00e06d4028864c45b1c654a0ac2157c6.png

92c55e7e8c2941cbbc927f46ed6a7228.png

在实际的应用中,我们可能不是简单的将该网页的链接直接分享出去,而是生成符合实际需要的URL,微信称其为自定义分享。意思即,在用户点击“转发给朋友”按钮之前,进行URL等内容的更新 ,经过调整后,再把链接发送给要分享的朋友。微信给出的关键方法是:updateAppMessageShareData。

需要注意的是:

最好不要再使用 wx.onMenuShareTimeline、wx.onMenuShareAppMessage、wx.onMenuShareQQ、wx.onMenuShareQZone 接口,请尽快迁移使用客户端6.7.2及JSSDK 1.4.0以上版本而支持 wx.updateAppMessageShareData、wx.updateTimelineShareData接口。

代码实现

获取令牌

获取令牌是调用API的基础,请提供合法的APPID和APPSECRET,示例代码如下:

  1. public string GetAccessToken()
  2. {
  3. string accessToken = "";
  4. //获取配置信息Datatable
  5. string respText = "";
  6. //获取appid和appsercret
  7. string wechat_appid = "";
  8. string wechat_appsecret = "";
  9. //获取josn数据
  10. string getAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";
  11. string url = string.Format(getAccessTokenUrl, wechat_appid, wechat_appsecret);
  12. HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
  13. HttpWebResponse response = (HttpWebResponse)request.GetResponse();
  14. using (Stream resStream = response.GetResponseStream())
  15. {
  16. StreamReader reader = new StreamReader(resStream, Encoding.Default);
  17. respText = reader.ReadToEnd();
  18. resStream.Close();
  19. }
  20. JavaScriptSerializer Jss = new JavaScriptSerializer();
  21. Dictionary<string, object> respDic = (Dictionary<string, object>)Jss.DeserializeObject(respText);
  22. //通过键access_token获取值
  23. try
  24. {
  25. accessToken = respDic["access_token"].ToString();
  26. }
  27. catch (Exception e)
  28. {
  29. accessToken =e.Message;
  30. }
  31. return accessToken;
  32. }

生成合法票据

正式调用前需要生成合法的票据,C#示例代码如下:

  1. public string getJsapi_ticket(string accessToken)
  2. {
  3. string content = "";
  4. try
  5. {
  6. string url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accessToken + "&type=jsapi";
  7. string method = "GET";
  8. HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
  9. CookieContainer cookieContainer = new CookieContainer();
  10. request.CookieContainer = cookieContainer;
  11. request.AllowAutoRedirect = true;
  12. request.Method = method;
  13. request.ContentType = "text/html";
  14. request.Headers.Add("charset", "utf-8");
  15. //发送请求并获取响应数据
  16. HttpWebResponse response = request.GetResponse() as HttpWebResponse;
  17. Stream responseStream = response.GetResponseStream();
  18. StreamReader sr = new StreamReader(responseStream, Encoding.UTF8);
  19. //获取返回过来的结果
  20. content = sr.ReadToEnd();
  21. dynamic resultStr = JsonConvert.DeserializeObject(content, new { errcode = "", errmsg = "", ticket = "", expires_in = "" }.GetType());
  22. //请求成功
  23. if (resultStr.errcode == "0" && resultStr.errmsg == "ok")
  24. {
  25. content = resultStr.ticket;
  26. }
  27. else
  28. {
  29. content = "";
  30. }
  31. return content;
  32. }
  33. catch (Exception ex)
  34. {
  35. content = ex.Message;
  36. return content;
  37. }
  38. }

获取有效签名

通过获取成功的票据信息,生成有效签名后,就可以在客户端进行调用及分享了,示例代码如下:

  1. public static string GetMD5(string encypStr, string charset)
  2. {
  3. string retStr;
  4. MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider();
  5. //创建md5对象
  6. byte[] inputBye;
  7. byte[] outputBye;
  8. //使用GB2312编码方式把字符串转化为字节数组.
  9. try
  10. {
  11. inputBye = Encoding.GetEncoding(charset).GetBytes(encypStr);
  12. }
  13. catch (Exception ex)
  14. {
  15. inputBye = Encoding.GetEncoding("GB2312").GetBytes(encypStr);
  16. }
  17. outputBye = m5.ComputeHash(inputBye);
  18. retStr = System.BitConverter.ToString(outputBye);
  19. retStr = retStr.Replace("-", "").ToUpper();
  20. return retStr;
  21. }
  22. /// <summary>
  23. /// 随机串
  24. /// </summary>
  25. public string getNoncestr()
  26. {
  27. Random random = new Random();
  28. return GetMD5(random.Next(1000).ToString(), "GBK").ToLower().Replace("s", "S");
  29. }
  30. /// <summary>
  31. /// 时间截,自1970年以来的秒数
  32. /// </summary>
  33. public string getTimestamp()
  34. {
  35. TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
  36. return Convert.ToInt64(ts.TotalSeconds).ToString();
  37. }
  38. /// <summary>
  39. /// 签名加密,使用SHA加密所得
  40. /// </summary>
  41. /// <param name="content">签名加密参数</param>
  42. /// <param name="encode">编码UTF-8</param>
  43. /// <returns></returns>
  44. public string Sha1(string content, Encoding encode)
  45. {
  46. try
  47. {
  48. SHA1 sha1 = new SHA1CryptoServiceProvider();
  49. byte[] bytesIn = encode.GetBytes(content);
  50. byte[] bytesOut = sha1.ComputeHash(bytesIn);
  51. sha1.Dispose();
  52. string result = BitConverter.ToString(bytesOut);
  53. result = result.Replace("-", "");
  54. return result;
  55. }
  56. catch (Exception ex)
  57. {
  58. throw new Exception("SHA1加密出错:" + ex.Message);
  59. }
  60. }
  61. /// <summary>
  62. /// 获取签名
  63. /// </summary>
  64. /// <param name="jsapi_ticket">微信公众号调用微信JS临时票据</param>
  65. /// <param name="nonceStr">随机串</param>
  66. /// <param name="timestamp">时间戳</param>
  67. /// <param name="url">当前网页URL</param>
  68. /// <returns></returns>
  69. public string GetSignature(string jsapi_ticket, string nonceStr, long timestamp, string url)
  70. {
  71. var string1Builder = new StringBuilder();
  72. //注意这里参数名必须全部小写,且必须有序
  73. string1Builder.Append("jsapi_ticket=").Append(jsapi_ticket).Append("&")
  74. .Append("noncestr=").Append(nonceStr).Append("&")
  75. .Append("timestamp=").Append(timestamp).Append("&")
  76. .Append("url=").Append(url.IndexOf("#") >= 0 ? url.Substring(0, url.IndexOf("#")) : url);
  77. return Sha1(string1Builder.ToString(), Encoding.UTF8);
  78. }

客户端准备 

我们通过准备 ViewState 传递到客户端,示例代码如下:

  1. string at=GetAccessToken();
  2. string ticket = getJsapi_ticket(at);
  3. string nonceStr = getNoncestr();
  4. string timestamp = getTimestamp();
  5. string currentWebUrl = Request.Url.ToString() ;
  6. string sign = GetSignature(ticket, nonceStr, Int64.Parse(timestamp), currentWebUrl);
  7. ViewState["ticket"] = ticket;
  8. ViewState["nonceStr"] = nonceStr;
  9. ViewState["timestamp"] = timestamp;
  10. ViewState["url"] = currentWebUrl;
  11. ViewState["sign"] = sign;

客户端实现

首先需要引用腾讯JS包,如下:

<script src="https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

后续我们将进行初始化配置,如下代码:

  1. wx.config({
  2. debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
  3. appId: '', // 必填,公众号的唯一标识
  4. timestamp:<%=ViewState["timestamp"]%> , // 必填,生成签名的时间戳
  5. nonceStr:'<%=ViewState["nonceStr"]%>', // 必填,生成签名的随机串
  6. signature:'<%=ViewState["sign"]%>',// 必填,签名
  7. jsApiList:['updateAppMessageShareData','updateTimelineShareData','onMenuShareAppMessage', 'onMenuShareTimeline' ]
  8. });

最后定义自定义分享函数 shareUrl ,如下代码:

  1. //自定义分享
  2. //分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
  3. function shareUrl(title,link,desc,imgUrl){
  4. var desc = document.getElementById('x_shareDesc').value;
  5. var imgUrl ="";
  6. wx.updateAppMessageShareData({
  7. title: title, // 分享标题
  8. desc: desc, // 分享描述
  9. link: link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
  10. imgUrl: imgUrl , // 分享图标
  11. success: function () {
  12. // alert("更新分享地址:"+link+" 信息成功");
  13. },
  14. fail: function () {
  15. // alert("分享fail");
  16. }
  17. })
  18. }
  19. //关键方法调用
  20. wx.ready(function(){
  21. shareUrl();
  22. });

小结

使用微信JSSDK需要登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。

另外为保障稳定性,引入的JS最好使用:http://res2.wx.qq.com/open/js/jweixin-1.6.0.js (支持https)。

目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复。

信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。

error接口可处理失败验证,如下所示:

  1. wx.error(function(res){
  2.   // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
  3. });

更多的开发细节请参考 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html

再次感谢您的阅读,请大家多评论指正。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/80708
推荐阅读
相关标签
  

闽ICP备14008679号