using System; using System.Collections.Generic; using System.Web; using System.IO; using System.Security.Cryptography; using System.Runtime.Serialization.Json; using System.Runtime.Serialization; using System.Net; using System.Runtime.Serialization.Formatters.Binary; using System.Text; namespace WeixinJSSDJDemo { public class JSSDK { private string appId; private string appSecret; public JSSDK(string appId, string appSecret) { this.appId = appId; this.appSecret = appSecret; } //创建Json序列化 及反序列化类目 #region //创建JSon类 保存文件 jsapi_ticket.json [DataContract(Namespace = "http://coderzh.cnblogs.com")] class JSTicket { [DataMember(Order = 0)] public string jsapi_ticket { get; set; } [DataMember(Order = 1)] public double expire_time { get; set; } } //创建 JSon类 保存文件 access_token.json [DataContract(Namespace = "http://coderzh.cnblogs.com")] class AccToken { [DataMember(Order = 0)] public string access_token { get; set; } [DataMember(Order = 1)] public double expire_time { get; set; } } //创建从微信返回结果的一个类 用于获取ticket [DataContract(Namespace = "http://coderzh.cnblogs.com")] class Jsapi { [DataMember(Order = 0)] public int errcode { get; set; } [DataMember(Order = 1)] public string errmsg { get; set; } [DataMember(Order = 2)] public string ticket { get; set; } [DataMember(Order = 3)] public string expires_in { get; set; } } #endregion //得到数据包,返回使用页面 public System.Collections.Hashtable getSignPackage() { string jsapiTicket = getJsApiTicket(); string url = HttpContext.Current.Request.Url.ToString(); //"http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; string timestamp = Convert.ToString(ConvertDateTimeInt(DateTime.Now)); string nonceStr = createNonceStr(); // 这里参数的顺序要按照 key 值 ASCII 码升序排序 string rawstring = "jsapi_ticket=" + jsapiTicket + "&noncestr=" + nonceStr + "×tamp=" + timestamp + "&url=" + url + ""; string signature = SHA1_Hash(rawstring); System.Collections.Hashtable signPackage = new System.Collections.Hashtable(); signPackage.Add("appId", appId); signPackage.Add("nonceStr", nonceStr); signPackage.Add("timestamp", timestamp); signPackage.Add("url", url); signPackage.Add("signature", signature); signPackage.Add("rawString", rawstring); return signPackage; } //创建随机字符串 private string createNonceStr() { int length = 16; string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; string str = ""; Random rad = new Random(); for (int i = 0; i < length; i++) { str += chars.Substring(rad.Next(0, chars.Length - 1), 1); } return str; } //得到ticket 如果文件里时间 超时则重新获取 private string getJsApiTicket() { // jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例 string path = HttpContext.Current.Server.MapPath(@"~/jssdk/jsapi_ticket.json"); JSTicket readJSTicket = null; //读取文件 using (FileStream file = new FileStream(path, FileMode.Open)) { var serializer = new DataContractJsonSerializer(typeof(JSTicket)); try { readJSTicket = (JSTicket)serializer.ReadObject(file); } catch { } file.Close(); } string ticket = ""; if (readJSTicket == null || readJSTicket.expire_time < ConvertDateTimeInt(DateTime.Now)) { string accessToken = getAccessToken(); string url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=" + accessToken + ""; Jsapi api = Desrialize<Jsapi>(new Jsapi(), httpGet(url)); ticket = api.ticket; if (ticket != "") { if (readJSTicket == null) { readJSTicket = new JSTicket(); } readJSTicket.expire_time = ConvertDateTimeInt(DateTime.Now) + 7000; readJSTicket.jsapi_ticket = ticket; string json = Serialize<JSTicket>(readJSTicket); StreamWriterMetod(json, path); } } else { ticket = readJSTicket.jsapi_ticket; } return ticket; } //得到accesstoken 如果文件里时间 超时则重新获取 private string getAccessToken() { // access_token 应该全局存储与更新,以下代码以写入到文件中做示例 string access_token = ""; string path = HttpContext.Current.Server.MapPath(@"~/jssdk/access_token.json"); AccToken readJSTicket = null; using (FileStream file = new FileStream(path, FileMode.Open)) { var serializer = new DataContractJsonSerializer(typeof(AccToken)); try { readJSTicket = (AccToken)serializer.ReadObject(file); } catch { } file.Close(); } if (readJSTicket == null || readJSTicket.expire_time < ConvertDateTimeInt(DateTime.Now)) { string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret + ""; AccToken iden = Desrialize<AccToken>(new AccToken(), httpGet(url)); access_token = iden.access_token; if (access_token != "") { iden.expire_time = ConvertDateTimeInt(DateTime.Now) + 7000; iden.access_token = access_token; string json = Serialize<AccToken>(iden); StreamWriterMetod(json, path); } } else { access_token = readJSTicket.access_token; } return access_token; } //发起一个http请球,返回值 private string httpGet(string url) { try { WebClient MyWebClient = new WebClient(); MyWebClient.Credentials = CredentialCache.DefaultCredentials;//获取或设置用于向Internet资源的请求进行身份验证的网络凭据 Byte[] pageData = MyWebClient.DownloadData(url); //从指定网站下载数据 string pageHtml = System.Text.Encoding.Default.GetString(pageData); //如果获取网站页面采用的是GB2312,则使用这句 //string pageHtml = Encoding.UTF8.GetString(pageData); //如果获取网站页面采用的是UTF-8,则使用这句 return pageHtml; } catch (WebException webEx) { Console.WriteLine(webEx.Message.ToString()); return null; } } //SHA1哈希加密算法 public string SHA1_Hash(string str_sha1_in) { SHA1 sha1 = new SHA1CryptoServiceProvider(); byte[] bytes_sha1_in = System.Text.UTF8Encoding.Default.GetBytes(str_sha1_in); byte[] bytes_sha1_out = sha1.ComputeHash(bytes_sha1_in); string str_sha1_out = BitConverter.ToString(bytes_sha1_out); str_sha1_out = str_sha1_out.Replace("-", "").ToLower(); return str_sha1_out; } /// <summary> /// StreamWriter写入文件方法 /// </summary> private void StreamWriterMetod(string str, string patch) { try { FileStream fsFile = new FileStream(patch, FileMode.OpenOrCreate); StreamWriter swWriter = new StreamWriter(fsFile); //寫入數據 swWriter.WriteLine(str); swWriter.Close(); } catch (Exception e) { throw e; } } /// <summary> /// 反序列化 字符串到对象 /// </summary> /// <param name="obj">泛型对象</param> /// <param name="str">要转换为对象的字符串</param> /// <returns>反序列化出来的对象</returns> public static T Desrialize<T>(T obj, string str) { try { var mStream = new MemoryStream(Encoding.Default.GetBytes(str)); var serializer = new DataContractJsonSerializer(typeof(T)); T readT = (T)serializer.ReadObject(mStream); return readT; } catch (Exception ex) { return default(T); throw new Exception("反序列化失败,原因:" + ex.Message); } } /// <summary> /// 序列化 对象到字符串 /// </summary> /// <param name="obj">泛型对象</param> /// <returns>序列化后的字符串</returns> public static string Serialize<T>(T obj) { try { var serializer = new DataContractJsonSerializer(typeof(T)); var stream = new MemoryStream(); serializer.WriteObject(stream, obj); byte[] dataBytes = new byte[stream.Length]; stream.Position = 0; stream.Read(dataBytes, 0, (int)stream.Length); string dataString = Encoding.UTF8.GetString(dataBytes); return dataString; } catch (Exception ex) { return null; throw new Exception("序列化失败,原因:" + ex.Message); } } /// <summary> /// 将c# DateTime时间格式转换为Unix时间戳格式 /// </summary> /// <param name="time">时间</param> /// <returns>double</returns> public int ConvertDateTimeInt(System.DateTime time) { int intResult = 0; System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); intResult = Convert.ToInt32((time - startTime).TotalSeconds); return intResult; } } }
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WeixinJSSDJDemo { public partial class Index : System.Web.UI.Page { protected static string AppId = ""; private JSSDK _helper = new JSSDK(AppId, ""); private Hashtable _result = null; protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { _result = _helper.getSignPackage(); } } protected string Timestamp { get { //TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); //return Convert.ToInt64(ts.TotalSeconds); return _result["timestamp"].ToString(); } } protected string NonceStr { get { //Random random = new Random(); //return GetMD5Hash(random.Next(1000).ToString()); return _result["nonceStr"].ToString(); } } protected string Signature { get { //return GetMD5Hash(Timestamp.ToString()).ToUpper(); return _result["signature"].ToString(); } } public static string GetMD5Hash(string value) { MD5 md5 = new MD5CryptoServiceProvider(); byte[] hashByte = md5.ComputeHash(Encoding.Default.GetBytes(value)); StringBuilder sb = new StringBuilder(); foreach (byte b in hashByte) { sb.Append(b.ToString("x").PadLeft(2, '0')); } return sb.ToString(); } } }
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="WeixinJSSDJDemo.Index" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <script src="Scripts/jquery-1.8.2.min.js"></script> <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> <style> div { margin-top: 50px; } </style> </head> <body> <form id="form1" runat="server"> <div> <a href="javascript:void(0)" onclick="ksly();">开始录音</a> </div> <div> <a href="javascript:void(0)" onclick="tzly();">停止录音</a> </div> <div> <a href="javascript:void(0)" onclick="bfly();">播放录音</a> </div> <div> <a href="javascript:void(0)" onclick="scly();">上传录音</a> </div> <div> <a href="javascript:void(0)" onclick="pz();">拍照或从手机相册中选图接口</a> </div> <div> <a href="javascript:void(0)" onclick="hqwlzt();">获取网络状态接口</a> </div> <div> <select id="selZb"> <option value="wgs84">wgs84的gps坐标</option> <option value="gcj02">火星坐标</option> </select> <a href="javascript:void(0)" onclick="hqdlwz();">获取地理位置接口</a> </div> <div> <a href="javascript:void(0)" onclick="wxsys();">调起微信扫一扫接口</a> </div> <div> <a href="javascript:void(0)" onclick="ycysjcd();">隐藏右上角菜单接口</a> </div> </form> </body> </html> <script> wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: '<%=AppId%>', // 必填,公众号的唯一标识 timestamp: '<%=Timestamp%>', // 必填,生成签名的时间戳 nonceStr: '<%=NonceStr%>', // 必填,生成签名的随机串 signature: '<%=Signature%>',// 必填,签名 jsApiList: [ "checkJsApi", 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'hideMenuItems', 'showMenuItems', 'hideAllNonBaseMenuItem', 'showAllNonBaseMenuItem', 'translateVoice', 'startRecord', 'stopRecord', 'onRecordEnd', 'playVoice', 'pauseVoice', 'stopVoice', 'uploadVoice', 'downloadVoice', 'chooseImage', 'previewImage', 'uploadImage', 'downloadImage', 'getNetworkType', 'openLocation', 'getLocation', 'hideOptionMenu', 'showOptionMenu', 'closeWindow', 'scanQRCode', 'chooseWXPay', 'openProductSpecificView', 'addCard', 'chooseCard', 'openCard' ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2。详见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html }); wx.error(function (res) { console.log(res); alert('验证失败'); }); wx.ready(function () { var url = 'http://szumxk.szum.gov.cn'; var link = url + '/<%=Request.Url.PathAndQuery%>'; var imgUrl = url + '/XZXK/img/upload.gif'; //转发到朋友圈 wx.onMenuShareTimeline({ title: 'JSSDK朋友圈转发测试', link: link, imgUrl: imgUrl, success: function () { alert('转发成功!'); }, cancel: function () { alert('转发失败!'); } }); //转发给朋友 wx.onMenuShareAppMessage({ title: 'JSSDK朋友圈转发测试', desc: '转发给朋友', link: link, imgUrl: imgUrl, type: 'link', dataUrl: '', success: function () { alert('转发成功!'); }, cancel: function () { alert('转发失败!'); } }); }); function fxpyq() { } var localId = ""; function ksly() { wx.startRecord(); } function tzly() { wx.stopRecord({ success: function (res) { localId = res.localId; } }); } function bfly() { if (localId != "") { wx.playVoice({ localId: localId // 需要播放的音频的本地ID,由stopRecord接口获得 }); } else { alert("没有录音localId"); } } var localIds = ""; function pz() { wx.chooseImage({ count:3, // 默认9 sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有 sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有 success: function (res) { localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片 alert(localIds); } }); } function hqwlzt() { wx.getNetworkType({ success: function (res) { var networkType = res.networkType; // 返回网络类型2g,3g,4g,wifi alert(networkType); } }); } function hqdlwz() { wx.getLocation({ type: $("#selZb").val(), // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02' success: function (res) { var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90 var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。 var speed = res.speed; // 速度,以米/每秒计 var accuracy = res.accuracy; // 位置精度 wx.openLocation({ latitude: latitude, // 纬度,浮点数,范围为90 ~ -90 longitude: longitude, // 经度,浮点数,范围为180 ~ -180。 name: 'wilson 测试位置名', // 位置名 address: '当前办公地址', // 地址详情说明 scale: 28, // 地图缩放级别,整形值,范围从1~28。默认为最大 infoUrl: 'http://weiweictgu.cnblogs.com/' // 在查看位置界面底部显示的超链接,可点击跳转 }); } }); } function wxsys() { wx.scanQRCode({ needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果, scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有 success: function (res) { var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果 alert("扫描结果为:"+result); } }); } function scly() { if (localId != "") { wx.uploadVoice({ localId: localId, // 需要上传的音频的本地ID,由stopRecord接口获得 isShowProgressTips: 1, // 默认为1,显示进度提示 success: function (res) { var serverId = res.serverId; // 返回音频的服务器端ID alert("上传成功,服务器id:" + serverId); } }); } else { alert("没有录音localId"); } } function ycysjcd() { wx.hideOptionMenu(); } </script>