/*由於官方 微信 JSSDK 只有PHP java版本的 我本身照着PHP的翻譯過來的,可供參考。歡迎指正*/ [csharp] view plaincopy在CODE上查看代碼片派生到個人代碼片 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 JSSDK.Models { 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"); //讀取文件 FileStream file = new FileStream(path, FileMode.Open); var serializer = new DataContractJsonSerializer(typeof(JSTicket)); JSTicket readJSTicket = (JSTicket)serializer.ReadObject(file); file.Close(); string ticket = ""; if (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 != "") { 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"); FileStream file = new FileStream(path, FileMode.Open); var serializer = new DataContractJsonSerializer(typeof(AccToken)); AccToken readJSTicket = (AccToken)serializer.ReadObject(file); file.Close(); if (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; } } }