/// <summary> /// 执行消息处理。 /// </summary> private void ExecMessageHandler() { #region 参数校验 if (string.IsNullOrEmpty(this.MessageContext.HttpRequestContent)) { throw new StringNullOrEmptyException("HttpRequestContent"); } if (this.MessageContext.HttpRequestParams == null) { throw new StringNullOrEmptyException("HttpRequestParams"); } #endregion #region 初始化参数 this._requestParams = this.MessageContext.HttpRequestParams; this._requestContent = this.MessageContext.HttpRequestContent; #endregion #region 校验签名 CheckSignature.Execute(this._requestParams.Signature, this._requestParams.Timestamp, this._requestParams.Nonce, string.Empty); #endregion #region 消息解密 if (this._requestParams.IsEncrypt) { this._msgCrypto = new WeixinMsgCrypto(); int decryptMsgResult = this._msgCrypto.DecryptMsg(this._requestParams.Msg_Signature, this._requestParams.Timestamp, this._requestParams.Nonce, this._requestContent, ref this._requestContent); if (decryptMsgResult != Convert.ToInt32(WeixinMsgCryptoErrorCode.OK)) { throw new Exception("消息解密失败!"); } } #endregion //消息解析。 this._requestMessage = RequestMessageProcess.Parse(this._requestContent); if (this._requestMessage == null) { this._responeContent = string.Empty; //记录日志。 WeixinApp.Logger.Info($"消息未处理,requestContent:{this._requestContent}"); return; } #region 会话支持 //todo: 后期实现。 #endregion #region 消息去重 #region 除无效的消息标识 for (int i = 0; i < _messageIdentitys.Count; i++) { KeyValuePair <string, DateTime> item = _messageIdentitys[i]; //如果消息处理时间大于 30 秒则删除该条标识。 if (item.Value.AddSeconds(30) < DateTime.Now) { _messageIdentitys.Remove(item); } } #endregion string msgIdentity = this.GetMessageIdentity(this._requestMessage); //如果消息已经被标识为处理则返回空字符串, if (_messageIdentitys.Any(i => i.Key == msgIdentity)) { this._responeContent = string.Empty; //记录日志。 WeixinApp.Logger.Info($"消息重复,已经响应空字符串消息,消息标识:[{msgIdentity}]\r\n请求内容:{_requestContent}"); return; } //将当前消息标识添加到标识列表中, _messageIdentitys.Add(new KeyValuePair <string, DateTime>(msgIdentity, DateTime.Now)); #endregion //消息处理。 this._responeContent = RequestMessageProcess.ProcessByConfig(this._requestContent); #region 消息加密 if (this._requestParams.IsEncrypt) { int encryptMsgResult = this._msgCrypto.EncryptMsg(this._responeContent, this._requestParams.Timestamp, this._requestParams.Nonce, ref this._responeContent); if (encryptMsgResult != Convert.ToInt32(WeixinMsgCryptoErrorCode.OK)) { throw new Exception("消息加密失败!"); } } #endregion }