一般处理程序通常实现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类
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace StudentManagement.DAL{ //需要系统配置;系统设定;系统设置;查看系统配置程序集 using System.Configuration; using System.Data.SqlClient; using System.Data; public class HelperSQL { //在ui的配置文件中配置AppSettings public static string str = System.Configuration.ConfigurationManager.AppSettings["ConnectionString"]; private static SqlConnection connection; public static SqlConnection Connection { get { //判断是否有这个连接没有 if (connection == null) { //创建连接 connection = new SqlConnection(str); //打开连接 connection.Open(); } //判断连接是否是关闭的 else if(connection.State==System.Data.ConnectionState.Closed){ //打开连接 connection.Open(); } //判断连接是否中断 else if (connection.State == System.Data.ConnectionState.Broken) { //先关闭连接 connection.Close(); //打开连接 connection.Open(); } //返回连接 return connection; } } public static int ExecuteCommand(string strsql) { //传入数据库命令和连接 SqlCommand sqlcmd = new SqlCommand(strsql, Connection); //执行语句返回受影响的行数 int result = sqlcmd.ExecuteNonQuery(); return result; } public static int ExecuteCommand(string str, params SqlParameter[] values) { //传入数据库命令和连接 SqlCommand sqlcmd = new SqlCommand(str, Connection); //增加参数 sqlcmd.Parameters.AddRange(values); return sqlcmd.ExecuteNonQuery(); } public static DataSet GetDataSet(string str) { //创建一个内存缓存 DataSet ds = new DataSet(); //传入命令和连接 SqlCommand sqlcmd = new SqlCommand(str,Connection); //创建一个桥接器 SqlDataAdapter sqlda = new SqlDataAdapter(sqlcmd); //写入内存 sqlda.Fill(ds); //返回 return ds; } public static DataSet GetDataSet(string str, params SqlParameter[] values) { //创建一个内存缓存 DataSet ds = new DataSet(); //传入命令和连接 SqlCommand sqlcmd = new SqlCommand(str, Connection); //增加参数 sqlcmd.Parameters.AddRange(values); //打开桥连接 SqlDataAdapter sqlda = new SqlDataAdapter(sqlcmd); //写入到内存 sqlda.Fill(ds); //返回 return ds; } public static DataSet StoredProcedure(string strName, params IDataParameter[] parmenters) { using (SqlConnection connection = new SqlConnection(str)) { //创建一个内存缓存 DataSet ds = new DataSet(); //创建一个桥连接 SqlDataAdapter sqlda = new SqlDataAdapter(); //告诉桥连接这个是存储过程 sqlda.SelectCommand = StoredProcedureCommand(connection, strName, parmenters); //写入内存 sqlda.Fill(ds); //返回 return ds; } } private static SqlCommand StoredProcedureCommand(SqlConnection sqlcc, string strName, IDataParameter[] parmenters) { //传入存储过程名称和连接数据库命令 SqlCommand sqlcmd = new SqlCommand(strName, sqlcc); //告诉数据库这个是存储过程 sqlcmd.CommandType = CommandType.StoredProcedure; foreach (var item in parmenters) { if (item !=null) { //判断的参数是输入输出或者参数是输入并且参数不能为空 if ((item.Direction==ParameterDirection.InputOutput|| item.Direction==ParameterDirection.Input )&& (item.Value==null)) { //该类区分空值(空对象)和未初始化值 item.Value = DBNull.Value; } //加入这个参数 sqlcmd.Parameters.Add(item); } } //返回连接和命令 return sqlcmd; } }}
这个是手动搭建的一个类库,可能不全,随后我会附加上一个比较全的sqlHelper.cs类文件
using System;using System.Collections.Generic;using System.Text;using System.Data;using System.Data.SqlClient;namespace DAL{ /// <summary> /// 数据层 - 数据库 操作类 /// </summary> internal class SqlHelper { //获得配置文件的连接字符串 public readonly static string strConn = System.Configuration.ConfigurationManager.ConnectionStrings["connStr"].ConnectionString; #region 01.查询数据表 static DataTable ExecuteDataTable(string strSql, params SqlParameter[] paras) /// <summary> /// 查询数据表 /// </summary> /// <param name="strSql">sql语句</param> /// <param name="paras">参数数组</param> /// <returns>数据表</returns> public static DataTable GetDataTable(string strSql, params SqlParameter[] paras) { //创建数据库连接对象 SqlConnection conn = new SqlConnection(strConn); //创建适配器对象(sql命令,连接通道) SqlDataAdapter da = new SqlDataAdapter(strSql, conn); //为适配器添加参数 da.SelectCommand.Parameters.AddRange(paras); //创建数据表对象 DataTable dt = new DataTable(); //适配器 读取数据库,并将查询的结果 装入程序的 dt里 da.Fill(dt); //返回数据表 return dt; } #endregion #region 02.执行非查询语句 int ExcuteNonQuery(string strSql, params SqlParameter[] paras) /// <summary> /// 执行非查询语句) /// </summary> /// <param name="strSql">sql语句</param> /// <param name="paras">参数数组</param> /// <returns>受影响的行数</returns> public static int ExcuteNonQuery(string strSql, params SqlParameter[] paras) { int res = -1; //创建连接通道 using (SqlConnection conn = new SqlConnection(strConn)) { //创建命令对象(sql语句,连接通道) SqlCommand cmd = new SqlCommand(strSql, conn); //添加参数 cmd.Parameters.AddRange(paras); conn.Open(); //执行非查询SQL命令 res = cmd.ExecuteNonQuery(); } return res; } #endregion #region 03.执行多条非查询语句 public static int ExcuteNonQuerys(string[] strSqls, SqlParameter[][] parasArr) /// <summary> /// 执行多条非查询语句 /// </summary> /// <param name="strSql">sql语句数组</param> /// <param name="paras">参数二维数组</param> /// <returns>受影响的行数</returns> public static int ExcuteNonQuerys(string[] strSqls, SqlParameter[][] parasArr) { int res = 0; //创建连接通道 using (SqlConnection conn = new SqlConnection(strConn)) { //打开数据库连接 conn.Open(); //创建事务 SqlTransaction tran = conn.BeginTransaction(); //创建命令对象 SqlCommand cmd = conn.CreateCommand(); //为命令对象指定事务 cmd.Transaction = tran; try { //循环执行sql语句 for (int i = 0; i < strSqls.Length; i++) { //获得要执行的sql语句 string strSql = 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();//回滚事务 throw ex; } } return res; } #endregion #region 04.执行Scalar查询单个值 public static int ExcuteScalar(string strSql, params SqlParameter[] paras) /// <summary> /// 执行Scalar查询单个值 /// </summary> /// <param name="strSql">sql语句</param> /// <param name="paras">参数数组</param> /// <returns>返回查询结果</returns> public static int ExcuteScalar(string strSql, params SqlParameter[] paras) { int res = -1; //创建连接通道 using (SqlConnection conn = new SqlConnection(strConn)) { //创建命令对象(sql语句,连接通道) SqlCommand cmd = new SqlCommand(strSql, conn); //添加参数 cmd.Parameters.AddRange(paras); conn.Open(); //将查询结果转换为int类型并返回 res = Convert.ToInt32(cmd.ExecuteScalar()); } return res; } #endregion #region 05.执行分页存储过程 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> public static DataTable GetPageListByProc(int userID, int pageIndex, int pageSize, out int rowCount, out int pageCount) { DataTable dt = new DataTable(); //创建连接通道 using (SqlConnection conn = new SqlConnection(strConn)) { //创建适配器对象 SqlDataAdapter da = new SqlDataAdapter("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(new SqlParameter("@rowCount", SqlDbType.Int)); da.SelectCommand.Parameters.Add(new SqlParameter("@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); } //返回数据表 return dt; } #endregion #region 06.执行存储过程 public static DataTable ExecuteProcedure(string procedure, params SqlParameter[] paras) /// <summary> /// 执行存储过程 /// </summary> /// <param name="procedure">存储过程名称</param> /// <param name="param">参数数组</param> /// <returns>数据表</returns> public static DataTable ExecuteProcedure(string procedure, params SqlParameter[] paras) { //创建连接通道 SqlConnection conn = new SqlConnection(strConn); //创建适配器对象(sql命令,连接通道) SqlDataAdapter da = new SqlDataAdapter(procedure, conn); //设置适配器的命令类型为存储过程 da.SelectCommand.CommandType = CommandType.StoredProcedure; //为适配器添加参数 da.SelectCommand.Parameters.AddRange(paras); //创建数据表对象 DataTable dt = new DataTable(); //填充数据集 da.Fill(dt); //返回数据表 return dt; } #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 *****************************************************************/ }}
这里我经常出现的问题是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 ******/CREATE DATABASE [StudentManagement] CONTAINMENT = NONE ON PRIMARY ( 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 )GOALTER DATABASE [StudentManagement] SET COMPATIBILITY_LEVEL = 110GOIF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))beginEXEC [StudentManagement].[dbo].[sp_fulltext_database] @action = 'enable'endGOALTER DATABASE [StudentManagement] SET ANSI_NULL_DEFAULT OFF GOALTER DATABASE [StudentManagement] SET ANSI_NULLS OFF GOALTER DATABASE [StudentManagement] SET ANSI_PADDING OFF GOALTER DATABASE [StudentManagement] SET ANSI_WARNINGS OFF GOALTER DATABASE [StudentManagement] SET ARITHABORT OFF GOALTER DATABASE [StudentManagement] SET AUTO_CLOSE OFF GOALTER DATABASE [StudentManagement] SET AUTO_CREATE_STATISTICS ON GOALTER DATABASE [StudentManagement] SET AUTO_SHRINK OFF GOALTER DATABASE [StudentManagement] SET AUTO_UPDATE_STATISTICS ON GOALTER DATABASE [StudentManagement] SET CURSOR_CLOSE_ON_COMMIT OFF GOALTER DATABASE [StudentManagement] SET CURSOR_DEFAULT GLOBAL GOALTER DATABASE [StudentManagement] SET CONCAT_NULL_YIELDS_NULL OFF GOALTER DATABASE [StudentManagement] SET NUMERIC_ROUNDABORT OFF GOALTER DATABASE [StudentManagement] SET QUOTED_IDENTIFIER OFF GOALTER DATABASE [StudentManagement] SET RECURSIVE_TRIGGERS OFF GOALTER DATABASE [StudentManagement] SET ENABLE_BROKER GOALTER DATABASE [StudentManagement] SET AUTO_UPDATE_STATISTICS_ASYNC OFF GOALTER DATABASE [StudentManagement] SET DATE_CORRELATION_OPTIMIZATION OFF GOALTER DATABASE [StudentManagement] SET TRUSTWORTHY OFF GOALTER DATABASE [StudentManagement] SET ALLOW_SNAPSHOT_ISOLATION OFF GOALTER DATABASE [StudentManagement] SET PARAMETERIZATION SIMPLE GOALTER DATABASE [StudentManagement] SET READ_COMMITTED_SNAPSHOT OFF GOALTER DATABASE [StudentManagement] SET HONOR_BROKER_PRIORITY OFF GOALTER DATABASE [StudentManagement] SET RECOVERY FULL GOALTER DATABASE [StudentManagement] SET MULTI_USER GOALTER DATABASE [StudentManagement] SET PAGE_VERIFY CHECKSUM GOALTER DATABASE [StudentManagement] SET DB_CHAINING OFF GOALTER DATABASE [StudentManagement] SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF ) GOALTER DATABASE [StudentManagement] SET TARGET_RECOVERY_TIME = 0 SECONDS GOEXEC sys.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 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOSET ANSI_PADDING ONGOCREATE TABLE [dbo].[SM_Class]( [SM_id] [int] IDENTITY(1,1) NOT NULL, [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] NOT NULL, [SM_Istf] [bit] NOT NULL, CONSTRAINT [PK__SM_Class__D963B824E04B3DFA] PRIMARY KEY CLUSTERED ( [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]GOSET ANSI_PADDING OFFGOUSE [master]GOALTER DATABASE [StudentManagement] SET READ_WRITE GO
这个数据库的脚本可能需要注意的两点
第一、你必须手动建一个“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 后面的路径在那个盘下面的那个文件.这个搭建好了之后我相信应该会有数据库了吧 !里面的字段可能不够成熟,希望大家多多指导下。