C# 微信JSSDK 获取配置信息

本内容部分内容是搬运来,并个人稍加改良完成。

/// <summary>
    /// 微信JSSDK基础信息
    /// </summary>
    public class WechatJSSDKController : ApiController
    {
        private static string appid = ConfigurationManager.AppSettings["appID"];
        private static string appsecret = ConfigurationManager.AppSettings["appsecret"];

        /// <summary>
        /// 获取微信配置基础信息
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public WXShare GetWxShareInfo()
        {
            var context = HttpContext.Current;
            string url = Common.ObjectToString(context.Request["url"]);
            DateTime now = DateTime.Now;
            var timestamp = GetTimeStamp(now);//取十位时间戳
            var guid = Guid.NewGuid().ToString("N");//随机串
            var ticket = "";//签名密钥
            try
            {
                WXShare s = new WXShare();
                //取缓存中的Ticket,没有则重新生成Ticket值(也可以将Ticket值保存到文件中,此时从文件中读取Ticket)
                var Cache = CacheHelper.GetCache("ticket");
                if (Cache == null) CacheHelper.SetCache("ticket", GetTicket(), 7000);
                ticket = CacheHelper.GetCache("ticket").ToString();

                url = HttpUtility.UrlDecode(url);//url解码
                string sign = GetSignature(ticket, guid, timestamp, url);
                s.appid = appid;
                s.noncestr = guid;
                s.timestamp = timestamp;
                s.signature = sign;
                //logger.Warn($"url:{url},时间戳:{timestamp},随机数:{guid},ticket:{ticket},sign值:{sign}");//记录日志
                return s;
            }
            catch (Exception ex)
            {
                //logger.Warn(ex);
                throw ex;
            }
        }


        /// <summary>
        /// GetTicket 签名密钥
        /// </summary>
        /// <returns></returns>
        public static string GetTicket()
        {
            string token = "";
            var Cache = CacheHelper.GetCache("token");
            if (Cache == null) CacheHelper.SetCache("token", GetAccessToken(), 7000);//获取AccessToken            
            token = CacheHelper.GetCache("token").ToString();
            IDictionary<string, string> dic = new Dictionary<string, string>();
            dic["access_token"] = token;
            dic["type"] = "jsapi";
            FormUrlEncodedContent content = new FormUrlEncodedContent(dic);
            var response = Client.PostAsync("https://api.weixin.qq.com/cgi-bin/ticket/getticket", content).Result;
            if (response.StatusCode != HttpStatusCode.OK)
                return "";
            var result = response.Content.ReadAsStringAsync().Result;
            JObject obj = JObject.Parse(result);
            string ticket = obj["ticket"]?.ToString() ?? "";
            return ticket;
        }

        /// <summary>
        /// GetAccessToken
        /// </summary>
        /// <returns></returns>
        public static string GetAccessToken()
        {
            IDictionary<string, string> dic = new Dictionary<string, string>();
            dic["grant_type"] = "client_credential";
            dic["appid"] = appid;//自己的appid
            dic["secret"] = appsecret;//自己的appsecret
            FormUrlEncodedContent content = new FormUrlEncodedContent(dic);
            var response = Client.PostAsync("https://api.weixin.qq.com/cgi-bin/token", content).Result;
            if (response.StatusCode != HttpStatusCode.OK)
                return "";
            var result = response.Content.ReadAsStringAsync().Result;
            JObject obj = JObject.Parse(result);
            string token = obj["access_token"]?.ToString() ?? "";
            return token;
        }

        /// <summary>
        /// 签名算法
        /// </summary>
        /// <param name="ticket">ticket</param>
        /// <param name="noncestr">随机字符串</param>
        /// <param name="timestamp">时间戳</param>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string GetSignature(string ticket, string noncestr, long timestamp, string url)
        {
            var string1Builder = new StringBuilder();
            //拼接字符串
            string1Builder.Append("jsapi_ticket=").Append(ticket).Append("&")
                          .Append("noncestr=").Append(noncestr).Append("&")
                          .Append("timestamp=").Append(timestamp).Append("&")
                          .Append("url=").Append(url.IndexOf("#") >= 0 ? url.Substring(0, url.IndexOf("#")) : url);
            string str = string1Builder.ToString();
            return SHA1(str);//加密
        }

        public static string SHA1(string content)
        {
            return SHA1(content, Encoding.UTF8);
        }
        /// <summary>
        /// SHA1 加密
        /// </summary>
        /// <param name="content">需要加密字符串</param>
        /// <param name="encode">指定加密编码</param>
        /// <returns>返回40位小写字符串</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("-", "").ToLower();//转小写
                return result;
            }
            catch (Exception ex)
            {
                throw new Exception("SHA1加密出错:" + ex.Message);
            }
        }


        //请求基类
        private static HttpClient _client = null;
        public static HttpClient Client
        {
            get
            {
                if (_client == null)
                {
                    var handler = new HttpClientHandler()
                    {
                        AutomaticDecompression = DecompressionMethods.GZip,
                        AllowAutoRedirect = false,
                        UseCookies = false,
                    };
                    _client = new HttpClient(handler);
                    _client.Timeout = TimeSpan.FromSeconds(5);
                    _client.DefaultRequestHeaders.Add("Accept", "application/json");
                }
                return _client;
            }
        }

        /// <summary>
        /// 十位时间戳
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static int GetTimeStamp(DateTime dt)
        {
            DateTime dateStart = new DateTime(1970, 1, 1, 8, 0, 0);
            int timeStamp = Convert.ToInt32((dt - dateStart).TotalSeconds);
            return timeStamp;
        }


        /// <summary>
        /// 返回实体
        /// </summary>
        public class WXShare
        {
            public string appid { get; set; }
            /// <summary>
            /// 随机码
            /// </summary>
            public string noncestr { get; set; }
            /// <summary>
            /// 时间戳
            /// </summary>
            public int timestamp { get; set; }
            /// <summary>
            /// 签名值
            /// </summary>
            public string signature { get; set; }
        }

        public class CacheHelper
        {
            /// <summary>  
            /// 获取数据缓存  
            /// </summary>  
            /// <param name="cacheKey"></param>  
            public static object GetCache(string cacheKey)
            {
                var objCache = HttpRuntime.Cache.Get(cacheKey);
                return objCache;
            }
            /// <summary>  
            /// 设置数据缓存  
            /// </summary>  
            public static void SetCache(string cacheKey, object objObject)
            {
                var objCache = HttpRuntime.Cache;
                objCache.Insert(cacheKey, objObject);
            }
            /// <summary>  
            /// 设置数据缓存  
            /// </summary>  
            public static void SetCache(string cacheKey, object objObject, int timeout = 7200)
            {
                try
                {
                    if (objObject == null) return;
                    var objCache = HttpRuntime.Cache;
                    //相对过期  
                    //objCache.Insert(cacheKey, objObject, null, DateTime.MaxValue,  new TimeSpan(0, 0, timeout), CacheItemPriority.NotRemovable, null);  
                    //绝对过期时间  
                    objCache.Insert(cacheKey, objObject, null, DateTime.UtcNow.AddSeconds(timeout), TimeSpan.Zero, CacheItemPriority.High, null);
                }
                catch (Exception)
                {
                    //throw;  
                }
            }
            /// <summary>  
            /// 移除指定数据缓存  
            /// </summary>  
            public static void RemoveAllCache(string cacheKey)
            {
                var cache = HttpRuntime.Cache;
                cache.Remove(cacheKey);
            }
            /// <summary>  
            /// 移除全部缓存  
            /// </summary>  
            public static void RemoveAllCache()
            {
                var cache = HttpRuntime.Cache;
                var cacheEnum = cache.GetEnumerator();
                while (cacheEnum.MoveNext())
                {
                    cache.Remove(cacheEnum.Key.ToString());
                }
            }
        }
    }

微信页面调用: 

//页面引用
<script src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>

 

<script type="text/javascript">        
        $(function () {
            var url = window.location.href;
            $.ajax({
                url: "/WechatJSSDK/GetWxShareInfo",
                data: {
                    url: url
                },
                success: function (ret) {
                    var appId = ret.appid;
                    var noncestr = ret.noncestr;
                    var timestamp = ret.timestamp;
                    var signature = ret.signature;
                    wx.config({
                        debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                        appId: appId, // 必填,公众号的唯一标识
                        timestamp: timestamp, // 必填,生成签名的时间戳
                        nonceStr: noncestr, // 必填,生成签名的随机串
                        signature: signature,// 必填,签名,见附录1
                        jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ',
                            'onMenuShareWeibo', 'onMenuShareQZone', 'chooseImage',
                            'uploadImage', 'downloadImage', 'startRecord', 'stopRecord',
                            'onVoiceRecordEnd', 'playVoice', 'pauseVoice', 'stopVoice',
                            'translateVoice', 'openLocation', 'getLocation', 'hideOptionMenu',
                            'showOptionMenu', 'closeWindow', 'hideMenuItems', 'showMenuItems',
                            'showAllNonBaseMenuItem', 'hideAllNonBaseMenuItem', 'scanQRCode'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
                    });



                }
            });

            wx.ready(function () {

                // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。

            });
            wx.error(function (res) {

                // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。

            });
//更换图片
            $('[name="avatar"]').click(function () {                
                wxChooseImage();
            });

            //拍照或从手机相册中选图接口
            function wxChooseImage() {
                wx.chooseImage({
                    count: 1,
                    needResult: 1,
                    sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
                    sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有                    
                    success(res) {
                        var localId = res.localIds[0];
                        var layer_index = layer.load(1);
                        UploadImage(localId, function (ret) {
                            layer.close(layer_index);
                            switch (ret.code) {
                                case 0:
                                    $('[name="avatar"]').attr("src", ret.msg);
                                    break;
                                default:
                                    Common.alert('fail', ret.msg);
                                    break;
                            }
                        });

                    },
                    fail: function (res) {
                        alert("操作提示", JSON.stringify(res), "1", "确定", "", "", "");
                    }

                });
            }
                        
        });

        //获取本地图片
        function UploadImage(localId, callback) {
            wx.getLocalImgData({
                localId: localId, // 图片的localID
                success: function (res) {
                    var localData = res.localData; // localData是图片的base64数据,可以用img标签显示
            //上传服务器
$.ajax({ url: '服务器端接收地址', data: { img_base64: localData }, success: callback });
            //立即预览
            if (localData.indexOf('data:image') != 0) {
              //判断是否有这样的头部
              localData = 'data:image/jpeg;base64,' + localData;
            }
            localData = localData.replace(/\r|\n/g, '').replace('data:image/jgp', 'data:image/jpeg');
            $('[name="img_base64"]').attr('src', localData);
                }
            });
        }
        
       
    </script>

 

posted @ 2020-07-29 15:39  鞍山老菜鸟  阅读(499)  评论(0编辑  收藏  举报