上篇已经设计出比较完善的数据库了,这篇开始进入代码。 首先把上篇设计的数据库脚本在数据库中执行下,生成数据库,然后在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方法
好了,入口以及验证相关的都解决了,下一篇开始微信消息处理LookMsgType方法实现




