一般处理程序通常实现IHttpHandler接口,ashx效率比较高效,webform(aspx)比较消耗资源,mvc效率刚好介于两者之间
一般处理程序处理过程(HttpHandler)
IIS处理不了这种后缀程序通过映射表将该程序传递给ASPNET_ISAPI.DLL的程序,然后又将请求转给了网站程序
网站程序调用HttPRuntime类的静态方法处理请求,有以下步骤:
1,实现System.Web.IHttpHandle特殊接口的类
实现了该接口的类都能作为一个外部请求的目标程序
2,创建 HttpContext context 数据上下文对象,用于处理请求的所以参数数据.
(主要是httpRequest-->用于Form表单数据url 参数 和httpResponse()主要包含了FileStream对象用于保存输出的数据)
3,分析请求报文,并将数据封装到HttpWorkerRequest对象对应的属性
并调用HttpapplicationFactory的类中的静态方法来创建HttpApplication对象
(实际上是先通过httpApplication池 看有没有空闲的 没有才创建),那么
该对象会处理此次请求的所有运行过程
4,httpContex对象传入到httpApplication的时候就可以调用页面类中的ProcessRequest方法
好了一般处理程序就说到这里吧!
开始我来实现我的简单三层
第一步我首先搭建了DAL层(数据访问层)
因为是直接与数据库发生关系的,所以我新建了一个HelperSQL.cs类
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespaceStudentManagement.DAL
{//需要系统配置;系统设定;系统设置;查看系统配置程序集usingSystem.Configuration;usingSystem.Data.SqlClient;usingSystem.Data;publicclassHelperSQL
{//在ui的配置文件中配置AppSettingspublicstaticstringstr = System.Configuration.ConfigurationManager.AppSettings["ConnectionString"];privatestaticSqlConnection connection;publicstaticSqlConnection Connection {get{//判断是否有这个连接没有if(connection ==null) {//创建连接connection =newSqlConnection(str);//打开连接connection.Open();
}//判断连接是否是关闭的elseif(connection.State==System.Data.ConnectionState.Closed){//打开连接connection.Open();
}//判断连接是否中断elseif(connection.State ==System.Data.ConnectionState.Broken) {//先关闭连接connection.Close();//打开连接connection.Open();
}//返回连接returnconnection;
}
}publicstaticintExecuteCommand(stringstrsql)
{//传入数据库命令和连接SqlCommand sqlcmd =newSqlCommand(strsql, Connection);//执行语句返回受影响的行数intresult =sqlcmd.ExecuteNonQuery();returnresult;
}publicstaticintExecuteCommand(stringstr,paramsSqlParameter[] values) {//传入数据库命令和连接SqlCommand sqlcmd =newSqlCommand(str, Connection);//增加参数sqlcmd.Parameters.AddRange(values);returnsqlcmd.ExecuteNonQuery();
}publicstaticDataSet GetDataSet(stringstr) {//创建一个内存缓存DataSet ds =newDataSet();//传入命令和连接SqlCommand sqlcmd =newSqlCommand(str,Connection);//创建一个桥接器SqlDataAdapter sqlda =newSqlDataAdapter(sqlcmd);//写入内存sqlda.Fill(ds);//返回returnds;
}publicstaticDataSet GetDataSet(stringstr,paramsSqlParameter[] values)
{//创建一个内存缓存DataSet ds =newDataSet();//传入命令和连接SqlCommand sqlcmd =newSqlCommand(str, Connection);//增加参数sqlcmd.Parameters.AddRange(values);//打开桥连接SqlDataAdapter sqlda =newSqlDataAdapter(sqlcmd);//写入到内存sqlda.Fill(ds);//返回returnds;
}publicstaticDataSet StoredProcedure(stringstrName,paramsIDataParameter[] parmenters)
{using(SqlConnection connection =newSqlConnection(str))
{//创建一个内存缓存DataSet ds =newDataSet();//创建一个桥连接SqlDataAdapter sqlda =newSqlDataAdapter();//告诉桥连接这个是存储过程sqlda.SelectCommand =StoredProcedureCommand(connection, strName, parmenters);//写入内存sqlda.Fill(ds);//返回returnds;
}
}privatestaticSqlCommand StoredProcedureCommand(SqlConnection sqlcc,stringstrName, IDataParameter[] parmenters) {//传入存储过程名称和连接数据库命令SqlCommand sqlcmd =newSqlCommand(strName, sqlcc);//告诉数据库这个是存储过程sqlcmd.CommandType =CommandType.StoredProcedure;foreach(variteminparmenters)
{if(item !=null)
{//判断的参数是输入输出或者参数是输入并且参数不能为空if((item.Direction==ParameterDirection.InputOutput||item.Direction==ParameterDirection.Input )&&(item.Value==null))
{//该类区分空值(空对象)和未初始化值item.Value =DBNull.Value;
}//加入这个参数sqlcmd.Parameters.Add(item);
}
}//返回连接和命令returnsqlcmd;
}
}
}
View Code
这个是手动搭建的一个类库,可能不全,随后我会附加上一个比较全的sqlHelper.cs类文件
usingSystem;usingSystem.Collections.Generic;usingSystem.Text;usingSystem.Data;usingSystem.Data.SqlClient;namespaceDAL
{///<summary>///数据层 - 数据库 操作类///</summary>internalclassSqlHelper
{//获得配置文件的连接字符串publicreadonlystaticstringstrConn = System.Configuration.ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;#region01.查询数据表 static DataTable ExecuteDataTable(string strSql, params SqlParameter[] paras)///<summary>///查询数据表///</summary>///<param name="strSql">sql语句</param>///<param name="paras">参数数组</param>///<returns>数据表</returns>publicstaticDataTable GetDataTable(stringstrSql,paramsSqlParameter[] paras)
{//创建数据库连接对象SqlConnection conn =newSqlConnection(strConn);//创建适配器对象(sql命令,连接通道)SqlDataAdapter da =newSqlDataAdapter(strSql, conn);//为适配器添加参数da.SelectCommand.Parameters.AddRange(paras);//创建数据表对象DataTable dt =newDataTable();//适配器 读取数据库,并将查询的结果 装入程序的 dt里da.Fill(dt);//返回数据表returndt;
}#endregion#region02.执行非查询语句 int ExcuteNonQuery(string strSql, params SqlParameter[] paras)///<summary>///执行非查询语句)///</summary>///<param name="strSql">sql语句</param>///<param name="paras">参数数组</param>///<returns>受影响的行数</returns>publicstaticintExcuteNonQuery(stringstrSql,paramsSqlParameter[] paras)
{intres = -1;//创建连接通道using(SqlConnection conn =newSqlConnection(strConn))
{//创建命令对象(sql语句,连接通道)SqlCommand cmd =newSqlCommand(strSql, conn);//添加参数cmd.Parameters.AddRange(paras);
conn.Open();//执行非查询SQL命令res =cmd.ExecuteNonQuery();
}returnres;
}#endregion#region03.执行多条非查询语句 public static int ExcuteNonQuerys(string[] strSqls, SqlParameter[][] parasArr)///<summary>///执行多条非查询语句///</summary>///<param name="strSql">sql语句数组</param>///<param name="paras">参数二维数组</param>///<returns>受影响的行数</returns>publicstaticintExcuteNonQuerys(string[] strSqls, SqlParameter[][] parasArr)
{intres =0;//创建连接通道using(SqlConnection conn =newSqlConnection(strConn))
{//打开数据库连接conn.Open();//创建事务SqlTransaction tran =conn.BeginTransaction();//创建命令对象SqlCommand cmd =conn.CreateCommand();//为命令对象指定事务cmd.Transaction =tran;try{//循环执行sql语句for(inti =0; i < strSqls.Length; i++)
{//获得要执行的sql语句stringstrSql =strSqls[i];//为命令对象指定 此次执行的 sql语句cmd.CommandText =strSql;//添加参数if(parasArr.Length > i)//如果 参数2维数组的长度大于当前循环的下标{
cmd.Parameters.AddRange(parasArr[i]);//将 交错数组 的第一个元素(其实也是一个数组,添加到参数集合中)}
res+=cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
tran.Commit();//提交事务}catch(Exception ex)
{
res=0;
tran.Rollback();//回滚事务throwex;
}
}returnres;
}#endregion#region04.执行Scalar查询单个值 public static int ExcuteScalar(string strSql, params SqlParameter[] paras)///<summary>///执行Scalar查询单个值///</summary>///<param name="strSql">sql语句</param>///<param name="paras">参数数组</param>///<returns>返回查询结果</returns>publicstaticintExcuteScalar(stringstrSql,paramsSqlParameter[] paras)
{intres = -1;//创建连接通道using(SqlConnection conn =newSqlConnection(strConn))
{//创建命令对象(sql语句,连接通道)SqlCommand cmd =newSqlCommand(strSql, conn);//添加参数cmd.Parameters.AddRange(paras);
conn.Open();//将查询结果转换为int类型并返回res =Convert.ToInt32(cmd.ExecuteScalar());
}returnres;
}#endregion#region05.执行分页存储过程 public static DataTable GetPageList(int pageIndex, int pageSize, out int pageCount, out int rowCount)///<summary>///执行特殊的分页存储过程///</summary>///<param name="userID">用户ID</param>///<param name="pageIndex">页码</param>///<param name="pageSize">页容量</param>///<param name="pageCount">总页数--输出</param>///<param name="rowCount">总行数--输出</param>///<returns></returns>publicstaticDataTable GetPageListByProc(intuserID,intpageIndex,intpageSize,outintrowCount,outintpageCount)
{
DataTable dt=newDataTable();//创建连接通道using(SqlConnection conn =newSqlConnection(strConn))
{//创建适配器对象SqlDataAdapter da =newSqlDataAdapter("GetPageList", conn);//设置 命令类型 为存储过程da.SelectCommand.CommandType =CommandType.StoredProcedure;//设置 参数da.SelectCommand.Parameters.AddWithValue("@pageIndex", pageIndex);//当前页码da.SelectCommand.Parameters.AddWithValue("@pageSize", pageSize);//页容量da.SelectCommand.Parameters.AddWithValue("@userID", userID);//用户ID//在存储过程中 输出参数da.SelectCommand.Parameters.Add(newSqlParameter("@rowCount", SqlDbType.Int));
da.SelectCommand.Parameters.Add(newSqlParameter("@pageCount", SqlDbType.Int));//将后面两个参数 设置为 输出类型da.SelectCommand.Parameters[3].Direction =ParameterDirection.Output;
da.SelectCommand.Parameters[4].Direction =ParameterDirection.Output;//执行 并将查询到的 结果 赋给 数据表对象da.Fill(dt);//获得 存储过程 返回的 输出参数rowCount = Convert.ToInt32(da.SelectCommand.Parameters[3].Value);
pageCount= Convert.ToInt32(da.SelectCommand.Parameters[4].Value);
}//返回数据表returndt;
}#endregion#region06.执行存储过程 public static DataTable ExecuteProcedure(string procedure, params SqlParameter[] paras)///<summary>///执行存储过程///</summary>///<param name="procedure">存储过程名称</param>///<param name="param">参数数组</param>///<returns>数据表</returns>publicstaticDataTable ExecuteProcedure(stringprocedure,paramsSqlParameter[] paras)
{//创建连接通道SqlConnection conn =newSqlConnection(strConn);//创建适配器对象(sql命令,连接通道)SqlDataAdapter da =newSqlDataAdapter(procedure, conn);//设置适配器的命令类型为存储过程da.SelectCommand.CommandType =CommandType.StoredProcedure;//为适配器添加参数da.SelectCommand.Parameters.AddRange(paras);//创建数据表对象DataTable dt =newDataTable();//填充数据集da.Fill(dt);//返回数据表returndt;
}#endregion/***********************分页存储过程SQL代码***********************
CREATE procedure usp_GetPageList
@PageIndex int = 1,
@PageSize int = 10,
@PageCount int output,
@RowCount int output
as
begin
select * from (Select ROW_NUMBER() over(order by ID) as num, * from Student) as temp where num between (@pageIndex-1) * @pageSize + 1 and @pageSize + 1
select @RowCount = COUNT(*) from Student
set @PageCount = Ceiling(@RowCount/@PageSize)
end
*****************************************************************/}
}
View Code
这里我经常出现的问题是DataTable与DataSet的问题
第一、DataSet 应用程序集的问题 using system.data;这个东西我老是忘掉 所以在后面的BLL层,UI层这个程序集一定要引用上。
第二、解释下DataSet和DataTable之间的关系:
DataSet可以比作一个内存中的数据库,DataTable是一个内存中的数据表,DataSet里可以存储多个DataTable
一般我们可能需要将DataSet转换成DataTable : DataSet ds=new DataSet(); DataTable dt=ds.Tables[0];
这里我还想说上一点点,就是 SqlDataAdapter
SqlDataAdapter是 DataSet和 SQL Server之间的桥接器,用于检索和保存数据。
其引用程序集 using:System.Data.SqlClient;
这个里说一点小小的东西,一般我们看到Table 都知道是一个表 而在c#都会出现Table+“s” 这个可以理解成一个集合,如果这个理解有错,希望大家指点指点。
这个搭建好了,突然觉得好像没有数据库,接下里我就上传一个简单的数据库脚本
USE[master]GO/****** Object: Database [StudentManagement] Script Date: 2014/12/28 15:22:35 ******/CREATEDATABASE[StudentManagement]CONTAINMENT=NONEONPRIMARY( NAME=N'StudentManagement_data', FILENAME=N'E:\SQL\StudentManagement.mdf', SIZE=10240KB , MAXSIZE=10240KB , FILEGROWTH=10%)LOGON( NAME=N'StudentManagement_log', FILENAME=N'E:\SQL\StudentManagement,ldf', SIZE=5120KB , MAXSIZE=2048GB , FILEGROWTH=10240KB )GOALTERDATABASE[StudentManagement]SETCOMPATIBILITY_LEVEL=110GOIF(1=FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))beginEXEC[StudentManagement].[dbo].[sp_fulltext_database]@action='enable'endGOALTERDATABASE[StudentManagement]SETANSI_NULL_DEFAULTOFFGOALTERDATABASE[StudentManagement]SETANSI_NULLSOFFGOALTERDATABASE[StudentManagement]SETANSI_PADDINGOFFGOALTERDATABASE[StudentManagement]SETANSI_WARNINGSOFFGOALTERDATABASE[StudentManagement]SETARITHABORTOFFGOALTERDATABASE[StudentManagement]SETAUTO_CLOSEOFFGOALTERDATABASE[StudentManagement]SETAUTO_CREATE_STATISTICSONGOALTERDATABASE[StudentManagement]SETAUTO_SHRINKOFFGOALTERDATABASE[StudentManagement]SETAUTO_UPDATE_STATISTICSONGOALTERDATABASE[StudentManagement]SETCURSOR_CLOSE_ON_COMMITOFFGOALTERDATABASE[StudentManagement]SETCURSOR_DEFAULT GLOBALGOALTERDATABASE[StudentManagement]SETCONCAT_NULL_YIELDS_NULLOFFGOALTERDATABASE[StudentManagement]SETNUMERIC_ROUNDABORTOFFGOALTERDATABASE[StudentManagement]SETQUOTED_IDENTIFIEROFFGOALTERDATABASE[StudentManagement]SETRECURSIVE_TRIGGERSOFFGOALTERDATABASE[StudentManagement]SETENABLE_BROKERGOALTERDATABASE[StudentManagement]SETAUTO_UPDATE_STATISTICS_ASYNCOFFGOALTERDATABASE[StudentManagement]SETDATE_CORRELATION_OPTIMIZATIONOFFGOALTERDATABASE[StudentManagement]SETTRUSTWORTHYOFFGOALTERDATABASE[StudentManagement]SETALLOW_SNAPSHOT_ISOLATIONOFFGOALTERDATABASE[StudentManagement]SETPARAMETERIZATION SIMPLEGOALTERDATABASE[StudentManagement]SETREAD_COMMITTED_SNAPSHOTOFFGOALTERDATABASE[StudentManagement]SETHONOR_BROKER_PRIORITYOFFGOALTERDATABASE[StudentManagement]SETRECOVERYFULLGOALTERDATABASE[StudentManagement]SETMULTI_USERGOALTERDATABASE[StudentManagement]SETPAGE_VERIFY CHECKSUMGOALTERDATABASE[StudentManagement]SETDB_CHAININGOFFGOALTERDATABASE[StudentManagement]SETFILESTREAM( NON_TRANSACTED_access=OFF)GOALTERDATABASE[StudentManagement]SETTARGET_RECOVERY_TIME=0SECONDSGOEXECsys.sp_db_vardecimal_storage_format N'StudentManagement', N'ON'GOUSE[StudentManagement]GO/****** Object: Table [dbo].[SM_Class] Script Date: 2014/12/28 15:22:37 ******/SETANSI_NULLSONGOSETQUOTED_IDENTIFIERONGOSETANSI_PADDINGONGOCREATETABLE[dbo].[SM_Class]([SM_id][int]IDENTITY(1,1)NOTNULL,[SM_name][varchar](20)NULL,[SM_Grade][varchar](20)NULL,[SM_Class][varchar](20)NULL,[SM_Gender][varchar](5)NULL,[SM_Age][int]NULL,[SM_OutTime][datetime]NOTNULL,[SM_Istf][bit]NOTNULL,CONSTRAINT[PK__SM_Class__D963B824E04B3DFA]PRIMARYKEYCLUSTERED([SM_id]ASC)WITH(PAD_INDEX=OFF, STATISTICS_NORECOMPUTE=OFF, IGNORE_DUP_KEY=OFF, ALLOW_ROW_LOCKS=ON, ALLOW_PAGE_LOCKS=ON)ON[PRIMARY])ON[PRIMARY]GOSETANSI_PADDINGOFFGOUSE[master]GOALTERDATABASE[StudentManagement]SETREAD_WRITEGO
View Code
这个数据库的脚本可能需要注意的两点
第一、你必须手动建一个“StudentManagement”的数据库,建好数据库之后 在新建查询 里面打上 USE StudentManagement;
第二、在你新建表的同时,你需要确定你的路径在哪里
( NAME = N'StudentManagement_data', FILENAME = N'E:\SQL\StudentManagement.mdf' , SIZE = 10240KB , MAXSIZE = 10240KB , FILEGROWTH = 10%)
LOG ON
( NAME = N'StudentManagement_log', FILENAME = N'E:\SQL\StudentManagement,ldf' , SIZE = 5120KB , MAXSIZE = 2048GB , FILEGROWTH = 10240KB )
GO
也就是FILENAME 后面的路径在那个盘下面的那个文件.这个搭建好了之后我相信应该会有数据库了吧 !里面的字段可能不够成熟,希望大家多多指导下。