tnblog
首页

微信开发三 使用反射根据消息类型自动调用不同方法

96人阅读 2019/1/16 21:56 评论:0 收藏
分类: 微信


微信只会向我们一个地方推送消息,如果全部逻辑都写到一起,代码会非常多。

所以我们可以考虑通过消息类型,来实现不同的消息类型调用不同的处理方法,降低代码的耦合性,

类似这种需求反射就是一种比较科学的方式。


先定义一个用于处理请求的基类       

    /// <summary>
    /// 处理微信请求的基类
    /// </summary>
    public class BaseProcess
    {       
        //处理微信请求的虚方法
        public virtual void Process(XElement xl, HttpRequestBase _request, HttpResponseBase _response)
        {
 
        }
    }

 

然后不同的处理方法都去实现这个基类

例如:处理事件请求的处理方法 (消息类型为event)   

 /// <summary>
    /// 处理用户点击的事件处理方法
    /// </summary
    public class EventProcess : BaseProcess
    {
        public override void Process(XElement xl, HttpRequestBase _request, HttpResponseBase _response)
        {
            _response.Write("我是处理事件的请求方法");
            _response.End();
        }
    }

如:处理用户发送的文本消息方法(消息类型为text)      

    /// <summary>
    /// 处理用户发送的文本消息方法
    /// </summary>
    public class TextProcess : BaseProcess
    {
 
        public override void Process(XElement xl, HttpRequestBase _request, HttpResponseBase _response)
        {
            _response.Write("这是处理用户发送的文本信息");
            _response.End();
        }
    }

如图:


然后在入口点用反射处理下就行了     

  /// <summary>
        /// 处理微信的请求
        /// </summary>
        public JsonResult Index()
        {
            try
            {
                //读取微信发送的xml数据
                StreamReader reader = new StreamReader(Request.InputStream);
                string xmldata = reader.ReadToEnd();
                XElement xl = XElement.Parse(xmldata);
 
                //取出消息类型
                string MsgType = xl.Elements().Where(a => a.Name == "MsgType").FirstOrDefault().Value;
 
                //把微信推送的请求类型首字母转大写
                MsgType = FirstToUpper(MsgType);
                //得到需要的类型
                Type needtype = Type.GetType("MvcApplication1.Process." + MsgType + "Process");
                //通过反射调用实例化对应的处理类
                BaseProcess process = Activator.CreateInstance(needtype) as BaseProcess;
                //调用处理方法
                process.Process(xl, Request, Response);
          
                 
                return Json("请求成功");
            }
            catch (Exception e) 
            {
                //请求失败进行日志记录...略         
                return Json("请求失败");
            }
        }

我们把用户点击的菜单事件真正实现以下    

 /// <summary>
    /// 处理用户点击的事件处理方法
    /// </summary
    public class EventProcess : BaseProcess
    {
        public override void Process(XElement xl, HttpRequestBase _request, HttpResponseBase _response)
        {
            //取出消息类型
            string MsgType = xl.Elements().Where(a => a.Name == "MsgType").FirstOrDefault().Value;
 
            string ToUserName = xl.Elements().Where(a => a.Name == "ToUserName").FirstOrDefault().Value;
            string FromUserName = xl.Elements().Where(a => a.Name == "FromUserName").FirstOrDefault().Value;
 
            //取出事件标识
            string EventKey = xl.Elements().Where(a => a.Name == "EventKey").FirstOrDefault().Value;
            string Event = xl.Elements().Where(a => a.Name == "Event").FirstOrDefault().Value;
 
 
            //消息类型为空就没必要记录日志了
            if (!string.IsNullOrEmpty(MsgType))
            {
                AddLog(EventKey, MsgType, Event, ToUserName, FromUserName);
            }
 
            //用户推送的是一个事件请求
            ReMsgModel rsm = new ReMsgModel();
 
            rsm.MsgType = MsgType;
            rsm.Content = "用户点击了菜单按钮";
            rsm.ToUserName = FromUserName;
            rsm.FromUserName = ToUserName;
            GetTextMesXml(_response, rsm);
        }
    }

效果如下



评价

{{item.title}}

{{item.content}}
断剑重铸之日,骑士归来之时
博主搜索
文章类别
最新文章
最新评价
{{item.ArticleTitle}}
{{item.BlogName}} : {{item.Content}}