剑轩

微信开发:使用反射+虚函数的方式分散处理微信不同消息类型

电脑版发表于:2019/1/18 10:11

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

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


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

    public class BaseProcess
    {
        protected string ToUserName = "";
        protected string FromUserName = "";
        protected string MsgType = "";

        /// <summary>
        /// 解析公共参数的方法
        /// </summary>
        /// <param name="root"></param>
        public void DealCommonParameter(XElement root)
        {
            ToUserName = root.Element("ToUserName").Value;
            FromUserName = root.Element("FromUserName").Value;
            MsgType = root.Element("MsgType").Value;
        }

        /// <summary>
        /// 处理微信消息的虚函数
        /// </summary>
        /// <param name="root"></param>
        /// <param name="Response"></param>
        public virtual void Process(XElement root, HttpResponseBase Response)
        {

        }
    }


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


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

    public class EventProcess : BaseProcess
    {
        public override void Process(XElement root, HttpResponseBase Response)
        {
            string Event = root.Element("Event").Value;

            if (Event == "CLICK")
            {
                string EventKey = root.Element("EventKey").Value;
                if (EventKey == "wx_menu_net")
                {
                    Response.Write(WXTools.SendNewsMsg(ToUserName, FromUserName));
                    Response.End();
                }
                else if (EventKey == "wx_menu_python")
                {
                    Response.Write(WXTools.SendTextMsg(ToUserName, FromUserName, "你点击了python"));
                    Response.End();
                }
                else
                {
                    Response.Write(WXTools.SendTextMsg(ToUserName, FromUserName, "你点击了事件"));
                    Response.End();
                }
            }

        }
    }

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

    /// <summary>
    /// 处理文本消息
    /// </summary>
    public class TextProcess : BaseProcess
    {
        public override void Process(XElement root, HttpResponseBase Response)
        {
            string content = root.Element("Content").Value;
            //关键字回复
            if (content.Contains("姐姐"))
            {
                Response.Write(WXTools.SendImgMsg(ToUserName, FromUserName, "q6yc_ZO"));
                Response.End();
            }
            if (content.Contains("视频") || content.Contains("教程") || content.Contains("微信"))
            {
                Response.Write(WXTools.SendVedioMsg(ToUserName, FromUserName, "q6yc_ZOszJbRSKad74", "视频教程", "这是一个微信开发视频教程"));
                Response.End();
            }
            if (content.Contains("图文"))
            {
                Response.Write(WXTools.SendNewsMsg(ToUserName, FromUserName));
                Response.End();
            }
            else
            {
                //记录一下日志
                LogTools.WriteLog(content, "接收到文本消息");
                Response.Write(WXTools.SendTextMsg(ToUserName, FromUserName, content));
                Response.End();
            }
        }
    }

在如处理图片消息的类:

    public class ImageProcess : BaseProcess
    {
        public override void Process(XElement root, HttpResponseBase Response)
        {
            string MediaId = root.Element("MediaId").Value;
            //记录一下日志
            //LogTools.WriteLog(PicUrl, "接收到图片消息");

            Response.Write(WXTools.SendImgMsg(ToUserName, FromUserName, MediaId));
            Response.End();
        }
    }

结构如图:


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

/// <summary>
/// 微信推送统一入口
/// </summary>
public void Index()
{
    //获取微信推送的内容
    StreamReader reader = new StreamReader(Request.InputStream);
    string xml = reader.ReadToEnd();
    if (string.IsNullOrEmpty(xml))
    {
        return;
    }
    //解析xml,获取xml里边的具体值
    XElement root = XElement.Parse(xml);

    //首字母转大写
    string MsgType = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(root.Element("MsgType").Value);

    //根据不同的消息类型,通过反射去找到不同类的处理方法
    //反射创建对象
    object obj = Activator.CreateInstance(Type.GetType("MvcApplication2.Process." + MsgType + "Process"));

    //父类提供公共参数
    obj.GetType().GetMethod("DealCommonParamter").Invoke(obj, new object[] { root });
    //调用具体的处理方法
    obj.GetType().GetMethod("Process").Invoke(obj, new object[] { root, Response });
}

当然公共参数的处理也可以直接封装到一个对象,然后反射调用方法的时候多传一个即可。







关于TNBLOG
TNBLOG,技术分享。技术交流:群号677373950
ICP备案 :渝ICP备18016597号-1
App store Android
精彩评论
{{item.replyName}}
{{item.content}}
{{item.time}}
{{subpj.replyName}}
@{{subpj.beReplyName}}{{subpj.content}}
{{subpj.time}}
猜你喜欢