//<?xml version="1.0" encoding="utf-8"?>
        //<xml>
        //  <ToUserName><![CDATA[gh_a96a4a619366]]></ToUserName>
        //  <FromUserName><![CDATA[olPjZjsXuQPJoV0HlruZkNzKc91E]]></FromUserName>
        //  <CreateTime>1357986928</CreateTime>
        //  <MsgType><![CDATA[text]]></MsgType>
        //  <Content><![CDATA[中文]]></Content>
        //  <MsgId>5832509444155992350</MsgId>
        //</xml>

        /// <summary>
        /// 获取XDocument转换后的IRequestMessageBase实例。
        /// 如果MsgType不存在,抛出UnknownRequestMsgTypeException异常
        /// </summary>
        /// <returns></returns>
        public static IRequestMessageBase GetRequestEntity(XDocument doc, PostModel postModel = null)
        {
            RequestMessageBase requestMessage = null;
            RequestMsgType msgType;

            try
            {
                msgType = MsgTypeHelper.GetRequestMsgType(doc);
                switch (msgType)
                {
                    case RequestMsgType.TEXT:
                        requestMessage = new RequestMessageText();
                        break;
                    case RequestMsgType.LOCATION:
                        requestMessage = new RequestMessageLocation();
                        break;
                    case RequestMsgType.IMAGE:
                        requestMessage = new RequestMessageImage();
                        break;
                    case RequestMsgType.VOICE:
                        requestMessage = new RequestMessageVoice();
                        break;
                    case RequestMsgType.VIDEO:
                        requestMessage = new RequestMessageVideo();
                        break;
                    case RequestMsgType.LINK:
                        requestMessage = new RequestMessageLink();
                        break;
                    case RequestMsgType.SHORTVIDEO:
                        requestMessage = new RequestMessageShortVideo();
                        break;
                    case RequestMsgType.EVENT:
                        //判断Event类型
                        switch (doc.Root.Element("Event").Value.ToUpper())
                        {
                            case "ENTER"://进入会话
                                requestMessage = new RequestMessageEvent_Enter();
                                break;
                            case "LOCATION"://地理位置
                                requestMessage = new RequestMessageEvent_Location();
                                break;
                            case "SUBSCRIBE"://订阅(关注)
                                requestMessage = new RequestMessageEvent_Subscribe();
                                break;
                            case "UNSUBSCRIBE"://取消订阅(关注)
                                requestMessage = new RequestMessageEvent_Unsubscribe();
                                break;
                            case "CLICK"://菜单点击
                                requestMessage = new RequestMessageEvent_Click();
                                break;
                            case "SCAN"://二维码扫描
                                requestMessage = new RequestMessageEvent_Scan();
                                break;
                            case "VIEW"://URL跳转
                                requestMessage = new RequestMessageEvent_View();
                                break;
                            case "MASSSENDJOBFINISH":
                                requestMessage = new RequestMessageEvent_MassSendJobFinish();
                                break;
                            case "TEMPLATESENDJOBFINISH"://模板信息
                                requestMessage = new RequestMessageEvent_TemplateSendJobFinish();
                                break;
                            case "SCANCODE_PUSH"://扫码推事件(scancode_push)
                                requestMessage = new RequestMessageEvent_Scancode_Push();
                                break;
                            case "SCANCODE_WAITMSG"://扫码推事件且弹出“消息接收中”提示框(scancode_waitmsg)
                                requestMessage = new RequestMessageEvent_Scancode_Waitmsg();
                                break;
                            case "PIC_SYSPHOTO"://弹出系统拍照发图(pic_sysphoto)
                                requestMessage = new RequestMessageEvent_Pic_Sysphoto();
                                break;
                            case "PIC_PHOTO_OR_ALBUM"://弹出拍照或者相册发图(pic_photo_or_album)
                                requestMessage = new RequestMessageEvent_Pic_Photo_Or_Album();
                                break;
                            case "PIC_WEIXIN"://弹出微信相册发图器(pic_weixin)
                                requestMessage = new RequestMessageEvent_Pic_Weixin();
                                break;
                            case "LOCATION_SELECT"://弹出地理位置选择器(location_select)
                                requestMessage = new RequestMessageEvent_Location_Select();
                                break;
                            case "CARD_PASS_CHECK"://卡券通过审核
                                requestMessage = new RequestMessageEvent_Card_Pass_Check();
                                break;
                            case "CARD_NOT_PASS_CHECK"://卡券未通过审核
                                requestMessage = new RequestMessageEvent_Card_Not_Pass_Check();
                                break;
                            case "USER_GET_CARD"://领取卡券
                                requestMessage = new RequestMessageEvent_User_Get_Card();
                                break;
                            case "USER_DEL_CARD"://删除卡券
                                requestMessage = new RequestMessageEvent_User_Del_Card();
                                break;
                            case "KF_CREATE_SESSION"://多客服接入会话
                                requestMessage = new RequestMessageEvent_Kf_Create_Session();
                                break;
                            case "KF_CLOSE_SESSION"://多客服关闭会话
                                requestMessage = new RequestMessageEvent_Kf_Close_Session();
                                break;
                            case "KF_SWITCH_SESSION"://多客服转接会话
                                requestMessage = new RequestMessageEvent_Kf_Switch_Session();
                                break;
                            case "POI_CHECK_NOTIFY"://审核结果事件推送
                                requestMessage = new RequestMessageEvent_Poi_Check_Notify();
                                break;
                            case "WIFICONNECTED"://Wi-Fi连网成功事件
                                requestMessage = new RequestMessageEvent_WifiConnected();
                                break;
                            case "USER_CONSUME_CARD"://卡券核销
                                requestMessage = new RequestMessageEvent_User_Consume_Card();
                                break;
                            case "USER_ENTER_SESSION_FROM_CARD"://从卡券进入公众号会话
                                requestMessage = new RequestMessageEvent_User_Enter_Session_From_Card();
                                break;
                            case "USER_VIEW_CARD"://进入会员卡
                                requestMessage = new RequestMessageEvent_User_View_Card();
                                break;
                            case "MERCHANT_ORDER"://微小店订单付款通知
                                requestMessage = new RequestMessageEvent_Merchant_Order();
                                break;
                            case "SUBMIT_MEMBERCARD_USER_INFO"://接收会员信息事件通知
                                requestMessage = new RequestMessageEvent_Submit_Membercard_User_Info();
                                break;
                            case "SHAKEAROUNDUSERSHAKE"://摇一摇事件通知
                                requestMessage = new RequestMessageEvent_ShakearoundUserShake();
                                break;
                            default://其他意外类型(也可以选择抛出异常)
                                requestMessage = new RequestMessageEventBase();
                                break;
                        }
                        break;
                    default:
                        throw new UnknownRequestMsgTypeException(string.Format("MsgType:{0} 在RequestMessageFactory中没有对应的处理程序!", msgType), new ArgumentOutOfRangeException());//为了能够对类型变动最大程度容错(如微信目前还可以对公众账号suscribe等未知类型,但API没有开放),建议在使用的时候catch这个异常
                }
                EntityHelper.FillEntityWithXml(requestMessage, doc);
            }
            catch (ArgumentException ex)
            {
                throw new WeixinException(string.Format("RequestMessage转换出错!可能是MsgType不存在!,XML:{0}", doc.ToString()), ex);
            }
            return requestMessage;
        }
 /// <summary>
 /// 检查签名是否正确
 /// </summary>
 /// <param name="signature"></param>
 /// <param name="postModel">需要提供:Timestamp、Nonce、Token</param>
 /// <returns></returns>
 public static bool Check(string signature, PostModel postModel)
 {
     return Check(postModel.Timestamp, postModel.Nonce, postModel.Token);
 }
 /// <summary>
 /// 返回正确的签名
 /// </summary>
 /// <param name="postModel">需要提供:Timestamp、Nonce、Token</param>
 /// <returns></returns>
 public static string GetSignature(PostModel postModel)
 {
     return GetSignature(postModel.Timestamp, postModel.Nonce, postModel.Token);
 }
        public ActionResult Callback(PostModel postModel)
        {
            var logPath = Server.MapPath(string.Format("~/App_Data/Open/{0}/", DateTime.Now.ToString("yyyy-MM-dd")));
            if (!Directory.Exists(logPath))
            {
                Directory.CreateDirectory(logPath);
            }
            wx_openInfo wx_open = wx_openInfoService.instance().Single(new Guid(System.Configuration.ConfigurationManager.AppSettings["openID"]));
            postModel.EncodingAESKey = wx_open.open_sEncodingAESKey; //根据自己后台的设置保持一致
            postModel.AppId = wx_open.open_sAppID; //根据自己后台的设置保持一致
            postModel.Token = wx_open.open_sToken;
            var maxRecordCount = 10;
            MessageHandler<CustomMessageContext> messageHandler = null;
            try
            {
                var checkPublish = bool.Parse(System.Configuration.ConfigurationManager.AppSettings["checkPublish"]);// false; //是否在“全网发布”阶段
                if (checkPublish)
                {
                    messageHandler = new OpenCheckMessageHandler(Request.InputStream, postModel, 10);
                }
                else
                {
                    messageHandler = new CustomMessageHandler(Request.InputStream, postModel, maxRecordCount);
                }

                messageHandler.RequestDocument.Save(Path.Combine(logPath,
                    string.Format("{0}_Request_{1}.txt", DateTime.Now.Ticks, messageHandler.RequestMessage.FromUserName)));
                messageHandler.Execute(); //执行
                return new FixWeixinBugWeixinResult(messageHandler);
            }
            catch (Exception ex)
            {
                using (TextWriter tw = new StreamWriter(Server.MapPath("~/App_Data/Open/Error_" + DateTime.Now.Ticks + ".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();
                    return Content("");
                }
            }
        }