C# asp.net网页调用微信扫一扫 微信JS-API-JDK

前几天在需求的情况下需要开发一个网站,用户需要点击按钮调用微信中的扫一扫功能,扫描一个只有病案号的二维码,扫描到的结果自动填充至网页中的Text文本框中。

在思考之下,使用过很多开源的二维码识别,很难做到和微信一样的扫描功能(扫到二维码自动识别),于是开始研究如何调用微信APP中的扫一扫功能。

官方开发文档:概述 | 微信开放文档

个人理解:通过h5/aspx页面调用微信扫一扫是调用微信app中的jdk,扫一扫是微信jdk中其中一个功能,官方允许h5/aspx通过JavaScript调用微信中的jdk,但需要进行合法认证后方可调用。

微信官方是允许公众号和官方小程序调用jdk,网页开发是属于公众号开发。

整个过程:加载网页-》身份验证-》获取官方给出的jdk调用权限 -》使用网页触发器-》调用jdk。

身份验证和jdk的调用都是通过JavaScript进行的。

前提准备:

软件:

1、微信开发者工具 稳定版 Stable Build | 微信开放文档

用途:debug,查看微信wx.config发送与回复。

2、花生壳 花生壳-免费内网穿透软件|端口映射工具|DNS免费动态域名解析_花生壳,内网也能用-贝锐花生壳官网 (6元购买99年HTTP映射)

自己有域名的可以跳过,本人是因为没有域名,才使用花生壳将自己的内网访问ip映射为公网的域名。

用途:内网穿透,将IIS发布的局域网网站的ip位置映射为域名。

服务:

1、微信公众号 个人订阅号或企业服务号 

注册流程简单,自行百度即可注册。

用途:使用appid和secret获取微信JS-JDK调用权限。

2、SHA-1加密类库

用途:官方要求通过SHA-1生成签名。

开发过程:

一、项目建立

1、在visual studio中创建一个ASP.NET Web应用程序

2、 右击项目-》添加新项-》创建一个web窗体(使用C#语言 文件后缀为.aspx)

 3、在界面中拖放一个button按钮和Text文本框,按钮用来触发调用,文本框用来获取扫描结果。

二、在aspx网页头部写入js,引入官方js文件。

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

这里使用了一个偷懒的办法,直接通过网络请求js文件。

三、根据开发文档创建config注入,也在.aspx上部分。

<script>
    wx.config({
        debug: true,//是否开启调试模式 true会通过alert显示获取到的接口权限或报错
        appId: '<%=appid%>', //以下4个是通过.aspx.cs后端传入 
        timestamp: '<%=time%>',
        nonceStr:  '<%=randstr%>',
        signature: '<%=signstr%>',
        jsApiList: ['scanQRCode']//需要调用的权限,这里以扫一扫为例 只获取了扫一扫的接口名
    });
</script>

其他接口列表见:概述 | 微信开放文档

四、添加一个.cs类,用来处理获取config文件中所需要的appid、timestamp(时间戳)、nonceStr(随机字符串)、signature(签名)。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
public static string GetInfo(string link,string appid,string secret) //传入url请求地址
        {
            //使用appid何secret请求获得accesstoken
            string accesstoken = SendRequest("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret, Encoding.UTF8);

            //根据accesstoken获得ticket
            string url1 = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accesstoken.Substring(accesstoken.IndexOf(':') + 2, accesstoken.IndexOf(',') - 3 - accesstoken.IndexOf(':')) + "&type=jsapi";
            string requstStr = SendRequest(url1, Encoding.UTF8);//进行请求
            string ticket = requstStr.Substring(requstStr.IndexOf("ticket") + 9, requstStr.LastIndexOf(',') - 1 - requstStr.IndexOf("ticket") - 9);// 获得json参数 然后提出ticket

            /*下面是加密获取签名过程 signature
            参与签名的字段包括
            1、noncestr(随机字符串), 
            2、有效的jsapi_ticket, 
            3、timestamp(时间戳), 
            4、url(当前网页的URL,不包含#及其后面部分) 。
            对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。
                            noncestr=Wm3WZYTPz0wzccnW
                            jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
                            timestamp=1414587457
                            url=http://mp.weixin.qq.com?params=value

                jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
                &noncestr=Wm3WZYTPz0wzccnW
                &timestamp=1414587457
                &url=http://mp.weixin.qq.com?params=value
             
             */
            DateTime dti = DateTime.Now; //声明存放空间
            string dtime = dti.ToString("yyyy-MM-dd HH:mm:ss"); //获取时间
            string noncestr = dti.ToString("yyyyMMddHHmmss"); //获取随机字符串 这里是将时间作为随机字符串
            int timestamp = 1644481645;// 获取时间戳 这里网页转的当前时间 也可以直接用我的
            string timestampstr = "1644481645";
            noncestr = "20220212154406";//随机字符串 我是通过时间转的 自定义 可以直接用我的
            string string1 = "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + link;//拼接连接字符串
            string signature = SHA1(string1, Encoding.UTF8);//SHA-1加密过程 可以使用动态库 没有的直接用我的 方法在后面
            signature = signature.ToLower(); // 生成后转换小写
            //signature = "32ba4a26f1c06f7cd94531745513ac7f96dd9da3"; 这里是我获得的 最好去网上先找sha-1加密验证一下算法是否正确

            //返回 时间戳 、 加密字符串 、签名
            return timestampstr + "," + noncestr + "," + signature;

        }

        /// <summary>
        /// get方式获取请求结果
        /// </summary>
        /// <param name="url"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static string SendRequest(string url, Encoding encoding)
        {
            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
            webRequest.Method = "GET";
            HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
            StreamReader sr = new StreamReader(webResponse.GetResponseStream(), encoding);
            string str = sr.ReadToEnd();
            return str;
        }

        /// <summary>
        /// sha-1加密算法
        /// </summary>
        /// <param name="content"></param>
        /// <param name="encode"></param>
        /// <returns></returns>
        public static string SHA1(string content, Encoding encode)
        {
            try
            {
                SHA1 sha1 = new SHA1CryptoServiceProvider();
                byte[] bytes_in = encode.GetBytes(content);
                byte[] bytes_out = sha1.ComputeHash(bytes_in);
                sha1.Dispose();
                string result = BitConverter.ToString(bytes_out);
                result = result.Replace("-", "");
                return result;
            }
            catch (Exception ex)
            {
                throw new Exception("SHA1加密出错:" + ex.Message);
            }
        }

五、在.aspx.cs网页后端接受返回参数

        /// <summary>
        /// 先声明需要的三个返回js变量
        /// </summary>
        public string time = ""; //时间戳
        public string randstr = ""; //加密字符串
        public string signstr = ""; //签名
        public string appid = "appidappid这里写你自己公众号的"; //appid
        public string secret = "公众号中获取的"; //secret
        public string jsapi_ticket = "";

        protected void Page_Load(object sender, EventArgs e)
        {
            Response.Cache.SetNoStore();
            string[] str = vxHelper.GetInfo(this.Request.Url.ToString(),appid,secret).Split(',');
            time = str[0];
            randstr = str[1];
            signstr = str[2];
        }

注:如果这个时候显示报错,前端JavaScript提示没有找到声明的变量,就把错误都注释掉重新生成一下。

如果vxHelper显示错误,这里是刚才写的cs类,建立时候起了什么名字写什么就行。

六、调用 

本人是新建了JavaScript文件单独调用

wx.ready(function () {
    document.querySelector('#scanQRCode0').onclick = function () {
        wx.scanQRCode();
    };
    // 下面是扫描后返回结果 结果在res里
    document.querySelector('#scanQRCode1').onclick = function () {
        wx.scanQRCode({
            needResult: 1,
            desc: 'scanQRCode desc',
            success: function (res) {
                $("#txt1").textbox('setValue',res);
                alert(JSON.stringify(res));
            }
        });
    };

});

scanQRCode0和scanQRCode1是button的控件id,建议改一下button按钮的id。

部署过程:

这里以在本机部署为例,在服务器端部署差不多。

建议先测试后,并且将获取的token和签名存入数据库,在取出时先判断是否存在2小时,若超过2小时后token过期需要重新获取。

入库和取库过程根据自己习惯进行,这里不在赘述。

1、部署至本机IIS服务器,如不会自行百度。

设置aspx网页为默认文档,端口80如果被占用请换一个端口。

这里一定要选择局域网IP地址,方便使用花生壳映射。

2、内网穿透,打开花生壳APP

 添加如下映射:

 保存成功后点击此域名查看是否可以正常访问

 如果可以正常访问,打开公众号设置平台

(1)在公众号设置-》功能设置-》js接口安全域名中添加花生壳映射的域名地址

        不需要前面加"http://"

 (2)在基本配置中,把本机或者服务器的外网地址(不知道的百度“我的ip”可以看到)添加进ip白名单中:

测试使用:

使用微信打开域名,点击按钮,若在config配置中开启了debug模式,则会有弹窗显示成功与失败,若成功会显示已经获取到的js接口允许调用的列表。

如有错误使用微信开发者工具,选择公众号网页开发,输入域名进行debug调试。

 如果不需要弹窗正式上线的时候,记得把config中的debug改为false。

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gum.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值