public XDocument Init(IEncryptPostModel postModel) { _postModel = postModel as PostModel ?? new PostModel(); //解密XML信息 var postDataStr = EcryptRequestDocument.ToString(); WXBizMsgCrypt msgCrype = new WXBizMsgCrypt(_postModel.Token, _postModel.EncodingAESKey, _postModel.AppId); string msgXml = null; var result = msgCrype.DecryptMsg(_postModel.Msg_Signature, _postModel.Timestamp, _postModel.Nonce, postDataStr, ref msgXml); //判断result类型 if (result != 0) { //验证没有通过,取消执行 CancelExecute = true; return(null); } RequestDocument = XDocument.Parse(msgXml);//完成解密 RequestMessage = RequestMessageFactory.GetRequestEntity(RequestDocument); //((RequestMessageBase)RequestMessage).FillEntityWithXml(RequestDocument); return(RequestDocument); }
/// <summary> /// /// </summary> /// <param name="inputStream"></param> /// <param name="maxRecordCount"></param> /// <param name="postModel">需要传入到Init的参数</param> public MessageHandler(Stream inputStream, IEncryptPostModel postModel, int maxRecordCount = 0) { var postDataDocument = XmlUtility.Convert(inputStream); //PostModel = postModel;//PostModel 在当前类初始化过程中必须赋值 CommonInitialize(postDataDocument, maxRecordCount, postModel); }
/// <summary> /// 构造函数公用的初始化方法 /// </summary> /// <param name="postDataDocument"></param> /// <param name="maxRecordCount"></param> /// <param name="postModel"></param> public void CommonInitialize(XDocument postDataDocument, int maxRecordCount, IEncryptPostModel postModel) { OmitRepeatedMessage = true; //默认开启去重 GlobalMessageContext.MaxRecordCount = maxRecordCount; PostModel = postModel; //PostModel 在当前类初始化过程中必须赋值 RequestDocument = Init(postDataDocument, postModel); }
/// <summary> /// <para>使用requestMessageBase的构造函数</para> /// <para>此构造函数提供给具体的类库进行测试使用,例如Senparc.NeuChar.Work</para> /// </summary> /// <param name="requestMessageBase"></param> /// <param name="maxRecordCount"></param> /// <param name="postModel">需要传入到Init的参数</param> public MessageHandler(RequestMessageBase requestMessageBase, IEncryptPostModel postModel, int maxRecordCount = 0) { ////将requestMessageBase生成XML格式。 //var xmlStr = XmlUtility.XmlUtility.Serializer(requestMessageBase); //var postDataDocument = XDocument.Parse(xmlStr); //CommonInitialize(postDataDocument, maxRecordCount, postData); //此方法不执行任何方法,提供给具体的类库进行测试使用,例如Senparc.NeuChar.Work }
public override XDocument Init(XDocument postDataDocument, IEncryptPostModel postModel) { _postModel = postModel as PostModel ?? new PostModel(); var postDataStr = postDataDocument.ToString(); //Work中消息默认都是强制加密的,但通知似乎没有加密 UsingEncryptMessage = postDataDocument.Root.Element("Encrypt") != null; EncryptPostData = RequestMessageFactory.GetEncryptPostData(postDataStr); XDocument requestDocument; //2、解密:获得明文字符串 if (UsingEncryptMessage) { string msgXml = null; WXBizMsgCrypt msgCrype = new WXBizMsgCrypt(_postModel.Token, _postModel.EncodingAESKey, _postModel.CorpId); var result = msgCrype.DecryptMsg(_postModel.Msg_Signature, _postModel.Timestamp, _postModel.Nonce, postDataStr, ref msgXml); /* msgXml * <xml><ToUserName><![CDATA[wx7618c0a6d9358622]]></ToUserName> * <FromUserName><![CDATA[001]]></FromUserName> * <CreateTime>1412585107</CreateTime> * <MsgType><![CDATA[text]]></MsgType> * <Content><![CDATA[你好]]></Content> * <MsgId>4299263624800632834</MsgId> * <AgentID>2</AgentID> * </xml> */ //判断result类型 if (result != 0) { //验证没有通过,取消执行 CancelExecute = true; return(null); } requestDocument = XDocument.Parse(msgXml); } else { requestDocument = postDataDocument;//TODO:深拷贝 } RequestMessage = RequestMessageFactory.GetRequestEntity <TMC>(new TMC(), doc: requestDocument); return(requestDocument); //消息上下文记录将在 base.CommonInitialize() 中根据去重等条件判断后进行添加 }
public override XDocument Init(XDocument postDataDocument, IEncryptPostModel postModel) { //进行加密判断并处理 var postDataStr = postDataDocument.ToString(); XDocument decryptDoc = postDataDocument; //if (postModel != null && postDataDocument.Root.Element("Encrypt") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("Encrypt").Value)) //{ // //使用了加密 // UsingEncryptMessage = true; // EcryptRequestDocument = postDataDocument; // WXBizMsgCrypt msgCrype = new WXBizMsgCrypt(_postModel.Token, _postModel.EncodingAESKey, _postModel.AppId); // string msgXml = null; // var result = msgCrype.DecryptMsg(_postModel.Msg_Signature, _postModel.Timestamp, _postModel.Nonce, postDataStr, ref msgXml); // //判断result类型 // if (result != 0) // { // //验证没有通过,取消执行 // CancelExcute = true; // return null; // } // if (postDataDocument.Root.Element("FromUserName") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("FromUserName").Value)) // { // //TODO:使用了兼容模式,进行验证即可 // UsingCompatibilityModelEncryptMessage = true; // } // decryptDoc = XDocument.Parse(msgXml);//完成解密 //} var msgType = MsgTypeHelper.GetRequestMsgType(decryptDoc); if (msgType != RequestMsgType.NeuChar) { throw new MessageHandlerException("仅支持 NeuChar 类型请求"); } RequestMessage = new RequestMessageNeuChar(); if (UsingEncryptMessage) { RequestMessage.Encrypt = postDataDocument.Root.Element("Encrypt").Value; } return(decryptDoc); //消息上下文记录将在 base.CommonInitialize() 中根据去重等条件判断后进行添加 }
/// <summary> /// 初始化数据 /// </summary> /// <param name="postDataDocument"></param> /// <param name="postModel"></param> /// <returns></returns> public override XDocument Init(XDocument postDataDocument, IEncryptPostModel postModel) { //进行加密判断并处理 _postModel = postModel as PostModel ?? new PostModel(); var postDataStr = postDataDocument.ToString(); XDocument decryptDoc = postDataDocument; if (_postModel != null && !_postModel.Token.IsNullOrWhiteSpace() && postDataDocument.Root.Element("Encrypt") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("Encrypt").Value)) { //使用了加密 UsingEcryptMessage = true; EcryptRequestDocument = postDataDocument; WXBizMsgCrypt msgCrype = new WXBizMsgCrypt(_postModel.Token, _postModel.EncodingAESKey, _postModel.AppId); string msgXml = null; var result = msgCrype.DecryptMsg(_postModel.Msg_Signature, _postModel.Timestamp, _postModel.Nonce, postDataStr, ref msgXml); //判断result类型 if (result != 0) { //验证没有通过,取消执行 CancelExcute = true; return(null); } if (postDataDocument.Root.Element("FromUserName") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("FromUserName").Value)) { //TODO:使用了兼容模式,进行验证即可 UsingCompatibilityModelEcryptMessage = true; } decryptDoc = XDocument.Parse(msgXml);//完成解密 } RequestMessage = RequestMessageFactory.GetRequestEntity(decryptDoc); if (UsingEcryptMessage) { RequestMessage.Encrypt = postDataDocument.Root.Element("Encrypt").Value; } //记录上下文 if (MessageContextGlobalConfig.UseMessageContext) { GlobalMessageContext.InsertMessage(RequestMessage); } return(decryptDoc); }
public override XDocument Init(XDocument postDataDocument, IEncryptPostModel postModel) { _postModel = postModel as PostModel ?? new PostModel(); UsingEcryptMessage = true;//Work中消息都是强制加密的 var postDataStr = postDataDocument.ToString(); EncryptPostData = RequestMessageFactory.GetEncryptPostData(postDataStr); //2、解密:获得明文字符串 WXBizMsgCrypt msgCrype = new WXBizMsgCrypt(_postModel.Token, _postModel.EncodingAESKey, _postModel.CorpId); string msgXml = null; var result = msgCrype.DecryptMsg(_postModel.Msg_Signature, _postModel.Timestamp, _postModel.Nonce, postDataStr, ref msgXml); /* msgXml * <xml><ToUserName><![CDATA[wx7618c0a6d9358622]]></ToUserName> * <FromUserName><![CDATA[001]]></FromUserName> * <CreateTime>1412585107</CreateTime> * <MsgType><![CDATA[text]]></MsgType> * <Content><![CDATA[你好]]></Content> * <MsgId>4299263624800632834</MsgId> * <AgentID>2</AgentID> * </xml> */ //判断result类型 if (result != 0) { //验证没有通过,取消执行 CancelExcute = true; return(null); } var requestDocument = XDocument.Parse(msgXml); RequestMessage = RequestMessageFactory.GetRequestEntity(requestDocument); //记录上下文 if (RequestMessage.MsgType != RequestMsgType.Unknown && MessageContextGlobalConfig.UseMessageContext) { GlobalMessageContext.InsertMessage(RequestMessage); } return(requestDocument); }
public override XDocument Init(XDocument requestDocument, IEncryptPostModel postModel) { XDocument decryptDoc = requestDocument; var messageContext = new Weixin.MP.MessageContexts.DefaultMpMessageContext();// new CustomMessageContext(); //base.GetCurrentMessageContext().GetAwaiter().GetResult(); RequestMessage = RequestMessageFactory.GetRequestEntity(messageContext, decryptDoc) as RequestMessageBase; base.SpecialDeduplicationAction = (lastMessage, messageHandler) => { //判断特殊事件 if (!messageHandler.MessageIsRepeated && lastMessage is RequestMessageEventBase && messageHandler.RequestMessage is RequestMessageEventBase && (lastMessage as RequestMessageEventBase).Event == (messageHandler.RequestMessage as RequestMessageEventBase).Event ) { var lastEventMessage = lastMessage as RequestMessageEventBase; var currentEventMessage = messageHandler.RequestMessage as RequestMessageEventBase; switch (lastEventMessage.Event) { case Event.user_get_card: //领取事件推送 //文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025274 //问题反馈:https://github.com/JeffreySu/WeiXinMPSDK/issues/1106 var lastGetUserCardMessage = lastMessage as RequestMessageEvent_User_Get_Card; var currentGetUserCardMessage = messageHandler.RequestMessage as RequestMessageEvent_User_Get_Card; if (lastGetUserCardMessage.UserCardCode == currentGetUserCardMessage.UserCardCode && lastGetUserCardMessage.CardId == currentGetUserCardMessage.CardId) { return(true); } break; default: break; } } return(false); }; //消息去重的基本方法已经在基类 CommonInitialize() 中实现 return(decryptDoc); }
public override XDocument Init(XDocument postDataDocument, IEncryptPostModel postData = null) { StartTime = DateTime.Now; return(base.Init(postDataDocument, postData)); }
/// <summary> /// 初始化 /// </summary> /// <param name="postDataDocument"></param> /// <param name="postModel"></param> /// <returns></returns> public override XDocument Init(XDocument postDataDocument, IEncryptPostModel postModel) { //进行加密判断并处理 _postModel = postModel as PostModel; var postDataStr = postDataDocument.ToString(); XDocument decryptDoc = postDataDocument; if (_postModel != null && !_postModel.Token.IsNullOrWhiteSpace() && postDataDocument.Root.Element("Encrypt") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("Encrypt").Value)) { //使用了加密 UsingEcryptMessage = true; EcryptRequestDocument = postDataDocument; WXBizMsgCrypt msgCrype = new WXBizMsgCrypt(_postModel.Token, _postModel.EncodingAESKey, _postModel.AppId); string msgXml = null; var result = msgCrype.DecryptMsg(_postModel.Msg_Signature, _postModel.Timestamp, _postModel.Nonce, postDataStr, ref msgXml); //判断result类型 if (result != 0) { //验证没有通过,取消执行 CancelExcute = true; return(null); } if (postDataDocument.Root.Element("FromUserName") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("FromUserName").Value)) { //TODO:使用了兼容模式,进行验证即可 UsingCompatibilityModelEcryptMessage = true; } decryptDoc = XDocument.Parse(msgXml);//完成解密 } RequestMessage = RequestMessageFactory.GetRequestEntity(decryptDoc); if (UsingEcryptMessage) { RequestMessage.Encrypt = postDataDocument.Root.Element("Encrypt").Value; } //TODO:分布式系统中本地的上下文会有同步问题,需要同步使用远程的储存 if (MessageContextGlobalConfig.UseMessageContext) { var omit = OmitRepeatedMessageFunc == null || OmitRepeatedMessageFunc(RequestMessage); lock (MessageContextGlobalConfig.OmitRepeatLock)//TODO:使用分布式锁 { #region 消息去重 if (omit && OmitRepeatedMessage && CurrentMessageContext.RequestMessages.Count > 0 //&& !(RequestMessage is RequestMessageEvent_Merchant_Order)批量订单的MsgId可能会相同 ) { //lastMessage必定有值(除非极端小的过期时间条件下,几乎不可能发生) var lastMessage = CurrentMessageContext.RequestMessages[CurrentMessageContext.RequestMessages.Count - 1]; if ( //使用MsgId去重 (lastMessage.MsgId != 0 && lastMessage.MsgId == RequestMessage.MsgId) || //使用CreateTime去重(OpenId对象已经是同一个) (lastMessage.MsgId == RequestMessage.MsgId && lastMessage.CreateTime == RequestMessage.CreateTime && lastMessage.MsgType == RequestMessage.MsgType) ) { MarkRepeatedMessage();//标记为已重复 } //判断特殊事件 if (!MessageIsRepeated && lastMessage is RequestMessageEventBase && RequestMessage is RequestMessageEventBase && (lastMessage as RequestMessageEventBase).Event == (RequestMessage as RequestMessageEventBase).Event ) { var lastEventMessage = lastMessage as RequestMessageEventBase; var currentEventMessage = RequestMessage as RequestMessageEventBase; switch (lastEventMessage.Event) { case Event.user_get_card: //领取事件推送 //文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025274 //问题反馈:https://github.com/JeffreySu/WeiXinMPSDK/issues/1106 var lastGetUserCardMessage = lastMessage as RequestMessageEvent_User_Get_Card; var currentGetUserCardMessage = RequestMessage as RequestMessageEvent_User_Get_Card; if (lastGetUserCardMessage.UserCardCode == currentGetUserCardMessage.UserCardCode && lastGetUserCardMessage.CardId == currentGetUserCardMessage.CardId) { MarkRepeatedMessage(); //标记为已重复 } break; default: break; } } } #endregion //在消息没有被去重的情况下记录上下文 if (!MessageIsRepeated) { GlobalMessageContext.InsertMessage(RequestMessage); } } } return(decryptDoc); }
/// <summary> /// 使用postDataDocument的构造函数 /// </summary> /// <param name="postDataDocument"></param> /// <param name="maxRecordCount"></param> /// <param name="postModel">需要传入到Init的参数</param> public MessageHandler(XDocument postDataDocument, IEncryptPostModel postModel, int maxRecordCount = 0) { //PostModel = postModel;//PostModel 在当前类初始化过程中必须赋值 CommonInitialize(postDataDocument, maxRecordCount, postModel); }
/// <summary> /// 初始化,获取RequestDocument。 /// Init中需要对上下文添加当前消息(如果使用上下文) /// </summary> /// <param name="requestDocument"></param> /// <param name="postModel"></param> public abstract XDocument Init(XDocument requestDocument, IEncryptPostModel postModel);
public override XDocument Init(XDocument postDataDocument, IEncryptPostModel postModel) { BeginTime = DateTime.Now; return(base.Init(postDataDocument, postModel)); }
/// <summary> /// 使用postDataDocument的构造函数 /// </summary> /// <param name="postDataDocument"></param> /// <param name="maxRecordCount"></param> /// <param name="postModel">需要传入到Init的参数</param> public MessageHandler(XDocument postDataDocument, IEncryptPostModel postModel, int maxRecordCount = 0) { CommonInitialize(postDataDocument, maxRecordCount, postModel); }
/// <summary> /// 检查签名是否正确 /// </summary> /// <param name="signature"></param> /// <param name="postModel">需要提供:Timestamp、Nonce、Token</param> /// <returns></returns> public static bool Check(string signature, IEncryptPostModel postModel) { return(Check(signature, postModel.Timestamp, postModel.Nonce, postModel.Token)); }
public override XDocument Init(XDocument postDataDocument, IEncryptPostModel postModel) { //进行加密判断并处理 var postDataStr = postDataDocument.ToString(); XDocument decryptDoc = postDataDocument; //if (postModel != null && postDataDocument.Root.Element("Encrypt") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("Encrypt").Value)) //{ // //使用了加密 // UsingEcryptMessage = true; // EcryptRequestDocument = postDataDocument; // WXBizMsgCrypt msgCrype = new WXBizMsgCrypt(_postModel.Token, _postModel.EncodingAESKey, _postModel.AppId); // string msgXml = null; // var result = msgCrype.DecryptMsg(_postModel.Msg_Signature, _postModel.Timestamp, _postModel.Nonce, postDataStr, ref msgXml); // //判断result类型 // if (result != 0) // { // //验证没有通过,取消执行 // CancelExcute = true; // return null; // } // if (postDataDocument.Root.Element("FromUserName") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("FromUserName").Value)) // { // //TODO:使用了兼容模式,进行验证即可 // UsingCompatibilityModelEcryptMessage = true; // } // decryptDoc = XDocument.Parse(msgXml);//完成解密 //} var msgType = MsgTypeHelper.GetRequestMsgType(decryptDoc); if (msgType != RequestMsgType.NeuChar) { throw new MessageHandlerException("仅支持 NeuChar 类型请求"); } RequestMessage = new RequestMessageNeuChar(); if (UsingEcryptMessage) { RequestMessage.Encrypt = postDataDocument.Root.Element("Encrypt").Value; } //TODO:分布式系统中本地的上下文会有同步问题,需要同步使用远程的储存 if (MessageContextGlobalConfig.UseMessageContext) { //var omit = OmitRepeatedMessageFunc == null || OmitRepeatedMessageFunc(RequestMessage); var cache = CacheStrategyFactory.GetObjectCacheStrategyInstance(); using (cache.BeginCacheLock(MessageContextGlobalConfig.MESSAGE_CONTENT_OMIT_REPEAT_LOCK_NAME, "NeuCharAppMessageHandler"))//使用分布式缓存 { #region 消息去重 if (/*omit &&*/ OmitRepeatedMessage && CurrentMessageContext.RequestMessages.Count > 0 //&& !(RequestMessage is RequestMessageEvent_Merchant_Order)批量订单的MsgId可能会相同 ) { //lastMessage必定有值(除非极端小的过期时间条件下,几乎不可能发生) var lastMessage = CurrentMessageContext.RequestMessages[CurrentMessageContext.RequestMessages.Count - 1]; if ( //使用MsgId去重 (lastMessage.MsgId != 0 && lastMessage.MsgId == RequestMessage.MsgId) || //使用CreateTime去重(OpenId对象已经是同一个) (lastMessage.MsgId == RequestMessage.MsgId && lastMessage.CreateTime == RequestMessage.CreateTime && lastMessage.MsgType == RequestMessage.MsgType) ) { MarkRepeatedMessage();//标记为已重复 } } #endregion //在消息没有被去重的情况下记录上下文 if (!MessageIsRepeated) { GlobalMessageContext.InsertMessage(RequestMessage); } } } return(decryptDoc); }
///// <summary> ///// 动态去重判断委托,仅当返回值为false时,不使用消息去重功能 ///// </summary> //public Func<IRequestMessageBase, bool> OmitRepeatedMessageFunc { get; set; } = null; public CustomMessageHandler(XDocument postDataDocument, IEncryptPostModel postModel, int maxRecordCount = 0) : base(postDataDocument, postModel, maxRecordCount) { }
/// <summary> /// 返回正确的签名 /// </summary> /// <param name="postModel">需要提供:Timestamp、Nonce、Token</param> /// <returns></returns> public static string GetSignature(IEncryptPostModel postModel) { return(GetSignature(postModel.Timestamp, postModel.Nonce, postModel.Token)); }