.NET微信公众号开发-4.0公众号消息处理

一.前言

微信公众平台的消息处理还是比较完善的,有最基本的文本消息,到图文消息,到图片消息,语音消息,视频消息,音乐消息其基本原理都是一样的,只不过所post的xml数据有所差别,在处理消息之前,我们要认真阅读,官方给我们的文档:http://mp.weixin.qq.com/wiki/14/89b871b5466b19b3efa4ada8e577d45e.html。首先我们从最基本的文本消息处理开始。

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
</xml>

我们可以看到这是消息处理的一个最基本的模式,有发送者,接受者,创建时间,类型,内容等等。

首先我们来创建一个消息处理的类,这个类用来捕获,所有的消息请求,根据不同的消息请求类型来处理不同的消息回复。

public class WeiXinService
    {
        /// <summary>
        /// TOKEN
        /// </summary>
        private const string TOKEN = "finder";
        /// <summary>
        /// 签名
        /// </summary>
        private const string SIGNATURE = "signature";
        /// <summary>
        /// 时间戳
        /// </summary>
        private const string TIMESTAMP = "timestamp";
        /// <summary>
        /// 随机数
        /// </summary>
        private const string NONCE = "nonce";
        /// <summary>
        /// 随机字符串
        /// </summary>
        private const string ECHOSTR = "echostr";
        /// <summary>
        ///
        /// </summary>
        private HttpRequest Request { get; set; }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="request"></param>
        public WeiXinService(HttpRequest request)
        {
            this.Request = request;
        }
        /// <summary>
        /// 处理请求,产生响应
        /// </summary>
        /// <returns></returns>
        public string Response()
        {
            string method = Request.HttpMethod.ToUpper();
            //验证签名
            if (method == "GET")
            {
                if (CheckSignature())
                {
                    return Request.QueryString[ECHOSTR];
                }
                else
                {
                    return "error";
                }
            }

            //处理消息
            if (method == "POST")
            {
                return ResponseMsg();
            }
            else
            {
                return "无法处理";
            }
        }

        /// <summary>
        /// 处理请求
        /// </summary>
        /// <returns></returns>
        private string ResponseMsg()
        {
            string requestXml = CommonWeiXin.ReadRequest(this.Request);
            IHandler handler = HandlerFactory.CreateHandler(requestXml);

            if (handler != null)
            {
                return handler.HandleRequest();
            }

            return string.Empty;
        }
        /// <summary>
        /// 检查签名
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        private bool CheckSignature()
        {
            string signature = Request.QueryString[SIGNATURE];
            string timestamp = Request.QueryString[TIMESTAMP];
            string nonce = Request.QueryString[NONCE];

            List<string> list = new List<string>();
            list.Add(TOKEN);
            list.Add(timestamp);
            list.Add(nonce);
            //排序
            list.Sort();
            //拼串
            string input = string.Empty;
            foreach (var item in list)
            {
                input += item;
            }
            //加密
            string new_signature = SecurityUtility.SHA1Encrypt(input);
            //验证
            if (new_signature == signature)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

在来看看我们的首先是如何捕获消息的。首页Default.ashx的代码如下

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/html";

            string postString = string.Empty;
            if (HttpContext.Current.Request.HttpMethod.ToUpper() == "POST")
            {
                //由微信服务接收请求,具体处理请求
                WeiXinService wxService = new WeiXinService(context.Request);
                string responseMsg = wxService.Response();
                context.Response.Clear();
                context.Response.Charset = "UTF-8";
                context.Response.Write(responseMsg);
                context.Response.End();
            }
            else
            {
                string token = "wei2414201";
                if (string.IsNullOrEmpty(token))
                {
                    return;
                }

                string echoString = HttpContext.Current.Request.QueryString["echoStr"];
                string signature = HttpContext.Current.Request.QueryString["signature"];
                string timestamp = HttpContext.Current.Request.QueryString["timestamp"];
                string nonce = HttpContext.Current.Request.QueryString["nonce"];

                if (!string.IsNullOrEmpty(echoString))
                {
                    HttpContext.Current.Response.Write(echoString);
                    HttpContext.Current.Response.End();
                }
            }

        }

从上面的代码中我们可以看到WeiXinService.cs类中的消息相应至关重要。

        /// <summary>
        /// 处理请求
        /// </summary>
        /// <returns></returns>
        private string ResponseMsg()
        {
            string requestXml = CommonWeiXin.ReadRequest(this.Request);
            IHandler handler = HandlerFactory.CreateHandler(requestXml);

            if (handler != null)
            {
                return handler.HandleRequest();
            }

            return string.Empty;
        }

IHandler是一个消息处理接口,其下面有EventHandler,TextHandler处理类实现这个接口。代码如下

    /// <summary>
    /// 处理接口
    /// </summary>
    public interface IHandler
    {
        /// <summary>
        /// 处理请求
        /// </summary>
        /// <returns></returns>
        string HandleRequest();
    }

EventHandler

class EventHandler : IHandler
    {
        /// <summary>
        /// 请求的xml
        /// </summary>
        private string RequestXml { get; set; }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="requestXml"></param>
        public EventHandler(string requestXml)
        {
            this.RequestXml = requestXml;
        }
        /// <summary>
        /// 处理请求
        /// </summary>
        /// <returns></returns>
        public string HandleRequest()
        {
            string response = string.Empty;
            EventMessage em = EventMessage.LoadFromXml(RequestXml);
            if (em.Event.Equals("subscribe", StringComparison.OrdinalIgnoreCase))//用来判断是不是首次关注
            {

                PicTextMessage tm = new PicTextMessage();//我自己创建的一个图文消息处理类
                tm.ToUserName = em.FromUserName;
                tm.FromUserName = em.ToUserName;
                tm.CreateTime = CommonWeiXin.GetNowTime();
                response = tm.GenerateContent();

            }

            return response;
        }
    }

TextHandler

    /// <summary>
    /// 文本信息处理类
    /// </summary>
    public class TextHandler : IHandler
    {
        string openid { get; set; }
        string access_token { get; set; }

        /// <summary>
        /// 请求的XML
        /// </summary>
        private string RequestXml { get; set; }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="requestXml">请求的xml</param>
        public TextHandler(string requestXml)
        {
            this.RequestXml = requestXml;
        }
        /// <summary>
        /// 处理请求
        /// </summary>
        /// <returns></returns>
        public string HandleRequest()
        {
            string response = string.Empty;
            TextMessage tm = TextMessage.LoadFromXml(RequestXml);
            string content = tm.Content.Trim();
            if (string.IsNullOrEmpty(content))
            {
                response = "您什么都没输入,没法帮您啊。";
            }
            else
            {
                    string username = System.Configuration.ConfigurationManager.AppSettings["weixinid"].ToString();
                    AccessToken token = AccessToken.Get(username);
                    access_token = token.access_token;
                    openid = tm.FromUserName;
                    response = HandleOther(content);

            }
            tm.Content = response;
            //进行发送者、接收者转换
            string temp = tm.ToUserName;
            tm.ToUserName = tm.FromUserName;
            tm.FromUserName = temp;
            response = tm.GenerateContent();
            return response;
        }
        /// <summary>
        /// 处理其他消息
        /// </summary>
        /// <param name="tm"></param>
        /// <returns></returns>
        private string HandleOther(string requestContent)
        {
            string response = string.Empty;
            if (requestContent.Contains("你好") || requestContent.Contains("您好"))
            {
                response = "您也好~";
            }else if (requestContent.Contains("openid") || requestContent.Contains("id") || requestContent.Contains("ID"))//用来匹配用户输入的关键字
            {
                response = "你的Openid: "+openid;
            }
            else if (requestContent.Contains("token") || requestContent.Contains("access_token"))
            {
                response = "你的access_token: " + access_token;
            }else
            {
                response = "试试其他关键字吧。";
            }
            return response;
        }
    }

HandlerFactory

    /// <summary>
    /// 处理器工厂类
    /// </summary>
    public class HandlerFactory
    {
        /// <summary>
        /// 创建处理器
        /// </summary>
        /// <param name="requestXml">请求的xml</param>
        /// <returns>IHandler对象</returns>
        public static IHandler CreateHandler(string requestXml)
        {
            IHandler handler = null;
            if (!string.IsNullOrEmpty(requestXml))
            {
                //解析数据
                XmlDocument doc = new System.Xml.XmlDocument();
                doc.LoadXml(requestXml);
                XmlNode node = doc.SelectSingleNode("/xml/MsgType");
                if (node != null)
                {
                    XmlCDataSection section = node.FirstChild as XmlCDataSection;
                    if (section != null)
                    {
                        string msgType = section.Value;

                        switch (msgType)
                        {
                            case "text":
                                handler = new TextHandler(requestXml);
                                break;
                            case "event":
                                handler = new EventHandler(requestXml);
                                break;
                        }
                    }
                }
            }

            return handler;
        }
    }

在这里基本的一些类已经完成了,现在我们来完成,关注我们的微信公众号,我们就发送一条图文消息,同时输入我们的一些关键字,返回一些消息,比如输入id返回用户的openid等等。

二.PicTextMessage

public class PicTextMessage : Message
    {
        /// <summary>
        /// 模板静态字段
        /// </summary>
        private static string m_Template;

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public PicTextMessage()
        {
            this.MsgType = "news";
        }
        /// <summary>
        /// 从xml数据加载文本消息
        /// </summary>
        /// <param name="xml"></param>
        public static PicTextMessage LoadFromXml(string xml)
        {
            PicTextMessage tm = null;
            if (!string.IsNullOrEmpty(xml))
            {
                XElement element = XElement.Parse(xml);
                if (element != null)
                {
                    tm = new PicTextMessage();
                    tm.FromUserName = element.Element(CommonWeiXin.FROM_USERNAME).Value;
                    tm.ToUserName = element.Element(CommonWeiXin.TO_USERNAME).Value;
                    tm.CreateTime = element.Element(CommonWeiXin.CREATE_TIME).Value;
                }
            }

            return tm;
        }
        /// <summary>
        /// 模板
        /// </summary>
        public override string Template
        {
            get
            {
                if (string.IsNullOrEmpty(m_Template))
                {
                    LoadTemplate();
                }

                return m_Template;
            }
        }
        /// <summary>
        /// 生成内容
        /// </summary>
        /// <returns></returns>
        public override string GenerateContent()
        {
            this.CreateTime = CommonWeiXin.GetNowTime();
            string str= string.Format(this.Template, this.ToUserName, this.FromUserName, this.CreateTime);
            return str;
        }

        /// <summary>
        /// 加载模板
        /// </summary>
        private static void LoadTemplate()
        {
            m_Template= @"<xml>
                            <ToUserName><![CDATA[{0}]]></ToUserName>
                            <FromUserName><![CDATA[{1}]]></FromUserName>
                            <CreateTime>{2}</CreateTime>
                            <MsgType><![CDATA[news]]></MsgType>
                            <ArticleCount>1</ArticleCount>
                            <Articles>
                                <item>
                                <Title><![CDATA[有位停车欢迎你!]]></Title>
                                <Description><![CDATA[如有问题请致电400-6238-136或直接在微信留言,我们将第一时间为您服务!]]></Description>
                                <PicUrl><![CDATA[http://www.baidu.com/youwei.jpg]]></PicUrl>
                                <Url><![CDATA[http://www.baidu.com]]></Url>
                                </item>
                            </Articles>
                        </xml> ";
        }
    }

最后我们的效果如下所示;

本人能力有限,希望大家多多包涵.

三.微信公众号开发系列导航

1.0初始微信公众号

2.0创建自定义菜单

3.0查询自定义菜单

4.0公众号消息处理

如果您看完本篇文章感觉不错,请点击左上角的【关注】来支持一下博主,谢谢!

如果您看完本篇文章感觉不错,请点击右下角的 【 推荐 】



作者:枫伶忆

QQ: 616931

出处:http://www.cnblogs.com/fenglingyi

声明:本文版权归作者和博客园共有,未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利


时间: 2024-10-09 06:54:10

.NET微信公众号开发-4.0公众号消息处理的相关文章

(转)微信公众平台开发 OAuth2.0网页授权

微信公众平台开发 OAuth2.0网页授权认证 网页授权获取用户基本信息 作者:方倍工作室 微信公众平台最近新推出微信认证,认证后可以获得高级接口权限,其中一个是OAuth2.0网页授权,很多朋友在使用这个的时候失败了或者无法理解其内容,希望我出个教程详细讲解一下,于是便有了这篇文章. 一.什么是OAuth2.0 官方网站:http://oauth.net/   http://oauth.net/2/ 权威定义:OAuth is An open protocol to allow secure

微信小程序(原名微信应用号)开发工具0.9版安装教程

微信小程序全称微信公众平台·小程序,原名微信公众平台·应用号(简称微信应用号) 声明 微信小程序开发工具类似于一个轻量级的IDE集成开发环境,目前仅开放给了少部分受微信官方邀请的人士(据说仅200个名额)进行内测,因此目前未受到邀请的人士只能使用破解版: 本破解版资源来自于网上,与本人无关,仅供技术开发人员研究之用: 由于尚属内测阶段,因此迭代更新非常快,后续很可能由于升级而导致暂时无法使用.   特别注意 由于目前发布的0.9版本必须验证才能登录(估计是为了验证是否为内测人士),因此必须先下载

金华兰溪义乌永康东阳微信小程序开发公司 天玑一号旺铺微信小程序

小公司开发自己的微信小程序是非常有必要的,下面上海微信小程序开发公司天玑[一号旺铺]就给大家说说开发自己的微信小程序会给大家带来什么好处.天玑金华.兰溪.义乌.永康.东阳微信小程序开发公司 天玑一号旺铺微信小程序开发报价咨询:http://www.wangpu1.com/全国免费热线:15058525901(微信同号) 小程序一定是基于 Html5+微信原生能力 的产品形态无需下载安装说明跟 App Store 的 APP 是不一样的,小程序是嵌在微信 APP 内的,微信提供标准化入口,当用户订

.NET微信公众号开发-5.0微信支付

一.前言 在开始做这个功能之前,我们要做的第一件事情就是思考,如何做这个微信支付,从哪里开始,从哪里入手,官方的sdk说明什么的,有没有什么官方的demo,还有就是老板给我的一些资料齐全不,那些要申请的接口什么的都有没有. 经过自己的一些探索,在老板的催促下终于硬着头皮做完了这个,很坑很坑的微信支付,在此做一些总结,希望对你们有所帮助,本人能力有限,如果有什么说的不好,希望大家多多包涵. 二.开发前准备. 1.0微信支付官方开发者文档 2.0官方demo下载 我们用c#所以选择.net版本 不过

.NET微信公众号开发-6.0模板消息

一.前言 为了保证用户不受到骚扰,在开发者出现需要主动提醒.通知用户时,才允许开发者在公众平台网站中模板消息库中选择模板,选择后获得模板ID,再根据模板ID向用户主动推送提醒.通知消息.这个意思也就是,我们作为微信商户,不能主动的给用户推送消息,如果这个功能完全开放,那么用户有可能会受到大量的垃圾信息,为了做一个很好的控制,微信那边给我们开放了一个模板消息,通过模板消息我们可以友好的给用户发送一些相关的消息提醒. 二.开发前的准备 1.0模板消息官方文档地址 2.0查看我们的模板消息是否申请成功

.NET微信公众号开发-2.0创建自定义菜单

一.前言 开发之前,我们需要阅读官方的接口说明文档,不得不吐槽一下,微信的这个官方文档真的很烂,但是,为了开发我们需要的功能,我们也不得不去看这些文档. 接口文档地址:http://mp.weixin.qq.com/wiki/13/43de8269be54a0a6f64413e4dfa94f39.html 看了这些个文档,基本意思明白了,就是我们把我们要创建的菜单创建好,post到微信的服务器上面,微信服务器然后给我们一些状态码,从而判断我们的菜单是否创建成功,只是在发送json数据以前我们要做

NET微信公众号开发-5.0微信支付(待测试)

开发前准备. 1.0微信支付官方开发者文档 2.0官方demo下载 我们用c#所以选择.net版本 不过这个官方的demo根本跑步起来 3.0官方demo运行起来解决方案 4.0微信支付官方.net版之坑你没商量 5.0开发前的微信公众平台的一些配置,请务必认真检查配置. 编码 做好了这些准备工作之后,我们知道微信支付有两种,1.原生态的,2.jsapi直接调用的,我项目中用到的是第二种 经过自己的一些业务逻辑处理,来到了我们的订单详情页面,现在需要去点击我们的支付按钮去支付,支付页面pay.a

微信小程序开发由0到1开发,快速开发上线

首先先注册微信小程序管理 一.登录微信公众平台https://mp.weixin.qq.com 二.点击立即注册. 注意:这里不要用微信公众号登录,小程序账号和微信公众号是不同的. 三.在注册页面点击小程序板块. 四.进入小程序注册页面.已经有小程序账号的可以直接登录. 五.注册成功后登录邮箱激活小程序账号. 六.激活后进入小程序身份信息登记,按要求填写好自己的个人/企业/组织等身份信息,通过后确认即可. 七.完成前期账号注册和认证后,即可进入小程序管理页面 点击查看腾讯官方3元购小程序购买 在

微信公众平台开发 OAuth2.0网页授权认证

一.什么是OAuth2.0 官方网站:http://oauth.net/   http://oauth.net/2/ 权威定义:OAuth is An open protocol to allow secure authorization in a simple and standard method from web, mobile and desktop applications. OAuth是一个开放协议,允许用户让第三方应用以安全且标准的方式获取该用户在某一网站.移动或桌面应用上存储的私