上一篇已經搭建好整體框架,實現了入口的驗證, 驗證通過后就交給LookMsgType方法處理,LookMsgType方法主要是對微信發來的不同的消息進行分解,不同的類型交給業務邏輯層不同的方法處理, 對不同類型的消息判斷,可以用if,也可以用switch 一般來說超過5個的if用switch會更好, 這里貼出LookMsgType方法:
1 public void LookMsgType(string msgType) 2 { 3 4 #region 判斷消息類型 5 switch (msgType) 6 { 7 case "text": 8 RText mText = new RText(); 9 mText = ReadXml.GetModel<RText>(mText, xmlModel); 10 BLLWei.DoText(dbHome, mText);//文本消息 11 break; 12 case "image": 13 RImg mImg = new RImg(); 14 mImg = ReadXml.GetModel<RImg>(mImg, xmlModel); 15 BLLWei.DoImg(dbHome,mImg);//圖片 16 break; 17 case "voice": //聲音 18 RVoice mVoice = new RVoice(); 19 mVoice = ReadXml.GetModel<RVoice>(mVoice, xmlModel); 20 BLLWei.DoVoice(dbHome,mVoice); 21 break; 22 23 case "video"://視頻 24 RVideo mVideo = new RVideo(); 25 mVideo = ReadXml.GetModel<RVideo>(mVideo, xmlModel); 26 BLLWei.DoVideo(dbHome, mVideo); 27 break; 28 29 case "location"://地理位置 30 RLocation mLocation = new RLocation(); 31 mLocation = ReadXml.GetModel<RLocation>(mLocation, xmlModel); 32 BLLWei.DoLocation(dbHome,mLocation); 33 break; 34 case "link"://鏈接 35 RLink mLink = new RLink(); 36 mLink = ReadXml.GetModel<RLink>(mLink, xmlModel); 37 BLLWei.DoLink(dbHome,mLink); 38 break; 39 #region 事件 40 case "event": 41 42 switch (ReadXml.ReadModel("Event", xmlModel)) 43 { 44 case "subscribe": 45 46 if (ReadXml.ReadModel("EventKey", xmlModel).IndexOf("qrscene_") >= 0) 47 { 48 RCodeNotSub mNotSub = new RCodeNotSub(); 49 mNotSub = ReadXml.GetModel<RCodeNotSub>(mNotSub, xmlModel); 50 BLLWei.DoCodeNotSub(dbHome,mNotSub);//未關注的新用戶,掃描帶參數的二維碼關注 51 } 52 else 53 { 54 RSub mSub = new RSub(); 55 mSub = ReadXml.GetModel<RSub>(mSub, xmlModel); 56 BLLWei.DoSub(dbHome,mSub);//普通關注 57 } 58 break; 59 case "unsubscribe": 60 RUnsub mUnSub = new RUnsub (); 61 mUnSub = ReadXml.GetModel<RUnsub>(mUnSub, xmlModel); 62 BLLWei.DoUnSub(dbHome,mUnSub);//取消關注 63 break; 64 65 case "SCAN": 66 RCodeSub mCodeSub = new RCodeSub(); 67 mCodeSub = ReadXml.GetModel<RCodeSub>(mCodeSub, xmlModel); 68 BLLWei.DoCodeSub(dbHome,mCodeSub);//已經關注的用戶掃描帶參數的二維碼 69 break; 70 case "LOCATION"://用戶上報地理位置 71 72 RSubLocation mSubLoc = new RSubLocation(); 73 mSubLoc = ReadXml.GetModel<RSubLocation>(mSubLoc, xmlModel); 74 75 BLLWei.DoSubLocation(dbHome, mSubLoc); 76 break; 77 case "CLICK"://自定義菜單點擊 78 79 RMenuClick mMenuClk = new RMenuClick(); 80 mMenuClk = ReadXml.GetModel<RMenuClick>(mMenuClk, xmlModel); 81 BLLWei.DoMenuClick(dbHome, mMenuClk); 82 break; 83 case "VIEW"://自定義菜單跳轉事件 84 85 RMenuView mMenuVw = new RMenuView(); 86 mMenuVw = ReadXml.GetModel<RMenuView>(mMenuVw, xmlModel); 87 BLLWei.DoMenuView(dbHome, mMenuVw); 88 break; 89 }; 90 break; 91 #endregion 92 } 93 #endregion 94 }
外層switch判斷msgtype, 在event類型時,再次switch判斷具體的事件類型(關注、取消關注、自定義菜單事件等), 至此所有的微信發來的消息都有處理了,在上面代碼中用到消息模型以及ReadXml.GetModel方法給模型賦值, 賦值之后傳遞給業務邏輯層對應的方法處理, 下面寫出消息封裝和給模型賦值的方法。
1、消息封裝:
對所有微信發來的消息進行封裝, 在datamodel中建一個Receive文件夾和一個send文件夾,在其中分別建立對應消息的類,完成之后,完整的datamodel類庫如下圖:
舉例
-----接收消息:
文本消息RText.cs

1 public class RText 2 { 3 public string ToUserName { get; set; }// 開發者微信號 4 public string FromUserName { get; set; }// 用戶號(OpenID) 5 public long CreateTime { get; set; }// 創建時間 6 public string MsgType { get; set; } //消息類型 7 public string Content { get; set; }//內容 8 public long MsgId { get; set; }//消息ID 9 10 }
自定義菜單點擊RMenuClick.cs

1 public class RMenuClick 2 { 3 public string ToUserName { get; set; }// 開發者微信號 4 public string FromUserName { get; set; }// 用戶號(OpenID) 5 public long CreateTime { get; set; }// 創建時間 6 public string MsgType { get; set; } //消息類型 7 8 public string Event { get; set; }//事件類型 9 public string EventKey { get; set; }//事件key 10 11 }
其他也都類似,不一一列舉。
-----發送消息
發送文本消息SText.cs

1 public class SText 2 { 3 4 5 6 public string ToUserName { get; set; }// 用戶號(OpenID) 7 public string FromUserName { get; set; }// 開發者微信號 8 9 public long CreateTime { get; set; }// 創建時間 10 11 public string MsgType { get { return "text"; } } //消息類型 12 13 public string Content { get; set; }//內容 14 15 16 }
發送圖文消息SNews.cs

1 namespace DataModel.Send 2 { 3 public class SNews 4 { 5 public string ToUserName { get; set; }// 用戶號(OpenID) 6 public string FromUserName { get; set; }// 開發者微信號 7 8 public long CreateTime { get; set; }// 創建時間 9 10 public string MsgType { get { return "news"; } } //消息類型 11 12 public int ArticleCount { get; set; }//圖文個數 13 14 public List<ArticlesModel> Articles { get; set; }//圖文列表 15 } 16 public class ArticlesModel //默認第一條大圖顯示 17 { 18 public string Title { get; set; }//標題 19 public string Description { get; set; }//描述 20 public string PicUrl { get; set; }//圖片鏈接 21 public string Url { get; set; }//點擊之后跳轉的鏈接 22 23 } 24 }
在發送圖文消息中,因為回復給微信的圖文消息中,具體的圖文內容是多條(最多可以10條),所以單獨會有ArticlesModel。 后面文章會寫出圖文消息的發送。
2、通過反射給model賦值
在上篇文章寫的入口處,已經有了解析xml的方法,現在封裝了消息,通常的做法,是每次用到對應的model就手動寫代碼賦值, 而我這里LookMsgType方法中所有給消息賦值時全用的ReadXml.GetModel這同一個方法, 這里用的就是反射,方法如下:
1 /// <summary> 2 /// 通過反射給接收消息model賦值 3 /// </summary> 4 /// <typeparam name="T"></typeparam> 5 /// <param name="model"></param> 6 /// <returns></returns> 7 public static T GetModel<T>(T model, Dictionary<string, string> xmlModel) where T : class 8 { 9 var m = model.GetType(); 10 foreach (PropertyInfo p in m.GetProperties()) 11 { 12 string name = p.Name; 13 if (xmlModel.Keys.Contains(name)) 14 { 15 string value=xmlModel.Where(x => x.Key == name).FirstOrDefault().Value; 16 p.SetValue(model, 17 string.IsNullOrEmpty(value) ? null : Convert.ChangeType(value, p.PropertyType), null); 18 } 19 } 20 return model; 21 }
T model 就是要使用的消息類, xmlmodel是在入口處傳遞進來的解析的微信發來的xml信息, 這樣,就不需要每次手動寫代碼賦值了。
好了,此篇實現了lookmsgtype方法, 實現了消息封裝和反射賦值, 接下去就是到了業務邏輯層中的處理和具體實現了...