[转载]asp.net开发微信公众平台(3)微信消息封装及反射赋值 – 沫尘 – 博客园.
上一篇已经搭建好整体框架,实现了入口的验证, 验证通过后就交给LookMsgType方法处理,LookMsgType方法主要是对微信发来的不同的消息进行分解,不同的类型交给业务逻辑层不同的方法处理, 对不同类型的消息判断,可以用if,也可以用switch 一般来说超过5个的if用switch会更好, 这里贴出LookMsgType方法:
public void LookMsgType( string msgType) { #region 判断消息类型 switch (msgType) { case "text" : RText mText = new RText(); mText = ReadXml.GetModel(mText, xmlModel); BLLWei.DoText(dbHome, mText); //文本消息 break ; case "image" : RImg mImg = new RImg(); mImg = ReadXml.GetModel(mImg, xmlModel); BLLWei.DoImg(dbHome,mImg); //图片 break ; case "voice" : //声音 RVoice mVoice = new RVoice(); mVoice = ReadXml.GetModel(mVoice, xmlModel); BLLWei.DoVoice(dbHome,mVoice); break ; case "video" : //视频 RVideo mVideo = new RVideo(); mVideo = ReadXml.GetModel(mVideo, xmlModel); BLLWei.DoVideo(dbHome, mVideo); break ; case "location" : //地理位置 RLocation mLocation = new RLocation(); mLocation = ReadXml.GetModel(mLocation, xmlModel); BLLWei.DoLocation(dbHome,mLocation); break ; case "link" : //链接 RLink mLink = new RLink(); mLink = ReadXml.GetModel(mLink, xmlModel); BLLWei.DoLink(dbHome,mLink); break ; #region 事件 case "event" : switch (ReadXml.ReadModel( "Event" , xmlModel)) { case "subscribe" : if (ReadXml.ReadModel( "EventKey" , xmlModel).IndexOf( "qrscene_" ) >= 0) { RCodeNotSub mNotSub = new RCodeNotSub(); mNotSub = ReadXml.GetModel(mNotSub, xmlModel); BLLWei.DoCodeNotSub(dbHome,mNotSub); //未关注的新用户,扫描带参数的二维码关注 } else { RSub mSub = new RSub(); mSub = ReadXml.GetModel(mSub, xmlModel); BLLWei.DoSub(dbHome,mSub); //普通关注 } break ; case "unsubscribe" : RUnsub mUnSub = new RUnsub (); mUnSub = ReadXml.GetModel(mUnSub, xmlModel); BLLWei.DoUnSub(dbHome,mUnSub); //取消关注 break ; case "SCAN" : RCodeSub mCodeSub = new RCodeSub(); mCodeSub = ReadXml.GetModel(mCodeSub, xmlModel); BLLWei.DoCodeSub(dbHome,mCodeSub); //已经关注的用户扫描带参数的二维码 break ; case "LOCATION" : //用户上报地理位置 RSubLocation mSubLoc = new RSubLocation(); mSubLoc = ReadXml.GetModel(mSubLoc, xmlModel); BLLWei.DoSubLocation(dbHome, mSubLoc); break ; case "CLICK" : //自定义菜单点击 RMenuClick mMenuClk = new RMenuClick(); mMenuClk = ReadXml.GetModel(mMenuClk, xmlModel); BLLWei.DoMenuClick(dbHome, mMenuClk); break ; case "VIEW" : //自定义菜单跳转事件 RMenuView mMenuVw = new RMenuView(); mMenuVw = ReadXml.GetModel(mMenuVw, xmlModel); BLLWei.DoMenuView(dbHome, mMenuVw); break ; }; break ; #endregion } #endregion } |
外层switch判断msgtype, 在event类型时,再次switch判断具体的事件类型(关注、取消关注、自定义菜单事件等), 至此所有的微信发来的消息都有处理了,在上面代码中用到消息模型以及ReadXml.GetModel方法给模型赋值, 赋值之后传递给业务逻辑层对应的方法处理, 下面写出消息封装和给模型赋值的方法。
1、消息封装:
对所有微信发来的消息进行封装, 在datamodel中建一个Receive文件夹和一个send文件夹,在其中分别建立对应消息的类,完成之后,完整的datamodel类库如下图:
举例
—–接收消息:
文本消息RText.cs
public class RText { public string ToUserName { get ; set ; } // 开发者微信号 public string FromUserName { get ; set ; } // 用户号(OpenID) public long CreateTime { get ; set ; } // 创建时间 public string MsgType { get ; set ; } //消息类型 public string Content { get ; set ; } //内容 public long MsgId { get ; set ; } //消息ID } |
自定义菜单点击RMenuClick.cs
public class RMenuClick { public string ToUserName { get ; set ; } // 开发者微信号 public string FromUserName { get ; set ; } // 用户号(OpenID) public long CreateTime { get ; set ; } // 创建时间 public string MsgType { get ; set ; } //消息类型 public string Event { get ; set ; } //事件类型 public string EventKey { get ; set ; } //事件key } |
其他也都类似,不一一列举。
—–发送消息
发送文本消息SText.cs
public class SText { public string ToUserName { get ; set ; } // 用户号(OpenID) public string FromUserName { get ; set ; } // 开发者微信号 public long CreateTime { get ; set ; } // 创建时间 public string MsgType { get { return "text" ; } } //消息类型 public string Content { get ; set ; } //内容 } SText |
发送图文消息SNews.cs
namespace DataModel.Send { public class SNews { public string ToUserName { get ; set ; } // 用户号(OpenID) public string FromUserName { get ; set ; } // 开发者微信号 public long CreateTime { get ; set ; } // 创建时间 public string MsgType { get { return "news" ; } } //消息类型 public int ArticleCount { get ; set ; } //图文个数 public List<ArticlesModel> Articles { get ; set ; } //图文列表 } public class ArticlesModel //默认第一条大图显示 { public string Title { get ; set ; } //标题 public string Description { get ; set ; } //描述 public string PicUrl { get ; set ; } //图片链接 public string Url { get ; set ; } //点击之后跳转的链接 } } 发送图文消息 |
在发送图文消息中,因为回复给微信的图文消息中,具体的图文内容是多条(最多可以10条),所以单独会有ArticlesModel。 后面文章会写出图文消息的发送。
2、通过反射给model赋值
在上篇文章写的入口处,已经有了解析xml的方法,现在封装了消息,通常的做法,是每次用到对应的model就手动写代码赋值, 而我这里LookMsgType方法中所有给消息赋值时全用的ReadXml.GetModel这同一个方法, 这里用的就是反射,方法如下:
/// <summary> /// 通过反射给接收消息model赋值 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="model"></param> /// <returns></returns> public static T GetModel<T>(T model, Dictionary< string , string > xmlModel) where T : class { var m = model.GetType(); foreach (PropertyInfo p in m.GetProperties()) { string name = p.Name; if (xmlModel.Keys.Contains(name)) { string value=xmlModel.Where(x => x.Key == name).FirstOrDefault().Value; p.SetValue(model, string .IsNullOrEmpty(value) ? null : Convert.ChangeType(value, p.PropertyType), null ); } } return model; } |
T model 就是要使用的消息类, xmlmodel是在入口处传递进来的解析的微信发来的xml信息, 这样,就不需要每次手动写代码赋值了。
好了,此篇实现了lookmsgtype方法, 实现了消息封装和反射赋值, 接下去就是到了业务逻辑层中的处理和具体实现了..