您系统中的IE浏览器版本过低,不能更好的体验,建议您升级至IE9以上,或者双核浏览器切换到极速核,IT人士,应该做个现代人---http://www.cnblogs.com/mochen/

[c#]asp.net开发微信公众平台(2)多层架构框架搭建和入口实现

     上篇已经设计出比较完善的数据库了,这篇开始进入代码。  首先把上篇设计的数据库脚本在数据库中执行下,生成数据库,然后在VS中建立项目,为了方便理解和查看,我设计的都是很直白的类名和文件名,没有命名空间前缀。

     采用接口方式,共8个项目:7个类库和一个MVC项目,  分别为:  

                                                                                     显示层——MVC项目

                                                                                     业务逻辑层——访问接口IBLL、具体实现BLL

                                                                                     数据访问层——访问接口IDAL、具体实现DAL

                                                                                     数据(模型)——DataModel

                                                                                     通用方法——Common

                                                                                     仓储——Factory

这里的仓储并不为了生产业务逻辑层和数据访问层的接口,而是为了存放EntityFramework上下文对象和一些缓存管理,业务逻辑层和数据访问层的接口生产(实现)工作我会交给Spring.NET注入实现。 框架搭建好之后如下:

 

    框架搭建好了,接下去把数据库添加进来,在DAL中(注意是DAL不是datamodel)添加新项,选择数据--ADO.NET实体数据模型:

 

取个名字,就叫WeixinModel吧, 选择从数据库生成,配置一下数据库连接到之前生成的数据库,一路下一步,最后加载到edmx, 在edmx上右键--添加代码生成项,选择代码:

选DbContext Generator,  然后保存一下edmx, 之后把edmx和weixinmodel.tt复制到DataModel,删除DAL中的edmx和weixinmodel.tt, 在datamodel中打开weixinmodel.tt保存一下即可, 另外需要在DAL中保留的WeiXinModel.Context.cs中声明datamodel命名空间。  

    框架和数据模型都有了,接下去在DAL、IDAL、BLL、IBLL中按照正确的引用层次添加引用,并写几个常用方法,就可以开始在显示层中使用了,

这里举例在DAL中写添删改查方法:

 1        //添加
 2         public T AddEntity<T>(DbContext db,T entity) where T : class
 3         {
 4             db.Entry<T>(entity).State = EntityState.Added;
 5             db.SaveChanges();
 6             return entity;
 7         }
 8 
 9         //修改
10         public bool UpdateEntity<T>(DbContext db,T entity) where T : class
11         {
12             db.Set<T>().Attach(entity);
13             db.Entry<T>(entity).State = EntityState.Modified;
14             db.SaveChanges();
15             return true;
16         }
17         //删除
18         public bool DeleteEntity<T>(DbContext db,T entity) where T : class
19         {
20             db.Set<T>().Attach(entity);
21             db.Entry<T>(entity).State = EntityState.Deleted;
22             db.SaveChanges();
23             return true;
24 
25         }
26 
27 
28 
29 
30         // 返回一个对象
31         public T InfoEntities<T>(DbContext db, Expression<Func<T, bool>> whereLambda) where T : class
32         {
33 
34             return db.Set<T>().Where<T>(whereLambda).FirstOrDefault();
35 
36         }
View Code

对应的把接口、业务逻辑层都写上。

 

    现在来到显示层,默认的MVC项目是返回VIEW, 这里我们不需要返回页面, 把home中的index改成Void返回类型, 接下去就是接收微信发来的请求进行判断了,验证请求----接收POST数据---分析XML----解析成自己想要的数据

 

  入口:首先验证消息来源是微信服务器,然后解析收到的xml,解析成功有数据则执行LookMsgType方法来进行处理

 1         private IBLL.IDoWei BLLWei { set; get; }
 2         public DbContext dbHome { get; set; }
 3         private string token { get; set; }
 4         Dictionary<string, string> xmlModel = new Dictionary<string, string>();         
 5         public void Index()
 6         {
 7             dbHome=FContext.WeiXinDbContext(); 
 8             //xml字符串
 9             string xmlData = string.Empty;
10             //请求类型
11             string method=Request.HttpMethod.ToLower();
12             string signature = Request.QueryString["signature"];
13             string timestamp = Request.QueryString["timestamp"];
14             string nonce = Request.QueryString["nonce"];
15             //验证接入和每次请求验证真实性
16             if (method == "get")
17             {
18                 if (CheckSign(signature,timestamp,nonce))
19                 {
20                     Often.ResponseToEnd(Request.QueryString["echostr"]);
21                 }
22                 else
23                 {
24                     Response.Status = "403";
25                     Often.ResponseToEnd("");
26                 }
27             }
28             //处理接收到的POST消息
29             else if (method == "post")
30             {
31                 using (Stream stream = Request.InputStream)
32                 {
33                     Byte[] byteData = new Byte[stream.Length];
34                     stream.Read(byteData, 0, (Int32)stream.Length);
35                     xmlData = Encoding.UTF8.GetString(byteData);
36                 }
37                 if (!string.IsNullOrEmpty(xmlData))
38                 {
39                     try
40                     {
41                         xmlModel = ReadXml.GetXmlModel(xmlData);
42                     }
43                     catch
44                     {
45                         //未能正确处理 给微信服务器回复默认值
46                         Often.ResponseToEnd("");
47                     }
48                 }
49                 if (xmlModel.Count > 0)
50                 {
51                     string msgType = ReadXml.ReadModel("MsgType", xmlModel);
52                     LookMsgType(msgType);
53                 }
54             }
55             else//除了post和get外 如head皆视为非法请求
56             {
57                 Response.Status = "403";
58                 Often.ResponseToEnd("");  
59             }
60             dbHome.Dispose();
61         }
View Code

这里用到的验证方法:

 1 /// <summary>
 2         /// 验证签名
 3         /// </summary>
 4         /// <param name="signature"></param>
 5         /// <param name="timestamp"></param>
 6         /// <param name="nonce"></param>
 7         /// <returns></returns>
 8         public bool CheckSign(string signature, string timestamp, string nonce)
 9         {
10             List<string> list = new List<string>();
11             list.Add(token);
12             list.Add(timestamp);
13             list.Add(nonce);
14             //默认排序
15             list.Sort();
16             string tmpStr = string.Empty;
17             list.All(l => { tmpStr += l; return true; });
18             tmpStr = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
19             //验证
20             if (tmpStr == signature)
21             {
22                 return true;
23             }
24             return false;
25         }

仓储中的EF上下文:

1         public static DbContext WeiXinDbContext()
2         {
3             DbContext dbcontext =new WeiXinEntities();  //创建
4             dbcontext.Configuration.AutoDetectChangesEnabled = false;//自动检测配置更改
5             dbcontext.Configuration.LazyLoadingEnabled = true;//延迟加载
6             dbcontext.Configuration.ValidateOnSaveEnabled = false;//自动跟踪
7             return dbcontext;
8         }

Common中的解析微信发来的XML方法

 1        //把接收到的XML转为字典
 2         public static Dictionary<string, string> GetXmlModel(string xmlStr)
 3         {
 4             XmlDocument doc = new XmlDocument();
 5             doc.LoadXml(xmlStr);
 6             Dictionary<string, string> mo = new Dictionary<string, string>();
 7             var data = doc.DocumentElement.ChildNodes;
 8             for (int i = 0; i < data.Count; i++)
 9             {
10                 mo.Add(data.Item(i).LocalName, data.Item(i).InnerText);
11             }
12             return mo;
13         }
14 
15 
16 
17         ////从字典中读取指定的值
18         public static string ReadModel(string key, Dictionary<string, string> model)
19         {
20             string str = "";
21             model.TryGetValue(key, out str);
22             if (str== null)
23                 str = "";
24             return str;
25         }

好了,入口以及验证相关的都解决了,下一篇开始微信消息处理LookMsgType方法实现

posted @ 2014-04-11 08:48  沫尘  阅读(13675)  评论(34编辑  收藏  举报