• [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方法实现

  • 相关阅读:
    前端工程师基础课程作业
    对于API接口设计的几点看法
    socket socket.io
    移动端布局
    angularJS
    bootstrop的应用
    jquery基础
    html5本地存储
    ajax
    数据库类型
  • 原文地址:https://www.cnblogs.com/mochen/p/3655835.html
Copyright © 2020-2023  润新知