PageRenderTime 23ms CodeModel.GetById 14ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

/Senparc.Weixin.MP/Senparc.Weixin.MP/MessageHandlers/MessageHandler.cs

https://github.com/mjhuangzk/WeiXinMPSDK
C# | 340 lines | 192 code | 42 blank | 106 comment | 16 complexity | 32a6fa17fb7b47f0a40244fbc30f9c58 MD5 | raw file
  1using System;
  2using System.Collections.Generic;
  3using System.IO;
  4using System.Linq;
  5using System.Text;
  6using System.Xml;
  7using System.Xml.Linq;
  8using Senparc.Weixin.MP.Context;
  9using Senparc.Weixin.MP.Entities;
 10using Senparc.Weixin.MP.Helpers;
 11
 12namespace Senparc.Weixin.MP.MessageHandlers
 13{
 14    public interface IMessageHandler
 15    {
 16        /// <summary>
 17        /// 发送者用户名(OpenId)
 18        /// </summary>
 19        string WeixinOpenId { get; }
 20
 21        /// <summary>
 22        /// 取消执行Execute()方法。一般在OnExecuting()中用于临时阻止执行Execute()。
 23        /// 默认为False。
 24        /// 如果在执行OnExecuting()执行前设为True,则所有OnExecuting()、Execute()、OnExecuted()代码都不会被执行。
 25        /// 如果在执行OnExecuting()执行过程中设为True,则后续Execute()及OnExecuted()代码不会被执行。
 26        /// </summary>
 27        bool CancelExcute { get; set; }
 28
 29        /// <summary>
 30        /// 在构造函数中转换得到原始XML数据
 31        /// </summary>
 32        XDocument RequestDocument { get; set; }
 33
 34        /// <summary>
 35        /// 根据ResponseMessageBase获得转换后的ResponseDocument
 36        /// 注意:这里每次请求都会根据当前的ResponseMessageBase生成一次,如需重用此数据,建议使用缓存或局部变量
 37        /// </summary>
 38        XDocument ResponseDocument { get; }
 39
 40        /// <summary>
 41        /// 请求实体
 42        /// </summary>
 43        IRequestMessageBase RequestMessage { get; set; }
 44        /// <summary>
 45        /// 响应实体
 46        /// 只有当执行Execute()方法后才可能有值
 47        /// </summary>
 48        IResponseMessageBase ResponseMessage { get; set; }
 49    }
 50
 51    /// <summary>
 52    /// 微信请求的集中处理方法
 53    /// 此方法中所有过程,都基于Senparc.Weixin.MP的基础功能,只为简化代码而设。
 54    /// </summary>
 55    public abstract class MessageHandler<TC> : IMessageHandler where TC : class, IMessageContext, new()
 56    {
 57        /// <summary>
 58        /// 上下文
 59        /// </summary>
 60        public static WeixinContext<TC> GlobalWeixinContext = new WeixinContext<TC>();
 61
 62        /// <summary>
 63        /// 全局消息上下文
 64        /// </summary>
 65        public WeixinContext<TC> WeixinContext
 66        {
 67            get { return GlobalWeixinContext; }
 68        }
 69
 70        /// <summary>
 71        /// 当前用户消息上下文
 72        /// </summary>
 73        public TC CurrentMessageContext
 74        {
 75            get { return WeixinContext.GetMessageContext(RequestMessage); }
 76        }
 77
 78        /// <summary>
 79        /// 发送者用户名(OpenId)
 80        /// </summary>
 81        public string WeixinOpenId
 82        {
 83            get
 84            {
 85                if (RequestMessage != null)
 86                {
 87                    return RequestMessage.FromUserName;
 88                }
 89                return null;
 90            }
 91        }
 92
 93        /// <summary>
 94        /// 
 95        /// </summary>
 96        [Obsolete("UserName属性从v0.6起已过期,建议使用WeixinOpenId")]
 97        public string UserName
 98        {
 99            get
100            {
101                return WeixinOpenId;
102            }
103        }
104
105        /// <summary>
106        /// 取消执行Execute()方法。一般在OnExecuting()中用于临时阻止执行Execute()。
107        /// 默认为False。
108        /// 如果在执行OnExecuting()执行前设为True,则所有OnExecuting()、Execute()、OnExecuted()代码都不会被执行。
109        /// 如果在执行OnExecuting()执行过程中设为True,则后续Execute()及OnExecuted()代码不会被执行。
110        /// </summary>
111        public bool CancelExcute { get; set; }
112
113        /// <summary>
114        /// 在构造函数中转换得到原始XML数据
115        /// </summary>
116        public XDocument RequestDocument { get; set; }
117
118        /// <summary>
119        /// 根据ResponseMessageBase获得转换后的ResponseDocument
120        /// 注意:这里每次请求都会根据当前的ResponseMessageBase生成一次,如需重用此数据,建议使用缓存或局部变量
121        /// </summary>
122        public XDocument ResponseDocument
123        {
124            get
125            {
126                if (ResponseMessage == null)
127                {
128                    return null;
129                }
130                return EntityHelper.ConvertEntityToXml(ResponseMessage as ResponseMessageBase);
131            }
132        }
133
134        //protected Stream InputStream { get; set; }
135        /// <summary>
136        /// 请求实体
137        /// </summary>
138        public IRequestMessageBase RequestMessage { get; set; }
139        /// <summary>
140        /// 响应实体
141        /// 只有当执行Execute()方法后才可能有值
142        /// </summary>
143        public IResponseMessageBase ResponseMessage { get; set; }
144
145        public MessageHandler(Stream inputStream)
146        {
147            using (XmlReader xr = XmlReader.Create(inputStream))
148            {
149                RequestDocument = XDocument.Load(xr);
150                Init(RequestDocument);
151            }
152        }
153
154        public MessageHandler(XDocument requestDocument)
155        {
156            Init(requestDocument);
157        }
158
159        private void Init(XDocument requestDocument)
160        {
161            RequestDocument = requestDocument;
162            RequestMessage = RequestMessageFactory.GetRequestEntity(RequestDocument);
163
164            //记录上下文
165            if (WeixinContextGlobal.UseWeixinContext)
166            {
167                WeixinContext.InsertMessage(RequestMessage);
168            }
169        }
170
171        /// <summary>
172        /// 根据当前的RequestMessage创建指定类型的ResponseMessage
173        /// </summary>
174        /// <typeparam name="TR">基于ResponseMessageBase的响应消息类型</typeparam>
175        /// <returns></returns>
176        public TR CreateResponseMessage<TR>() where TR : ResponseMessageBase
177        {
178            if (RequestMessage == null)
179            {
180                return null;
181            }
182
183            return RequestMessage.CreateResponseMessage<TR>();
184        }
185
186        /// <summary>
187        /// 执行微信请求
188        /// </summary>
189        public void Execute()
190        {
191            if (CancelExcute)
192            {
193                return;
194            }
195
196            OnExecuting();
197
198            if (CancelExcute)
199            {
200                return;
201            }
202
203            try
204            {
205                if (RequestMessage == null)
206                {
207                    return;
208                }
209
210                switch (RequestMessage.MsgType)
211                {
212                    case RequestMsgType.Text:
213                        ResponseMessage = OnTextRequest(RequestMessage as RequestMessageText);
214                        break;
215                    case RequestMsgType.Location:
216                        ResponseMessage = OnLocationRequest(RequestMessage as RequestMessageLocation);
217                        break;
218                    case RequestMsgType.Image:
219                        ResponseMessage = OnImageRequest(RequestMessage as RequestMessageImage);
220                        break;
221                    case RequestMsgType.Voice:
222                        ResponseMessage = OnVoiceRequest(RequestMessage as RequestMessageVoice);
223                        break;
224                    case RequestMsgType.Event:
225                        ResponseMessage = OnEventRequest(RequestMessage as RequestMessageEventBase);
226                        break;
227                    default:
228                        throw new UnknownRequestMsgTypeException("未知的MsgType请求类型", null);
229                }
230
231                //记录上下文
232                if (WeixinContextGlobal.UseWeixinContext && ResponseMessage != null)
233                {
234                    WeixinContext.InsertMessage(ResponseMessage);
235                }
236            }
237            catch (Exception ex)
238            {
239                throw ex;
240            }
241            finally
242            {
243                OnExecuted();
244            }
245        }
246
247        public virtual void OnExecuting()
248        {
249        }
250
251        public virtual void OnExecuted()
252        {
253        }
254
255
256        /// <summary>
257        /// 文字类型请求
258        /// </summary>
259        public abstract IResponseMessageBase OnTextRequest(RequestMessageText requestMessage);
260
261        /// <summary>
262        /// 位置类型请求
263        /// </summary>
264        public abstract IResponseMessageBase OnLocationRequest(RequestMessageLocation requestMessage);
265
266        /// <summary>
267        /// 图片类型请求
268        /// </summary>
269        public abstract IResponseMessageBase OnImageRequest(RequestMessageImage requestMessage);
270
271        /// <summary>
272        /// 语音类型请求
273        /// </summary>
274        public abstract IResponseMessageBase OnVoiceRequest(RequestMessageVoice requestMessage);
275
276        /// <summary>
277        /// 链接消息类型请求
278        /// </summary>
279        public abstract IResponseMessageBase OnLinkRequest(RequestMessageLink requestMessage);
280
281        /// <summary>
282        /// Event事件类型请求
283        /// </summary>
284        public virtual IResponseMessageBase OnEventRequest(RequestMessageEventBase requestMessage)
285        {
286            var strongRequestMessage = RequestMessage as IRequestMessageEventBase;
287            IResponseMessageBase responseMessage = null;
288            switch (strongRequestMessage.Event)
289            {
290                case Event.ENTER:
291                    responseMessage = OnEvent_EnterRequest(RequestMessage as RequestMessageEvent_Enter);
292                    break;
293                case Event.LOCATION:
294                    responseMessage = OnEvent_LocationRequest(RequestMessage as RequestMessageEvent_Location);//目前实际无效
295                    break;
296                case Event.subscribe://订阅
297                    responseMessage = OnEvent_SubscribeRequest(RequestMessage as RequestMessageEvent_Subscribe);
298                    break;
299                case Event.unsubscribe://退订
300                    responseMessage = OnEvent_UnsubscribeRequest(RequestMessage as RequestMessageEvent_Unsubscribe);
301                    break;
302                case Event.CLICK:
303                    responseMessage = OnEvent_ClickRequest(RequestMessage as RequestMessageEvent_Click);
304                    break;
305                default:
306                    throw new UnknownRequestMsgTypeException("未知的Event下属请求信息", null);
307            }
308            return responseMessage;
309        }
310
311        #region Event 下属分类
312
313        /// <summary>
314        /// Event事件类型请求之ENTER
315        /// </summary>
316        public abstract IResponseMessageBase OnEvent_EnterRequest(RequestMessageEvent_Enter requestMessage);
317
318        /// <summary>
319        /// Event事件类型请求之LOCATION
320        /// </summary>
321        public abstract IResponseMessageBase OnEvent_LocationRequest(RequestMessageEvent_Location requestMessage);
322
323        /// <summary>
324        /// Event事件类型请求之subscribe
325        /// </summary>
326        public abstract IResponseMessageBase OnEvent_SubscribeRequest(RequestMessageEvent_Subscribe requestMessage);
327
328        /// <summary>
329        /// Event事件类型请求之unsubscribe
330        /// </summary>
331        public abstract IResponseMessageBase OnEvent_UnsubscribeRequest(RequestMessageEvent_Unsubscribe requestMessage);
332
333        /// <summary>
334        /// Event事件类型请求之CLICK
335        /// </summary>
336        public abstract IResponseMessageBase OnEvent_ClickRequest(RequestMessageEvent_Click requestMessage);
337
338        #endregion
339    }
340}