微信小程序【消息推送服務器認證C# WebAPI】

參考微信開發文檔:

https://developers.weixin.qq.com/miniprogram/dev/api/custommsg/callback_help.htmlhtml

代碼可用api

/// <summary>
/// 接口認證
/// </summary>
/// <param name="echostr"></param>
/// <param name="signature"></param>
/// <param name="timestamp"></param>
/// <param name="nonce"></param>
/// <returns></returns>
[HttpGet]
public async Task<HttpResponseMessage> wx(string echostr, string signature, string timestamp, string nonce)
{
    string token = "token";
    if (!CheckSignature(token, signature, timestamp, nonce))
        echostr = "驗證不正確";
    HttpResponseMessage responseMessage = new HttpResponseMessage { Content = new StringContent(echostr, Encoding.GetEncoding("UTF-8"), "text/plain") };
 
    return responseMessage;
}
/// <summary>
/// 接收客服消息
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<HttpResponseMessage> wx()
{
    LogHelper log = new LogHelper();
    var content = await Request.Content.ReadAsStringAsync();
    log.LogError(content);
    HttpResponseMessage responseMessage = new HttpResponseMessage();
    return responseMessage;
}
/// <summary>
/// 驗證微信簽名
/// </summary>
private bool CheckSignature(string token, string signature, string timestamp, string nonce)
{
    string[] ArrTmp = { token, timestamp, nonce };
 
    Array.Sort(ArrTmp);
    string tmpStr = string.Join("", ArrTmp);
    var data = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(tmpStr));
    var sb = new StringBuilder();
    foreach (var t in data)
    {
        sb.Append(t.ToString("X2"));
    }
    tmpStr = sb.ToString();
    tmpStr = tmpStr.ToLower();
 
    if (tmpStr == signature)
    {
        return true;
    }
    else
    {
        return false;
    }
}

 推薦代碼:使用 Senparc.Weixin SDK

該版本是用通常處理程序作的,當初在微信配置中填的是此地址,沒有修改爲WebApi。你們能夠參考作成WebApi的服務器

引用:

using Senparc.Weixin;
using Senparc.Weixin.MP;
using Senparc.Weixin.MP.Entities.Request;
public class wxapi : IHttpHandler
    {
        //public static readonly string Token = Config.SenparcWeixinSetting.Token;//與微信公衆帳號後臺的Token設置保持一致,區分大小寫。
        //public static readonly string EncodingAESKey = Config.SenparcWeixinSetting.EncodingAESKey;//與微信公衆帳號後臺的EncodingAESKey設置保持一致,區分大小寫。
        //public static readonly string AppId = Config.SenparcWeixinSetting.WeixinAppId;//與微信公衆帳號後臺的AppId設置保持一致,區分大小寫。
        public static string Token = CachedConfigContext.Current.SettingConfig.token;
        public static string EncodingAESKey = CachedConfigContext.Current.SettingConfig.EncodingAESKey;
        public static string AppId = CachedConfigContext.Current.SettingConfig.appId;

        readonly Func<string> _getRandomFileName = () => DateTime.Now.ToString("yyyyMMdd-HHmmss") + Guid.NewGuid().ToString("n").Substring(0, 6);

        public void ProcessRequest(HttpContext context)
        {
            string postString = string.Empty;

            PostModel postModel = new PostModel();
            postModel.Signature = HttpContext.Current.Request.QueryString["signature"];
            postModel.Timestamp = HttpContext.Current.Request.QueryString["timestamp"];
            postModel.Nonce = HttpContext.Current.Request.QueryString["nonce"];
            postModel.Msg_Signature = HttpContext.Current.Request.QueryString["msg_signature"];
            var openid = HttpContext.Current.Request.QueryString["openid"];
            var encrypt_type = HttpContext.Current.Request.QueryString["encrypt_type"];

            if (HttpContext.Current.Request.HttpMethod.ToUpper() == "POST")
            {
                //using (Stream stream = HttpContext.Current.Request.InputStream)
                //{
                //    Byte[] postBytes = new Byte[stream.Length];
                //    stream.Read(postBytes, 0, (Int32)stream.Length);
                //    postString = Encoding.UTF8.GetString(postBytes);
                //}

                //if (!string.IsNullOrEmpty(postString))
                //{
                //    //Execute(postString);
                //}
                if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token))
                {
                    HttpContext.Current.Response.Write("error");
                    HttpContext.Current.Response.End();
                }
                #region 打包 PostModel 信息

                postModel.Token = Token;//根據本身後臺的設置保持一致
                postModel.EncodingAESKey = EncodingAESKey;//根據本身後臺的設置保持一致
                postModel.AppId = AppId;//根據本身後臺的設置保持一致

                #endregion

                //v4.2.2以後的版本,能夠設置每一個人上下文消息儲存的最大數量,防止內存佔用過多,若是該參數小於等於0,則不限制
                var maxRecordCount = 10;

                //自定義MessageHandler,對微信請求的詳細判斷操做都在這裏面。
                var messageHandler = new CustomMessageHandler(HttpContext.Current.Request.InputStream, postModel, maxRecordCount);

                #region 設置消息去重

                /* 若是須要添加消息去重功能,只需打開OmitRepeatedMessage功能,SDK會自動處理。
                 * 收到重複消息一般是由於微信服務器沒有及時收到響應,會持續發送2-5條不等的相同內容的RequestMessage*/
                messageHandler.OmitRepeatedMessage = true;//默認已經開啓,此處僅做爲演示,也能夠設置爲false在本次請求中停用此功能

                #endregion

                try
                {

                    #region 記錄 Request 日誌

                    var logPath = HttpContext.Current.Server.MapPath(string.Format("~/logs/MP/{0}/", DateTime.Now.ToString("yyyy-MM-dd")));
                    if (!Directory.Exists(logPath))
                    {
                        Directory.CreateDirectory(logPath);
                    }

                    //測試時可開啓此記錄,幫助跟蹤數據,使用前請確保logs文件夾存在,且有讀寫權限。
                    messageHandler.RequestDocument.Save(Path.Combine(logPath, string.Format("{0}_Request_{1}_{2}.txt", _getRandomFileName(),
                        messageHandler.RequestMessage.FromUserName,
                        messageHandler.RequestMessage.MsgType)));
                    if (messageHandler.UsingEcryptMessage)
                    {
                        messageHandler.EcryptRequestDocument.Save(Path.Combine(logPath, string.Format("{0}_Request_Ecrypt_{1}_{2}.txt", _getRandomFileName(),
                            messageHandler.RequestMessage.FromUserName,
                            messageHandler.RequestMessage.MsgType)));
                    }

                    #endregion

                    //執行微信處理過程
                    messageHandler.Execute();

                    #region 記錄 Response 日誌

                    //測試時可開啓,幫助跟蹤數據

                    //if (messageHandler.ResponseDocument == null)
                    //{
                    //    throw new Exception(messageHandler.RequestDocument.ToString());
                    //}
                    if (messageHandler.ResponseDocument != null)
                    {
                        messageHandler.ResponseDocument.Save(Path.Combine(logPath, string.Format("{0}_Response_{1}_{2}.txt", _getRandomFileName(),
                            messageHandler.ResponseMessage.ToUserName,
                            messageHandler.ResponseMessage.MsgType)));
                    }

                    if (messageHandler.UsingEcryptMessage && messageHandler.FinalResponseDocument != null)
                    {
                        //記錄加密後的響應信息
                        messageHandler.FinalResponseDocument.Save(Path.Combine(logPath, string.Format("{0}_Response_Final_{1}_{2}.txt", _getRandomFileName(),
                            messageHandler.ResponseMessage.ToUserName,
                            messageHandler.ResponseMessage.MsgType)));
                    }

                    #endregion

                    //return Content(messageHandler.ResponseDocument.ToString());//v0.7-
                    //return new WeixinResult(messageHandler);//v0.8+
                    var res = new Senparc.Weixin.MP.MvcExtension.FixWeixinBugWeixinResult(messageHandler);//爲了解決官方微信5.0軟件換行bug暫時添加的方法,平時用下面一個方法便可
                    HttpContext.Current.Response.Write(res.Content);
                    HttpContext.Current.Response.End();
                }
                catch (Exception ex)
                {
                    #region 異常處理
                    WeixinTrace.Log("MessageHandler錯誤:{0}", ex.Message);

                    using (TextWriter tw = new StreamWriter(HttpContext.Current.Server.MapPath("~/logs/Error_" + _getRandomFileName() + ".txt")))
                    {
                        tw.WriteLine("ExecptionMessage:" + ex.Message);
                        tw.WriteLine(ex.Source);
                        tw.WriteLine(ex.StackTrace);
                        //tw.WriteLine("InnerExecptionMessage:" + ex.InnerException.Message);

                        if (messageHandler.ResponseDocument != null)
                        {
                            tw.WriteLine(messageHandler.ResponseDocument.ToString());
                        }

                        if (ex.InnerException != null)
                        {
                            tw.WriteLine("========= InnerException =========");
                            tw.WriteLine(ex.InnerException.Message);
                            tw.WriteLine(ex.InnerException.Source);
                            tw.WriteLine(ex.InnerException.StackTrace);
                        }

                        tw.Flush();
                        tw.Close();
                    }
                    HttpContext.Current.Response.Write("");
                    HttpContext.Current.Response.End();
                    #endregion
                }

            }
            else
            {
                if (CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token))
                {
                    string echostr = HttpContext.Current.Request.QueryString["echoStr"];
                    //返回隨機字符串則表示驗證經過
                    HttpContext.Current.Response.Write(echostr);
                    HttpContext.Current.Response.End();
                }
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
相關文章
相關標籤/搜索