写在前面的
首先在调用微信的JS-SDK接口的时候需要仔细阅读一下官方的注意事项,否则可能事倍功半。这里先大概概述一下主要的流程,首先,使用微信扫一扫需要一个已经通过认证的公众号;其次,需要知道公众号的APPID以及APPSecrect,以便获取Access_Token和Ticket;再有就是需要了解.NET内部的SHA1的加密类;最后引用官方的JS,就可以了。
VIEW代码
需要注意的是,公众号一定要有域名绑定
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> <script src="http://res.wx.qq.com/open/js/jweixin-1.1.0.js"> </script> <script src="http://libs.baidu.com/jquery/2.0.0/jquery.js"></script> <script src="~/Script/WxScanQRCode.js"></script> <script> wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: '@ViewBag.appid', // 必填,公众号的唯一标识 timestamp: '@ViewBag.timestamp', // 必填,生成签名的时间戳 nonceStr: '@ViewBag.noncestr', // 必填,生成签名的随机串 signature: '@ViewBag.sinature',// 必填,签名 jsApiList: ['checkJsApi', //这里的接口在官方文档中都有涉及,我们只需要调用微信扫一扫即可 //'chooseImage', //'previewImage', // 'uploadImage', // 'downloadImage', // 'getNetworkType',//网络状态接口 // 'openLocation',//使用微信内置地图查看地理位置接口 // 'getLocation', //获取地理位置接口 // 'hideOptionMenu',//界面操作接口1 // 'showOptionMenu',//界面操作接口2 // 'closeWindow', 界面操作接口3 // 'hideMenuItems',界面操作接口4 // 'showMenuItems',界面操作接口5 // 'hideAllNonBaseMenuItem',界面操作接口6 // 'showAllNonBaseMenuItem',界面操作接口7 'scanQRCode'// 微信扫一扫接口 ] }); <!--开始扫描--> function scan(){ wx.ready(function () { var _scan = document.getElementById("url"); _scan.value = window.location.href; wx.scanQRCode({ needResult: 1, desc: 'scanQRCode desc', success: function (res) { alert(JSON.stringify(res)); } }); }) } </script> </head> <body> <div> <input type="text" name ="url" id="url"> <button id="scanbutton" type="button" οnclick="scan()">click here to scan</button> </div> </body> </html>
Controller代码
首先,我们需要根据APPID和APPSecrect来获取Access_Token,之后根据AccessToken来获取jsapi_ticket。最后,在Controller内部生成时间戳,随机字符串,之后将ticket以及前两者根据SHA1加密成签名,并发送给微信服务器,通过认证之后,这样就可以调用扫一扫的接口了。
public ActionResult Index() { //获取ACCESS_TOKEN string _url = Request.Url.ToString(); //获取Ticket string _ticket = Requestjsapi_ticket(Request_Url()); //获取ticket string _finalticket = _ticket; //获取noncestr string _noncestr = CreatenNonce_str(); //获取timestamp long _timestamp = CreatenTimestamp(); //获取sinature string _sinature = GetSignature(_finalticket, _noncestr, _timestamp, _url).ToLower(); ViewBag.appid = "这里填写你的APPID"; ViewBag.timestamp = _timestamp; ViewBag.noncestr = _noncestr; ViewBag.sinature = _sinature; return View(); } //获取AccessToken public static string Request_Url() { // 设置参数 string _appid = "这里写入你的APPID"; string _appsecret = "这里写入你的APPSecrect"; string _url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + _appid + "&secret=" + _appsecret; string method = "GET"; HttpWebRequest request = WebRequest.Create(_url) as HttpWebRequest; CookieContainer cookieContainer = new CookieContainer(); request.CookieContainer = cookieContainer; request.AllowAutoRedirect = true; request.Method = method; request.ContentType = "text/html"; request.Headers.Add("charset", "utf-8"); //发送请求并获取相应回应数据 HttpWebResponse response = request.GetResponse() as HttpWebResponse; //直到request.GetResponse()程序才开始向目标网页发送Post请求 Stream responseStream = response.GetResponseStream(); StreamReader sr = new StreamReader(responseStream, Encoding.UTF8); //返回结果网页(html)代码 string content = sr.ReadToEnd(); //由于微信服务器返回的JSON串中包含了很多信息,我们只需要将AccessToken获取就可以了,需要将JSON拆分 String[] str = content.Split('"'); content = str[3]; return content; } //根据AccessToken来获取jsapi_ticket public static string Requestjsapi_ticket(string accesstoken) { string _accesstoken = accesstoken; string url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + _accesstoken + "&type=jsapi"; string method = "GET"; HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; CookieContainer cookieContainer = new CookieContainer(); request.CookieContainer = cookieContainer; request.AllowAutoRedirect = true; request.Method = method; request.ContentType = "text/html"; request.Headers.Add("charset", "utf-8"); //发送请求并获取相应回应数据 HttpWebResponse response = request.GetResponse() as HttpWebResponse; //直到request.GetResponse()程序才开始向目标网页发送Post请求 Stream responseStream = response.GetResponseStream(); StreamReader sr = new StreamReader(responseStream, Encoding.UTF8); //返回结果网页(html)代码 string content = sr.ReadToEnd(); //同样,返回的JSON中只要取出ticket的信息即可 String[] str = content.Split('"'); content = str[9]; return content; } //接下来就是辅助工具类,生成随机字符串 #region 字符串随机 CreatenNonce_str() private static string[] strs = new string[] { "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z", "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z" }; public static string CreatenNonce_str() { Random r = new Random(); var sb = new StringBuilder(); var length = strs.Length; for (int i = 0; i < 15; i++) { sb.Append(strs[r.Next(length - 1)]); } return sb.ToString(); } #endregion //生成时间戳,备用 #region 时间戳生成 CreatenTimestamp() public static long CreatenTimestamp() { return (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000; } #endregion //获取签名,这里的三个参数分别为前面生成的ticket,随机字符串以及时间戳 #region 获取签名 GetSignature() public static string GetSignature(string jsapi_ticket, string noncestr, long timestamp,string url) { var string1Builder = new StringBuilder(); string1Builder.Append("jsapi_ticket=").Append(jsapi_ticket).Append("&") .Append("noncestr=").Append(noncestr).Append("&") .Append("timestamp=").Append(timestamp).Append("&") .Append("url=").Append(url.IndexOf("#") >= 0 ? url.Substring(0, url.IndexOf("#")) : url); return SHA1(string1Builder.ToString()); } #endregion //最后就是SHA1的加密算法工具 #region 加密签名算法 SHA1(content) //加密签名算法 public static string SHA1(string content) { return SHA1(content, Encoding.UTF8); } //加密签名 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); } } #endregion
总结
代码复制即可使用,需要注意的还是公众号的认证,域名的绑定,以及最后加密算法生成的字符串的正确性,少了哪一步,我们都不会得到一个正确的返回结果。
转载:https://blog.csdn.net/SugaryoTT/article/details/78558105