一.前言

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

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime></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公众号消息处理

5.0微信支付

6.0模板消息

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

  1. 微信公众平台开发-OAuth2.0网页授权(含源码)

    微信公众平台开发-OAuth2.0网页授权接口.网页授权接口详解(含源码)作者: 孟祥磊-<微信公众平台开发实例教程> 在微信开发的高级应用中,几乎都会使用到该接口,因为通过该接口,可以获 ...

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

    微信公众平台开发 OAuth2.0网页授权认证 网页授权获取用户基本信息 作者:方倍工作室 微信公众平台最近新推出微信认证,认证后可以获得高级接口权限,其中一个是OAuth2.0网页授权,很多朋友在使 ...

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

    微信小程序全称微信公众平台·小程序,原名微信公众平台·应用号(简称微信应用号) 声明 微信小程序开发工具类似于一个轻量级的IDE集成开发环境,目前仅开放给了少部分受微信官方邀请的人士(据说仅200个名 ...

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

    开发前准备. 1.0微信支付官方开发者文档 2.0官方demo下载 我们用c#所以选择.net版本 不过这个官方的demo根本跑步起来 3.0官方demo运行起来解决方案 4.0微信支付官方.net版 ...

  5. .NET微信公众号开发-1.0初始微信公众号

    一.前言 微信公众号是开发者或商家在微信公众平台上申请的应用账号,该帐号与QQ账号互通,通过公众号,商家可在微信平台上实现和特定群体的文字.图片.语音.视频的全方位沟通.互动 .形成了一 种主流的线上 ...

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

    一.前言 开发之前,我们需要阅读官方的接口说明文档,不得不吐槽一下,微信的这个官方文档真的很烂,但是,为了开发我们需要的功能,我们也不得不去看这些文档. 接口文档地址:http://mp.weixin ...

  7. .NET微信公众号开发-3.0查询自定义菜单

    一.前言 前面我们已经创建好了我们的自定义菜单.那么我们现在要如何查询我们自定义的菜单.原理都是一样的,而且都是相当简单,只是接口地址文档换掉了. 2.0开始编码 同样我们首先创建好我的查询页面,在这 ...

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

    一.前言 在开始做这个功能之前,我们要做的第一件事情就是思考,如何做这个微信支付,从哪里开始,从哪里入手,官方的sdk说明什么的,有没有什么官方的demo,还有就是老板给我的一些资料齐全不,那些要申请 ...

  9. 基于.net5 wtm框架、uni-app微信公众号开发一、公众号授权

    前端公众号授权 公众号设置 0.首先用IIS创建一个空目录的网站用于公众号域名验证,接着把该网站内网穿透出去,推荐用utools工具,官网:https://u.tools/ 下载安装好后搜索内网穿透并 ...

随机推荐

  1. .Net程序员必须要知道的东西之HttpModules与HttpHandlers介绍

    一.ASP.NET对请求处理的过程: 当客户端请求一个*.aspx文件的时候,这个请求会被inetinfo.exe进程截获,它判断文件的后缀(aspx)之后,将这个请求转交给ASPNET_ISAPI. ...

  2. TP3.1 中URL和APP区别

    1.__URL__指当前模块地址,就是当前的action的地址.(每个__action都是一个模块)    eg:当前打开config.html,那么config.html里边的__URL__/sav ...

  3. 微信将推指纹支付 "指付通"会与Touch ID整合吗

    有消息称微信下一版本将推指纹支付“指付通”,解决手机丢失资金安全的问题(这个应该是针对阿里手机支付的弱点),到时候用户绑定的银行卡进行付款时,不用输入密码只需在专门的支付设备(苹果Touch ID ? ...

  4. 决策树-预测隐形眼镜类型 (ID3算法,C4.5算法,CART算法,GINI指数,剪枝,随机森林)

    1. 1.问题的引入 2.一个实例 3.基本概念 4.ID3 5.C4.5 6.CART 7.随机森林 2. 我们应该设计什么的算法,使得计算机对贷款申请人员的申请信息自动进行分类,以决定能否贷款? ...

  5. Swift2.1 语法指南——可空链式调用

    原档:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programmi ...

  6. 关于CSS的优先级,CSS优先级计算

    原则一: 继承不如指定原则二: #id > .class > 标签选择符原则三:越具体越强大原则四:标签#id >#id ; 标签.class > .class CSS优先级权 ...

  7. MySQL Python教程(4)

    Class cursor.MySQLCursorBuffered 该类从Class cursor.MySQLCursorBuffered继承,如果需要,可以在执行完SQL语句后自动缓冲结果集合.imp ...

  8. js搜索框输入提示(高效-ys8)

    <style type="text/css"> .inputbox .seleDiv { border: 1px solid #CCCCCC; display: non ...

  9. nodejs,node原生服务器搭建实例

    nodejs,node原生服务器搭建实例

  10. CMake Error: your CXX compiler: "" was not found

    [root@amax src]# cmake . -- The CXX compiler identification is unknown CMake Error at /usr/local/sha ...