微信 JSSDK .NET版

/*因为官方 微信 JSSDK 只有PHP java版本的 我自己照着PHP的翻译过来的,可供参考。欢迎指正*/
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()
        {
            string ticket = "";
            // jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例
            string path = HttpContext.Current.Server.MapPath(@"/jssdk/jsapi_ticket.json");

            //判断是否存在该文件 不存在就创建
            if (File.Exists(path)==false)
            {
                File.Create(path);//创建该文件
            }

            //读取文件       
          
            FileStream file = new FileStream(path, FileMode.Open);
          
            StreamReader reader = new StreamReader(file);
            string redstr= reader.ReadLine();        
            if (redstr==null||redstr == "")
            {
                file.Close();     

                string accessToken = getAccessToken();
                string url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=" + accessToken + "";

                Jsapi api = Desrialize(new Jsapi(), httpGet(url));
                ticket = api.ticket;

                if (ticket != "")
                {
                    JSTicket readJSTicket = new JSTicket();
                    readJSTicket.expire_time = ConvertDateTimeInt(DateTime.Now) + 7000;
                    readJSTicket.jsapi_ticket = ticket;

                    string json = Serialize(readJSTicket);
                    StreamWriterMetod(json, path);
                }
            }
            else
            {
                //var serializer = new DataContractJsonSerializer(typeof(JSTicket));
                // MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(redstr));
                // JSTicket readJSTicket = (JSTicket)serializer.ReadObject(stream);
               
                JSTicket readJSTicket = Desrialize(new JSTicket(), redstr);
                file.Close();    
 
                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(new Jsapi(), httpGet(url));
                    ticket = api.ticket;

                    if (ticket != "")
                    {
                        readJSTicket.expire_time = ConvertDateTimeInt(DateTime.Now) + 7000;
                        readJSTicket.jsapi_ticket = ticket;

                        string json = Serialize(readJSTicket);
                        StreamWriterMetod(json, path);
                    }
                }
                else
                {
                    ticket = readJSTicket.jsapi_ticket;
                }
                reader.Close();
            }         
          
          

            return ticket;
        }

        //得到accesstoken 如果文件里时间 超时则重新获取
        private string getAccessToken()
        {
            // access_token 应该全局存储与更新,以下代码以写入到文件中做示例

            string access_token = "";
            string path = HttpContext.Current.Server.MapPath(@"/jssdk/access_token.json");

            //判断是否存在该文件 不存在就创建
            if (File.Exists(path) == false)
            {
                File.Create(path);//创建该文件
            }

            //读取json文件内容
            FileStream file = new FileStream(path, FileMode.Open);
            StreamReader reader = new StreamReader(file);
            string redstr= reader.ReadLine();

            if (redstr == null || redstr == "")
            {
                reader.Close();
                file.Close();

                string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret + "";

                AccToken iden = Desrialize(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(iden);
                    StreamWriterMetod(json, path);
                }
            }
            else
            {

               
                //var serializer = new DataContractJsonSerializer(typeof(AccToken));
                //MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(redstr));
                //AccToken readJSTicket = (AccToken)serializer.ReadObject(stream);

                AccToken readJSTicket = Desrialize(new AccToken(), redstr);
               
                file.Close();
                reader.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(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(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;
        }

        /// 
        /// StreamWriter写入文件方法
        /// 
        private void StreamWriterMetod(string str, string patch)
        {
            try
            {
                FileStream fsFile = new FileStream(patch, FileMode.Create, FileAccess.Write);
                fsFile.Seek(0, SeekOrigin.Begin);
                fsFile.SetLength(0); //清空txt文件            

                StreamWriter swWriter = new StreamWriter(fsFile);                
                swWriter.WriteLine(str);
                swWriter.Close();
                fsFile.Close();
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        /// 
        /// 反序列化 字符串到对象
        /// 
        /// 泛型对象
        /// 要转换为对象的字符串
        /// 反序列化出来的对象
        public static T Desrialize(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);
            }

        }

        /// 
        /// 序列化 对象到字符串
        /// 
        /// 泛型对象
        /// 序列化后的字符串
        public static string Serialize(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);
            }
        }


        /// 
        /// 将c# DateTime时间格式转换为Unix时间戳格式
        /// 
        /// 时间
        /// double
        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;
        }
    }
}

 
  

 
 

你可能感兴趣的:(asp.net,mvc,asp.net)