三层架构1
一、三层框架
表现层:也叫视图层,用html、css、js、jquery
业务逻辑层:也叫控制层,包含业务逻辑的实现部分
数据管理层:与数据库直接交互的部分
二、组建三层框架(现有实例)
1、数据管理层
A、引入Model类
创建项目之后在项目的同级目录上建立Model的目录,相应的在保存项目的硬盘上也建立Model的目录。然后把Model.Base复制到硬盘上也建立的Model目录下,并在项目的Model下引入硬盘Model.Base线面现有的Model.Base.csproj模块。
B、在项目的Model下面新建C#类库模块,项目名称为Model.TestDB,项目保存位置为硬盘的Model下面。此时硬盘和项目中都会产生Model.TestDB的目录。
** Model.TestDB中的每个类与数据库里面的表一一对应的,类里面的每个属性对应表里面的每个字段。
2、业务逻辑层
A、引入DAL类
在项目和硬盘上建立DAL目录,把Dal.Base和Utility复制到硬盘的DAL目录下。并在项目的DAL下面引入这两个目录中的DAL.Base.csproj和Utility.csproj模块。
B、在项目的DAL下面新建C#类库模块,项目名称为DAL.Test,项目保存位置为硬盘的DAL下面。此时硬盘和项目中都会产生DAL.Test的目录。
3、表现层(WEB层)
一开始创建网站项目时产生的项目就是实现表现成逻辑的模块,无需特别建立。
四、编译及引用
编译之前为了便于管理把所有的编译文件统一存放到与项目同级的硬盘目录Reference之中。
1、编译Model.Base
A、先打开Model.Base项目的属性页面,指定程序集和命名空间的名称,然后再指定生成-->输出路径为与项目同级的Reference目录。
B、在Model.Base上面点击右键选择[生成]来编译,编译结束后确认Reference目录是否已有编译文件。
2、Model.TestDB是需要需要引用Model.base的,打开Model.TestDB项目-->引用上点击右键-->添加引用-->浏览查找硬盘中存放编译文件的Reference目录-->选定要引入的编译文件-->确定。此时应该在Model.TestDB项目的引用中看到Model.base的程序集com.Model.Base。
3、编译Model.TestDB,参考【编译Model.Base】。
4、编译Utility,参考【编译Model.Base】。Utility是包含.NET默认功能外拓展的功能,属于基类不需要引用其他模块。
5、DAL.Base是需要引用多个模块。
A、Microsfot开头的5个模块直接复制到保存编译文件的Reference目录中。
B、引入包括5个Microsfot开头的模块外com.Model.Base和com.Utility模块一起引用到DAL.Base模块中。
C、编译DAL.Base,参考【编译Model.Base】。
6、DAL.Test也是需要引用多个模块的。
A、引入com.Model.Base、com.DAL.Base、ModelTserDB等三个模块一起引用到DAL.Base模块中。
B、编译DAL.Test,参考【编译Model.Base】。
7、在开始建立的WEB项目中需要引入上面说有模块
A、引入com.DAL.Base、DAL.Test、com.Model.Base、Model.TserDB、com.Utility等5个模块。
B、编译WEB项目,参考【编译Model.Base】。
--- 到此三层架构基础组建完毕---
五、使用三层架构实例
1、在web.config里面追加数据库连接字符串:con是默认连接串名称,追加新的连接字串名称时要在Model.Base下面的Enums.cs中追加对应的枚举类数据就可以。
如:con = 1, //默认
sq_ruanmou= 2 //新追加的连接
2、对数据库中的表结构全部转化为Model.TestDB中对应的类。
A、设置构造函数和字段对应的属性
本框架只支持一个字段的单一关键字段。多个字段组成的联合关键字段无法处理。
public class RNews : BaseModel //数据处理层中与数据表对应的类
{
public RNews() //该类的构造函数
{
PrimaryKey = "NewsId"; //只支持单一字段的关键字段
DataBaseName = DataBaseEnum.con; //选择数据库连接字串
}
public int NewsId { get; set; } //设置表中每个字段对应的属性
public string Title { get; set; }
public string Text { get; set; }
public DateTime CreatedTime { get; set; }
public string NewsClass { get; set; }
public int ViewCount { get; set; }
}
3、利用Model.TestDB中与表对应的类,在DAL.Test类中创建具有CURD功能的泛型结构的对应类。
public class RNewsDAL //业务逻辑层中与数据表对应的类
{
public static BaseDAL<RNews> m_RNewsDal = new BaseDAL<RNews>(); //创建一个表的CURD实例
}
** m_RNewsDal就是在表现层(显示层)用于CURD的对象。
4、CURD实例的应用
A、GetModel 获取普通查询的方法
1)可以传PrimaryKey对应的值
2)可以传where后面的条件表达式部分
UserInfor user = UserInforDAL.m_UserInforDal.GetModel(string.Format("UserName='{0}' and Pwd='{1}'", username, pwd));
if (user == null) //GetModel返回的实例user为null时表示查询没有返回结果。
{
Response.Write("<script>alert('用户名或者密码错误');</script>");
}
else
{
if (chk.Checked) //当复选框打钩时保存cookie
{
Response.Cookies["username"].Expires = DateTime.Now.AddHours(1); //设置cookie留存时间
}
Response.Cookies["username"].Value = username; //保存cookie
Response.Redirect("RNewsM.aspx"); //转移到新的制定页面
}
3)SQL注入处理
a、通常使用传递参数的方式防止SQL注入。
UserInfor user = UserInforDAL.m_UserInforDal.GetModel("UserName=@UserName and Pwd=@Pwd",ListPm);
b、可以事先检查输入的内容里面是否有非法字符的方式防止SQL注入。
public static bool SqlInsert(string strS) //检查输入的内容里面是否有非法字符的方法
{
bool b = true;
string sql = "exec |insert |select |delete |update |count |chr |mid |master |truncate |char |declare |drop |creat "; //需要检查的关键字符串
string[] sql_c = sql.Split('|'); //改成数组
foreach (var sl in sql_c)
{
if (strS.ToLower().IndexOf(sl) >= 0) //查找sl中的字符串在strS中的位置
{
b = false; //没查到会返回-1,否则就有
break; //一旦发现有一个非法字串就中断退出
}
}
return b;
}
** string.IndexOf(String):指定Unicode字符或字符串在此实例中的第一个匹配项的从零开始的索引。如果未在此实例中找到该字符或字符串,则此方法返回 -1。
** 调用检测的语句:
if (WebSafe.SqlInsert(username) == false || WebSafe.SqlInsert(pwd) == false){}
--- 检测结果false就表明有非法字串。