php专区

 首页 > php专区 > PHP应用 > 开放平台 > 沫尘[c#]asp.net开发微信公众平台(2)多层架构框架搭

沫尘[c#]asp.net开发微信公众平台(2)多层架构框架搭

分享到:
【字体:
导读:
          上篇已经设计出比较完善的数据库了,这篇开始进入代码。 首先把上篇设计的数据库脚本在数据库中执行下,生成数据库,然后在VS中建立项目,为了方便理解和查看,我设计的都是很...

上篇已经设计出比较完善的数据库了,这篇开始进入代码。  首先把上篇设计的数据库脚本在数据库中执行下,生成数据库,然后在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中写添删改查方法:

 
//添加
        public T AddEntity(DbContext db,T entity) where T : class
        {
            db.Entry(entity).State = EntityState.Added;
            db.SaveChanges();
            return entity;
        }

        //修改
        public bool UpdateEntity(DbContext db,T entity) where T : class
        {
            db.Set().Attach(entity);
            db.Entry(entity).State = EntityState.Modified;
            db.SaveChanges();
            return true;
        }
        //删除
        public bool DeleteEntity(DbContext db,T entity) where T : class
        {
            db.Set().Attach(entity);
            db.Entry(entity).State = EntityState.Deleted;
            db.SaveChanges();
            return true;

        }




        // 返回一个对象
        public T InfoEntities(DbContext db, Expression> whereLambda) where T : class
        {

            return db.Set().Where(whereLambda).FirstOrDefault();

        }

 

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

 

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

 

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


private IBLL.IDoWei BLLWei { set; get; }
        public DbContext dbHome { get; set; }
        private string token { get; set; }
        Dictionary xmlModel = new Dictionary();         
        public void Index()
        {
            dbHome=FContext.WeiXinDbContext(); 
            //xml字符串
            string xmlData = string.Empty;
            //请求类型
            string method=Request.HttpMethod.ToLower();
            string signature = Request.QueryString["signature"];
            string timestamp = Request.QueryString["timestamp"];
            string nonce = Request.QueryString["nonce"];
            //验证接入和每次请求验证真实性
            if (method == "get")
            {
                if (CheckSign(signature,timestamp,nonce))
                {
                    Often.ResponseToEnd(Request.QueryString["echostr"]);
                }
                else
                {
                    Response.Status = "403";
                    Often.ResponseToEnd("");
                }
            }
            //处理接收到的POST消息
            else if (method == "post")
            {
                using (Stream stream = Request.InputStream)
                {
                    Byte[] byteData = new Byte[stream.Length];
                    stream.Read(byteData, 0, (Int32)stream.Length);
                    xmlData = Encoding.UTF8.GetString(byteData);
                }
                if (!string.IsNullOrEmpty(xmlData))
                {
                    try
                    {
                        xmlModel = ReadXml.GetXmlModel(xmlData);
                    }
                    catch
                    {
                        //未能正确处理 给微信服务器回复默认值
                        Often.ResponseToEnd("");
                    }
                }
                if (xmlModel.Count > 0)
                {
                    string msgType = ReadXml.ReadModel("MsgType", xmlModel);
                    LookMsgType(msgType);
                }
            }
            else//除了post和get外 如head皆视为非法请求
            {
                Response.Status = "403";
                Often.ResponseToEnd("");  
            }
            dbHome.Dispose();
        }

这里用到的验证方法:

 

/// 
        /// 验证签名
        /// 
        /// 
        /// 
        /// 
        /// 
        public bool CheckSign(string signature, string timestamp, string nonce)
        {
            List list = new List();
            list.Add(token);
            list.Add(timestamp);
            list.Add(nonce);
            //默认排序
            list.Sort();
            string tmpStr = string.Empty;
            list.All(l => { tmpStr += l; return true; });
            tmpStr = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
            //验证
            if (tmpStr == signature)
            {
                return true;
            }
            return false;
        }

 

仓储中的EF上下文:


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

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

 
//把接收到的XML转为字典
        public static Dictionary GetXmlModel(string xmlStr)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xmlStr);
            Dictionary mo = new Dictionary();
            var data = doc.DocumentElement.ChildNodes;
            for (int i = 0; i < data.Count; i++)
            {
                mo.Add(data.Item(i).LocalName, data.Item(i).InnerText);
            }
            return mo;
        }



        ////从字典中读取指定的值
        public static string ReadModel(string key, Dictionary model)
        {
            string str = "";
            model.TryGetValue(key, out str);
            if (str== null)
                str = "";
            return str;
        }

 

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

源码下载,新建的QQ群,提供源码下载,有问题也可以问我:群号183695596
分享到:
大齐玩转微信公众账号系列(六): 微信...
此系列博文目录: 如何申请微信公众帐号 微信公众账号消息那些事儿 服务号实现自定义菜单 微信公众账号开发入门(原理)微信公众账号开发:URL 和 Tocken 微信公众账号开发:消息原理 微信公众账号开发:消息设计、源码 微信公众账号开发:菜单原理、设计、源码 微信公众账号开发:JS接口微信公众账号开发:Auth2.0认...
沫尘[c#]asp.net开发微信公众平台(1)数据...
开发微信公众平台之前,先去微信官方了解下大概的情况 这里:http://mp.weixin.qq.com/wiki/index.php ;看了之后心里大致有数了,开始设计数据库,尽可能的考虑,未考虑到的,以后再补充。     1、首先是用户部分,根据微信官方的接口结合实际运用,用户部分有3个表:用户表、用户资料表、用户分组表,我设计的如下...
  •         php迷,一个php技术的分享社区,专属您自己的技术摘抄本、收藏夹。
  • 在这里……