微信分享

風靈使發表於2018-09-18

WxHandler.ashx

using System;
using System.Text;
using System.Web;
using System.Web.Security;
using Service;

namespace ShareServer.Handler
{
    /// <summary>
    ///     微信業務邏輯處理
    /// </summary>
    public class WxHandler : IHttpHandler
    {
        private readonly WxService service = new WxService();

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/json";

            var type = context.Request["type"];

            switch (type)
            {
                case "share":
                    Share(context);
                    break;
                case "auth":
                    Auth(context);
                    break;
                case "openid":
                    OpenId(context);
                    break;
                default:
                    break;
            }
        }

        public bool IsReusable
        {
            get { return false; }
        }

        /// <summary>
        ///     微信分享
        /// </summary>
        /// <param name="context"></param>
        private void Share(HttpContext context)
        {
            var jsonHelper = new JsonHelper(context);

            var url = context.Request["page_url"];
            var utf8 = Encoding.UTF8;
            url = HttpUtility.UrlDecode(url, utf8);

            var config = service.GetShareConfig(url);

            jsonHelper.Success("查詢成功", config);
        }

        /// <summary>
        ///     微信認證
        /// </summary>
        /// <param name="context"></param>
        private void Auth(HttpContext context)
        {
            var token = "alsgame";
            var echoStr = context.Request["echoStr"];
            var signature = context.Request["signature"];
            var timestamp = context.Request["timestamp"];
            var nonce = context.Request["nonce"];
            string[] ArrTmp = {token, timestamp, nonce};
            Array.Sort(ArrTmp); //字典排序  
            var tmpStr = string.Join("", ArrTmp);
            tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
            tmpStr = tmpStr.ToLower();
            if (tmpStr == signature)
            {
                if (!string.IsNullOrEmpty(echoStr))
                {
                    context.Response.Write(echoStr);
                    context.Response.End();
                }
            }
        }

        /// <summary>
        ///     獲取OpenId
        /// </summary>
        public void OpenId(HttpContext context)
        {
            var jsonHelper = new JsonHelper(context);
            var code = context.Request["code"];

            var obj = service.GetOpenId(code);

            jsonHelper.Success("查詢成功", obj);
        }
    }
}

WxService.cs

using System;
using System.Configuration;
using System.IO;
using System.Net;
using System.Text;
using System.Web.Security;
using Newtonsoft.Json;

namespace Service
{
    /// <summary>
    ///     微信業務處理
    /// </summary>
    public class WxService
    {
        /// <summary>
        ///     微信公眾號
        /// </summary>
        private static readonly string appId = ConfigurationManager.AppSettings["APPID"];

        private static readonly string secret = ConfigurationManager.AppSettings["SECRET"];

        /// <summary>
        ///     全域性快取
        /// </summary>
        private static string AccessToken = "";

        private static string JsApiTicket = "";

        /// <summary>
        ///     上次更新時間
        /// </summary>
        private static long LastAccessToken;

        private static long LastJsApiTicket;

        /// <summary>
        ///     獲取OPENID
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public string GetOpenId(string code)
        {
            var url =
                "https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code";
            url = string.Format(url, appId, secret, code);

            return HttpGet(url);
        }

        /// <summary>
        ///     獲取微信配置資訊
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public WxConfig GetShareConfig(string url)
        {
            var ticket = GetJsApiTicket();
            var noncestr = GetNonceStr();
            var timestamp = GetTimeStamp();
            var signature = CreateSignature(ticket, noncestr, timestamp, url);

            var config = new WxConfig();
            config.appId = appId;
            config.ticket = ticket;
            config.nonceStr = noncestr;
            config.timestamp = timestamp;
            config.signature = signature;

            return config;
        }

        /// <summary>
        ///     生成簽名演算法
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        private string CreateSignature(string ticket, string nocestr, long timestamp, string url)
        {
            var text = "jsapi_ticket=" + ticket;
            text += "&noncestr=" + nocestr;
            text += "&timestamp=" + timestamp;
            text += "&url=" + url;

            return SHA1(text);
        }

        /// <summary>
        ///     獲取Ticket
        /// </summary>
        /// <returns></returns>
        public string GetJsApiTicket()
        {
            if (GetTimeStamp() - LastJsApiTicket > 7000)
            {
                var accessToken = GetAccessToken();
                var url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi";
                url = string.Format(url, accessToken);

                var result = HttpGet(url);
                var config = JsonConvert.DeserializeObject<WxConfig>(result);
                JsApiTicket = config.ticket;

                LastJsApiTicket = GetTimeStamp();
            }
            return JsApiTicket;
        }

        /// <summary>
        ///     獲取Access_Token
        /// </summary>
        /// <param name="appId"></param>
        /// <param name="secret"></param>
        /// <returns></returns>
        public string GetAccessToken()
        {
            if (GetTimeStamp() - LastAccessToken > 7000)
            {
                var url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";
                url = string.Format(url, appId, secret);

                var result = HttpGet(url);
                var config = JsonConvert.DeserializeObject<WxConfig>(result);
                AccessToken = config.access_token;

                LastAccessToken = GetTimeStamp();
            }
            return AccessToken;
        }

        /// <summary>
        ///     獲取TimeStamp
        /// </summary>
        /// <returns></returns>
        private long GetTimeStamp()
        {
            var ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalSeconds);
        }

        /// <summary>
        ///     獲取NoceStr
        /// </summary>
        /// <returns></returns>
        private string GetNonceStr()
        {
            return Guid.NewGuid().ToString();
        }

        /// <summary>
        ///     Sha1加密
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        private string SHA1(string text)
        {
            return FormsAuthentication.HashPasswordForStoringInConfigFile(text, "SHA1");
        }

        /// <summary>
        ///     http請求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="postDataStr"></param>
        /// <returns></returns>
        public string HttpGet(string url)
        {
            var request = (HttpWebRequest) WebRequest.Create(url);
            request.Method = "GET";
            request.ContentType = "text/json;charset=UTF-8";

            var response = (HttpWebResponse) request.GetResponse();
            var myResponseStream = response.GetResponseStream();
            var streamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
            var result = streamReader.ReadToEnd();
            streamReader.Close();
            myResponseStream.Close();

            return result;
        }
    }
}

JsonHelper.cs

using System;
using System.Web;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace Service
{
    /// <summary>
    ///     JSON輔助類
    /// </summary>
    public class JsonHelper
    {
        private readonly HttpContext context;

        public JsonHelper(HttpContext context)
        {
            this.context = context;
        }

        /// <summary>
        ///     處理成功
        /// </summary>
        public void Success(string msg, object data = null)
        {
            var message = new Message();

            message.status = 0;
            message.msg = msg;
            message.data = data == null ? new Array[0] : data;
            message.updateTime = DateTime.Now;
            context.Response.Write(SerializeObject(message));
        }

        /// <summary>
        ///     處理失敗
        /// </summary>
        public void Failure(string msg, object data = null)
        {
            var message = new Message();

            message.status = -1;
            message.msg = msg;
            message.data = data == null ? new Array[0] : data;
            message.updateTime = DateTime.Now;
            context.Response.Write(SerializeObject(message));
        }

        /// <summary>
        ///     序列化
        /// </summary>
        public string SerializeObject(object obj)
        {
            var timeFormat = new IsoDateTimeConverter();
            timeFormat.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
            return JsonConvert.SerializeObject(obj, Formatting.Indented, timeFormat);
        }
    }
}

實體類

WxConfig.cs

namespace Service
{
    public class WxConfig
    {
        public string appId { get; set; }

        public string signature { get; set; }

        public string nonceStr { get; set; }

        public long timestamp { get; set; }

        public string ticket { get; set; }

        public string access_token { get; set; }
    }
}

Message.cs

using System;

namespace Service
{
    public class Message
    {
        /// <summary>
        ///     響應狀態碼
        /// </summary>
        public int status { get; set; }

        /// <summary>
        ///     響應訊息
        /// </summary>
        public string msg { get; set; }

        /// <summary>
        ///     響應資料集
        /// </summary>
        public object data { get; set; }

        /// <summary>
        ///     伺服器時間
        /// </summary>
        public DateTime updateTime { get; set; }
    }
}

相關文章