使用反射根据消息类型自动调用不同方法
微信只会向我们一个地方推送消息,如果全部逻辑都写到一起,代码会非常多,所以我们可以通过消息类型, 来实现不同的消息类型使用不同的处理方法,降低代码的耦合性
先定义一个用于处理请求的基类
/// <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);
}
}
效果如下
原文地址:http://www.tnblog.net/aojiancc2/article/details/227