[c#基础]使用抽象工厂实现三层

引言

昨天加了一天班,今天闲来无事,就在想如何将之前的三层和最近一直在学的设计模式给联系在一起,然后就动手弄了个下面的小demo。

项目结构

项目各个层实现

Wolfy.Model层中有一个抽象类BaseModel.cs,User.cs是用户实体类,继承与BaseModel类,是用于类型安全考虑的,让各实体类有个统一的父类,在其他层使用的时候,可以使用里氏替换原则的考虑。

复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace Wolfy.Model
 8 {
 9     /// <summary>
10     /// 该抽象类为所有实体类的父类,
11     /// 所有实体类继承该抽象类, 为保持类型一致而设计的父类,也是出于安全性的考虑
12     /// </summary>
13     public abstract class BaseModel
14     {
15     }
16 }
复制代码
复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace Wolfy.Model
 8 {
 9     /// <summary>
10     /// 实体类user继承自BaseModel
11     /// 调用时就可以通过BaseModel model=new UserModel();
12     /// </summary>
13     public class UserModel : BaseModel
14     {
15         public int Id { get; set; }
16         public string UserName { set; get; }
17         public string Password { set; get; }
18     }
19 }
复制代码

Wolfy.FactoryDAL层是用于反射获取实例,其中只有一个类。

复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace Wolfy.FactoryDAL
 8 {
 9     public class DataAccess<T> where T : class
10     {
11         //获取配置路径
12         private static readonly string path = System.Configuration.ConfigurationManager.AppSettings["DAL"];
13         private DataAccess() { }
14         /// <summary>
15         /// 创建实例 反射创建实例
16         /// </summary>
17         /// <param name="type"></param>
18         /// <returns></returns>
19         public static T CreateDAL(string type)
20         {
21             string className = string.Format(path + ".{0}", type);
22             try
23             {
24                 return (T)System.Reflection.Assembly.Load(path).CreateInstance(className);
25 
26             }
27             catch (Exception ex)
28             {
29                 throw new Exception(ex.Message.ToString());
30             }
31         }
32     }
33 }
复制代码

Wolfy.IDAL层依赖与Wolfy.Model,其中包含一个基接口IBaseDAL.cs,还有一个用于定义一些基接口中没有方法的接口IUserDAL,继承基接口IBaseDAL<T>

复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace Wolfy.IDAL
 8 {
 9     /// <summary>
10     /// 所有的dal基本都有增删改查等功能,提取到dal接口层,
11     /// 所有实现该接口的类必须实现所有的未实现的成员
12     /// </summary>
13     /// <typeparam name="T"></typeparam>
14     public interface IBaseDAL<T> where T : Model.BaseModel, new()
15     {
16         bool Add(T model);
17         bool Detele(int ID);
18         bool Update(T model);
19         T GetModel(int ID);
20     }
21 }
复制代码
复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace Wolfy.IDAL
 8 {
 9     /// <summary>
10     /// 需有特殊的方法的 可定义子接口 
11     /// </summary>
12     public interface  IUserDAL:IBaseDAL<Model.UserModel>
13     {
14         /// <summary>
15         /// 判断用户名是否存在
16         /// </summary>
17         /// <param name="userName"></param>
18         /// <returns></returns>
19         bool Exists(string userName);
20         /// <summary>
21         /// 登录
22         /// </summary>
23         /// <param name="name"></param>
24         /// <param name="pwd"></param>
25         /// <returns></returns>
26         Model.UserModel Login(string name, string pwd);
27     }
28 }
复制代码

Wolfy.DAL层,处理数据库的操作。

复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Data;
 7 using System.Data.SqlClient;
 8 namespace Wolfy.DAL
 9 {
10     public class UserDAL : Wolfy.IDAL.IUserDAL
11     {
12         public bool Exists(string userName)
13         {
14             string sql = "select count(*) from Users where UserName=@UserName";
15             SqlParameter[] sp = { 
16                                 new SqlParameter("@UserName",userName)
17                                 };
18 
19             return (int)SqlHelper.ExecuteScalar(CommandType.Text, sql, sp) > 0;
20         }
21 
22         public bool Add(Model.UserModel model)
23         {
24             string sql = "insert into Users values(@UserName,@UserPwd)";
25             SqlParameter[] sp = { 
26                                 new SqlParameter("@UserName",model.UserName),
27                                     new SqlParameter("@UserName",model.Password)
28                                 };
29             return SqlHelper.ExecuteNonQuery(CommandType.Text, sql, sp) > 0;
30         }
31 
32         public bool Detele(int ID)
33         {
34             string sql = "delete from Users where id=" + ID;
35             return SqlHelper.ExecuteNonQuery(CommandType.Text, sql) > 0;
36         }
37 
38         public bool Update(Model.UserModel model)
39         {
40             string sql = string.Format("update Users set UserName={0},UserPwd={1} where id={2}", model.UserName, model.Password, model.Id);
41             return SqlHelper.ExecuteNonQuery(CommandType.Text, sql) > 0;
42         }
43 
44         public Model.UserModel GetModel(int ID)
45         {
46             string sql = "select * from Users where id=" + ID;
47             DataTable dt = SqlHelper.ExecuteDataTable(sql);
48             if (dt != null && dt.Rows.Count > 0)
49             {
50                 return new Model.UserModel() { UserName = dt.Rows[0]["UserName"].ToString(), Password = dt.Rows[0]["UserPwd"].ToString() };
51             }
52             else
53             {
54                 return null;
55             }
56         }
57 
58 
59         public Model.UserModel Login(string name, string pwd)
60         {
61             Model.UserModel model = null;
62             string sql = "select * from Users where UserName=@UserName and UserPwd=@UserPwd";
63             SqlParameter[] sp = { 
64                                 new SqlParameter("@UserName",name),
65                                 new SqlParameter("@UserPwd",pwd)
66                                 };
67             SqlDataReader reader = SqlHelper.ExecuteReader(CommandType.Text, sql, sp);
68             if (reader != null && !reader.IsClosed && reader.HasRows)
69             {
70                 model = new Model.UserModel();
71                 while (reader.Read())
72                 {
73                     model.Id = Convert.ToInt32(reader[0]);
74                     model.UserName = reader[1].ToString();
75                     model.Password = reader[2].ToString();
76                 }
77             }
78             reader.Dispose();
79             return model;
80         }
81     }
82 }
复制代码
复制代码
  1 using System;
  2 using System.Data;
  3 using System.Xml;
  4 using System.Data.SqlClient;
  5 using System.Collections;
  6 using System.Configuration;
  7 using System.IO;
  8 using System.Web;
  9 
 10 
 11 namespace Wolfy.DAL
 12 {
 13     /// <summary>
 14     /// 数据库的通用访问代码
 15     /// 此类为抽象类,不允许实例化,在应用时直接调用即可
 16     /// </summary>
 17     public abstract class SqlHelper
 18     {
 19         //获取数据库连接字符串,其属于静态变量且只读,项目中所有文档可以直接使用,但不能修改
 20         public static readonly string connectionString = ConfigurationManager.ConnectionStrings["SqlConnect"].ConnectionString;
 21 
 22 
 23         // 哈希表用来存储缓存的参数信息,哈希表可以存储任意类型的参数。
 24         private static Hashtable parmCache = Hashtable.Synchronized(new Hashtable());
 25 
 26         /// <summary>
 27         ///执行一个不需要返回值的SqlCommand命令,通过指定专用的连接字符串。
 28         /// 使用参数数组形式提供参数列表 
 29         /// </summary>
 30         /// <remarks>
 31         /// 使用示例:
 32         ///  int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
 33         /// </remarks>
 34         /// <param name="connectionString">一个有效的数据库连接字符串</param>
 35         /// <param name="commandType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param>
 36         /// <param name="commandText">存储过程的名字或者 T-SQL 语句</param>
 37         /// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param>
 38         /// <returns>返回一个数值表示此SqlCommand命令执行后影响的行数</returns>
 39         public static int ExecuteNonQuery(CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
 40         {
 41             SqlCommand cmd = new SqlCommand();
 42             using (SqlConnection conn = new SqlConnection(connectionString))
 43             {
 44                 //通过PrePareCommand方法将参数逐个加入到SqlCommand的参数集合中
 45                 PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters);
 46                 int val = cmd.ExecuteNonQuery();
 47                 //清空SqlCommand中的参数列表
 48                 cmd.Parameters.Clear();
 49                 return val;
 50             }
 51         }
 52 
 53         /// <summary>
 54         ///执行一条不返回结果的SqlCommand,通过一个已经存在的数据库连接 
 55         /// 使用参数数组提供参数
 56         /// </summary>
 57         /// <remarks>
 58         /// 使用示例:  
 59         ///  int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
 60         /// </remarks>
 61         /// <param name="conn">一个现有的数据库连接</param>
 62         /// <param name="commandType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param>
 63         /// <param name="commandText">存储过程的名字或者 T-SQL 语句</param>
 64         /// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param>
 65         /// <returns>返回一个数值表示此SqlCommand命令执行后影响的行数</returns>
 66         public static int ExecuteNonQuery(SqlConnection connection, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
 67         {
 68             SqlCommand cmd = new SqlCommand();
 69             PrepareCommand(cmd, connection, null, cmdType, cmdText, commandParameters);
 70             int val = cmd.ExecuteNonQuery();
 71             cmd.Parameters.Clear();
 72             return val;
 73         }
 74 
 75         /// <summary>
 76         /// 执行一条不返回结果的SqlCommand,通过一个已经存在的数据库事物处理 
 77         /// 使用参数数组提供参数
 78         /// </summary>
 79         /// <remarks>
 80         /// 使用示例: 
 81         ///  int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
 82         /// </remarks>
 83         /// <param name="trans">一个存在的 sql 事物处理</param>
 84         /// <param name="commandType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param>
 85         /// <param name="commandText">存储过程的名字或者 T-SQL 语句</param>
 86         /// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param>
 87         /// <returns>返回一个数值表示此SqlCommand命令执行后影响的行数</returns>
 88         public static int ExecuteNonQuery(SqlTransaction trans, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
 89         {
 90             SqlCommand cmd = new SqlCommand();
 91             PrepareCommand(cmd, trans.Connection, trans, cmdType, cmdText, commandParameters);
 92             int val = cmd.ExecuteNonQuery();
 93             cmd.Parameters.Clear();
 94             return val;
 95         }
 96 
 97         /// <summary>
 98         /// 执行一条返回结果集的SqlCommand命令,通过专用的连接字符串。
 99         /// 使用参数数组提供参数
100         /// </summary>
101         /// <remarks>
102         /// 使用示例:  
103         ///  SqlDataReader r = ExecuteReader(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
104         /// </remarks>
105         /// <param name="connectionString">一个有效的数据库连接字符串</param>
106         /// <param name="commandType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param>
107         /// <param name="commandText">存储过程的名字或者 T-SQL 语句</param>
108         /// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param>
109         /// <returns>返回一个包含结果的SqlDataReader</returns>
110         public static SqlDataReader ExecuteReader(CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
111         {
112             SqlCommand cmd = new SqlCommand();
113             SqlConnection conn = new SqlConnection(connectionString);
114             // 在这里使用try/catch处理是因为如果方法出现异常,则SqlDataReader就不存在,
115             //CommandBehavior.CloseConnection的语句就不会执行,触发的异常由catch捕获。
116             //关闭数据库连接,并通过throw再次引发捕捉到的异常。
117             try
118             {
119                 PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters);
120                 SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
121                 cmd.Parameters.Clear();
122                 return rdr;
123             }
124             catch
125             {
126                 conn.Close();
127                 throw;
128             }
129         }
130 
131         /// <summary>
132         /// 执行一条返回第一条记录第一列的SqlCommand命令,通过专用的连接字符串。 
133         /// 使用参数数组提供参数
134         /// </summary>
135         /// <remarks>
136         /// 使用示例:  
137         ///  Object obj = ExecuteScalar(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
138         /// </remarks>
139         /// <param name="connectionString">一个有效的数据库连接字符串</param>
140         /// <param name="commandType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param>
141         /// <param name="commandText">存储过程的名字或者 T-SQL 语句</param>
142         /// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param>
143         /// <returns>返回一个object类型的数据,可以通过 Convert.To{Type}方法转换类型</returns>
144         public static object ExecuteScalar(CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
145         {
146             SqlCommand cmd = new SqlCommand();
147             using (SqlConnection connection = new SqlConnection(connectionString))
148             {
149                 PrepareCommand(cmd, connection, null, cmdType, cmdText, commandParameters);
150                 object val = cmd.ExecuteScalar();
151                 cmd.Parameters.Clear();
152                 return val;
153             }
154         }
155 
156         /// <summary>
157         /// 执行一条返回第一条记录第一列的SqlCommand命令,通过已经存在的数据库连接。
158         /// 使用参数数组提供参数
159         /// </summary>
160         /// <remarks>
161         /// 使用示例: 
162         ///  Object obj = ExecuteScalar(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
163         /// </remarks>
164         /// <param name="conn">一个已经存在的数据库连接</param>
165         /// <param name="commandType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param>
166         /// <param name="commandText">存储过程的名字或者 T-SQL 语句</param>
167         /// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param>
168         /// <returns>返回一个object类型的数据,可以通过 Convert.To{Type}方法转换类型</returns>
169         public static object ExecuteScalar(SqlConnection connection, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
170         {
171             SqlCommand cmd = new SqlCommand();
172             PrepareCommand(cmd, connection, null, cmdType, cmdText, commandParameters);
173             object val = cmd.ExecuteScalar();
174             cmd.Parameters.Clear();
175             return val;
176         }
177 
178         /// <summary>
179         /// 缓存参数数组
180         /// </summary>
181         /// <param name="cacheKey">参数缓存的键值</param>
182         /// <param name="cmdParms">被缓存的参数列表</param>
183         public static void CacheParameters(string cacheKey, params SqlParameter[] commandParameters)
184         {
185             parmCache[cacheKey] = commandParameters;
186         }
187 
188         /// <summary>
189         /// 获取被缓存的参数
190         /// </summary>
191         /// <param name="cacheKey">用于查找参数的KEY值</param>
192         /// <returns>返回缓存的参数数组</returns>
193         public static SqlParameter[] GetCachedParameters(string cacheKey)
194         {
195             SqlParameter[] cachedParms = (SqlParameter[])parmCache[cacheKey];
196             if (cachedParms == null)
197                 return null;
198             //新建一个参数的克隆列表
199             SqlParameter[] clonedParms = new SqlParameter[cachedParms.Length];
200             //通过循环为克隆参数列表赋值
201             for (int i = 0, j = cachedParms.Length; i < j; i++)
202                 //使用clone方法复制参数列表中的参数
203                 clonedParms[i] = (SqlParameter)((ICloneable)cachedParms[i]).Clone();
204             return clonedParms;
205         }
206 
207         /// <summary>
208         /// 为执行命令准备参数
209         /// </summary>
210         /// <param name="cmd">SqlCommand 命令</param>
211         /// <param name="conn">已经存在的数据库连接</param>
212         /// <param name="trans">数据库事物处理</param>
213         /// <param name="cmdType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param>
214         /// <param name="cmdText">Command text,T-SQL语句 例如 Select * from Products</param>
215         /// <param name="cmdParms">返回带参数的命令</param>
216         private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, CommandType cmdType, string cmdText, SqlParameter[] cmdParms)
217         {
218             //判断数据库连接状态
219             if (conn.State != ConnectionState.Open)
220                 conn.Open();
221             cmd.Connection = conn;
222             cmd.CommandText = cmdText;
223             //判断是否需要事物处理
224             if (trans != null)
225                 cmd.Transaction = trans;
226             cmd.CommandType = cmdType;
227             if (cmdParms != null)
228             {
229                 foreach (SqlParameter parm in cmdParms)
230                     cmd.Parameters.Add(parm);
231             }
232         }
233 
234         /// <summary>
235         /// 获取dataset数据
236         /// </summary>
237         /// <param name="sql"></param>
238         /// <returns></returns>
239         public static DataTable ExecuteDataTable(string sql)
240         {
241             using (SqlConnection conn = new SqlConnection(connectionString))
242             {
243                 SqlDataAdapter da = new SqlDataAdapter(sql, conn);
244                 DataTable dst = new DataTable();
245                 da.Fill(dst);
246                 return dst;
247             }
248         }
249     }
250 }
复制代码

Wolfy.BLL业务逻辑层中包含了一个用于继承的基类BaseBLL<T>和用户业务逻辑UserBLL类,这层依赖Wolfy.IDAL,Wolfy.Model,Wolfy.FactoryDAL库

复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace Wolfy.BLL
 8 {
 9     public class BaseBLL<T> where T : Wolfy.Model.UserModel, new()
10     {
11         protected Wolfy.IDAL.IBaseDAL<T> Dal;
12         public BaseBLL(string type)
13         {
14             //通过工厂得到 dal
15             Dal = Wolfy.FactoryDAL.DataAccess<Wolfy.IDAL.IBaseDAL<T>>.CreateDAL(type);
16         }
17         public virtual bool Add(T model)
18         {
19             return Dal.Add(model);
20         }
21         public virtual bool Delete(int ID)
22         { return Dal.Detele(ID); }
23         public virtual bool Update(T model)
24         { return Dal.Update(model); }
25         public virtual T GetModel(int ID)
26         {
27             return Dal.GetModel(ID);
28         }
29        
30     }
31 }
复制代码
复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace Wolfy.BLL
 8 {
 9     public class UserBLL : BaseBLL<Wolfy.Model.UserModel>
10     {
11         private const string _Type = "UserDAL";
12         private Wolfy.IDAL.IUserDAL _DAL;
13         public UserBLL()
14             : base(_Type)
15         {
16             _DAL = base.Dal as Wolfy.IDAL.IUserDAL;
17             if (_DAL == null)
18             {
19                 throw new NullReferenceException(_Type);
20             }
21         }
22         public bool Exists(string userName)
23         {
24             return _DAL.Exists(userName);
25         }
26         public Model.UserModel Login(string name, string pwd)
27         { return _DAL.Login(name, pwd); }
28     }
29 }
复制代码

web.config程序集名称,连接字符串配置

复制代码
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!--
 3   有关如何配置 ASP.NET 应用程序的详细信息,请访问
 4   http://go.microsoft.com/fwlink/?LinkId=169433
 5   -->
 6 <configuration>
 7   <system.web>
 8     <compilation debug="true" targetFramework="4.5" />
 9     <httpRuntime targetFramework="4.5" />
10 
11   </system.web>
12   <connectionStrings>
13     <add name="SqlConnect" connectionString="server=.;database=Test;uid=sa;pwd=sa"/>
14   </connectionStrings>
15 <appSettings>
16   <add key="DAL" value="Wolfy.DAL"/>
17 </appSettings>
18 </configuration>
复制代码

测试

简单的ajax登录,web项目需引用Wolfy.BLL.dll和Wolfy.Model.dll和Wolfy.DAL.dll

复制代码
 1 <!DOCTYPE html>
 2 <html xmlns="http://www.w3.org/1999/xhtml">
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5     <title>wolfy信息系统登录</title>
 6     <script type="text/javascript" src="Scripts/jquery-1.11.0.js"></script>
 7     <script type="text/javascript">
 8         $(function () {
 9             $("#btnLogin").click(function () {
10                 var name = $("#txtUserName").val();
11                 var pwd = $("#txtPwd").val();
12                 $.ajax({
13                     url: "Ashx/Login.ashx",
14                     data: "name=" + name + "&pwd=" + pwd,
15                     type: "Post",
16                     dataType: "text",
17                     success: function (msg) {
18                         if (msg == "1") {
19                             $("#divMsg").html("登录成功");
20                         } else if(msg=="2") {
21                             $("#divMsg").html("用户名或密码为空");
22                         } else if(msg=="3"){
23                             $("#divMsg").html("用户名不存在");
24                         } else {
25                             $("#divMsg").html("密码错误");
26                         }
27                     }
28 
29 
30                 });
31             });
32         });
33     </script>
34 </head>
35 <body>
36     <table>
37         <tr>
38             <td>用户名:</td>
39             <td><input type="text" id="txtUserName" name="name" value="admin" /></td>
40         </tr>
41         <tr>
42             <td>密码:</td>
43             <td><input type="password" id="txtPwd" name="name" value="admin" /></td>
44         </tr>
45         <tr>
46             <td colspan="2"><input type="button" id="btnLogin" name="name" value="登录" /></td>
47         </tr>
48     </table>
49     <div id="divMsg"></div>
50 </body>
51 </html>
复制代码
复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 
 6 namespace Wolfy.LoginDemo.Ashx
 7 {
 8     /// <summary>
 9     /// Login 的摘要说明
10     /// </summary>
11     public class Login : IHttpHandler
12     {
13 
14         public void ProcessRequest(HttpContext context)
15         {
16             context.Response.ContentType = "text/plain";
17             //接收用户名和密码
18             string name = context.Request["name"];
19             string pwd = context.Request["pwd"];
20             if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pwd))
21             {
22                 context.Response.Write("2");
23             }
24             else
25             {
26                 BLL.UserBLL bll = new BLL.UserBLL();
27                 Model.UserModel model = new Model.UserModel();
28                 if (!bll.Exists(name))
29                 {
30                     context.Response.Write("3");
31                 }
32                 else
33                 {
34                     model = bll.Login(name, pwd);
35                     if (model != null)
36                     {
37                         //登录成功记入cookie
38                         context.Response.Cookies["n"].Value = name;
39                         context.Response.Cookies["n"].Expires = DateTime.Now.AddDays(7);
40                         context.Response.Cookies["p"].Value = pwd;
41                         context.Response.Cookies["p"].Expires = DateTime.Now.AddDays(7);
42                         context.Response.Write("1");
43                     }
44                 }
45 
46 
47 
48             }
49         }
50 
51         public bool IsReusable
52         {
53             get
54             {
55                 return false;
56             }
57         }
58     }
59 }
复制代码

结果

源码下载:http://pan.baidu.com/s/1hqqSUrU

总结

参考文章:http://www.cnblogs.com/cmsdn/p/3494461.html

参考着这篇文章,敲了一遍,实践了一下。在博客园,虽然有很多提供代码的园友,但是自己动手实践一下,就可以发现其中好与不好的地方,也可以加深理解。

博客地址:http://www.cnblogs.com/wolf-sun/
博客版权:本文以学习、研究和分享为主,欢迎转载,但必须在文章页面明显位置给出原文连接。
如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步!
再次感谢您耐心的读完本篇文章。

转载:http://www.cnblogs.com/wolf-sun/p/3562156.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/543175.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php 当前ip_php获取本机ip(远程IP地址)

例子&#xff0c;php获取用户IP地址。复制代码 代码示例:// 111111111111echo $_SERVER[REMOTE_ADDR];// 2222222222222function get_local_ip() {$preg "/\A((([0-9]?[0-9])|(1[0-9]{2})|(2[0-4][0-9])|(25[0-5]))\.){3}(([0-9]?[0-9])|(1[0-9]{2})|(2[0-4][0-9])|(25…

场效应管原理_场效应管——不就是一个电控开关?

管在mpn中&#xff0c;它的长相和我们常面讲的三极管非常像&#xff0c;所以有不少修朋友好长时间还分不清楚&#xff0c;统一的把这些长相相同的三极管、场效应管、双二极管、还有各种稳压IC统统称作“三个脚的管管”&#xff0c;呵呵&#xff0c;如果这样麻木不分的话&#x…

解决phpMyAdmin在nginx+php-fpm模式下无法使用的问题

原创作品&#xff0c;允许转载&#xff0c;转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://dgd2010.blog.51cto.com/1539422/1684839 昨天接到一个网友的问题&#xff0c;说yum安装nginxphp-fpmmysqlphpMyAdmin后&#xff0c;发现…

python库有什么用_Python程序员必知什么 常用的Python库有哪些

Python程序员必知什么&#xff1f;常用的Python库有哪些&#xff1f;Python有很多丰富而强大的库&#xff0c;这是它成为人工智能与数据分析领域强者的关键。有很多Python开发人员想知道常用的Python库有哪些&#xff0c;接下来就给大家详细介绍一下。ArrowPython中处理时间的库…

三次握手面试题java_java面试题三次握手和四次挥手-嗨客网

题目对 tcp 了解吗&#xff1f;讲讲它的三次握手和四次挥手&#xff1f;为什么需要三次握手&#xff0c;为什么需要四次挥手。答案三次握手第一次握手&#xff1a;客户端向服务器发送连接请求&#xff0c;这个时候报文首部中的同步为 SYN 1&#xff0c;同时生成一个随机序列号…

运维经验分享(三)-- 解决Ubuntu下crontab不能正确执行脚本的问题

原创作品&#xff0c;允许转载&#xff0c;转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://dgd2010.blog.51cto.com/1539422/1676490 运维经验分享作为一个专题&#xff0c;目前共7篇文章 《运维经验分享&#xff08;一&#xff0…

一个jsp能取到父类jsp的值吗_「Javaweb」ssm整合权限控制框架shiro,你知道怎么做吗?...

为美好而努力——羊羽科技说。最近在开发自己的网站&#xff0c;需要权限控制功能&#xff0c;在网上找了一下&#xff0c;找到了我接下来要介绍的shiro框架。shiro框架是Apache公司维护的开源产品之一&#xff0c;其官网对其的简介是这样的&#xff1a;shiro官网简介翻译过来就…

php for嵌套循环_PHP中的for循环怎样嵌套

本篇文章主要介绍 PHP中的for循环怎样嵌套&#xff0c;感兴趣的朋友参考下&#xff0c;希望对大家有所帮助。for循环的执行原理&#xff1a;for循环的参数有(初始值&#xff1b;判断条件&#xff1b;更新循环变量表达式) 三者均不是必须的&#xff0c;若三者不完整则必须在适当…

Visio显示不完整

下面显示不完整的话&#xff0c;选中对象&#xff0c;菜单栏设置&#xff08;点击对象&#xff0c;右键并没有段落选项&#xff09;行距为单倍&#xff1b;右侧显示不完整&#xff0c;选中后右键设置环绕方式为负于文字上方&#xff0c;原来是嵌入型。

python2 python3 通信_python与USB通信

Date周三 04 十一月 2015TagsUSB/PythonPyUSB依赖于一些USB的驱动程序, 这个貌似叫做无驱驱动, 其中libusb是一统天下者, 当然就要用这个咯. 那么问题来了, libusb这个驱动是怎么装到要开发的设备上呢? 在windows下答案是Zadig, 这个和rtlsdr用的方案是一致的.下载了最新的Zad…

php设置用户头像,PHP针对多用户实现更换头像功能

一个网站&#xff0c;其实说白了就是某几个特定功能的组合&#xff0c;而更换用户头像就在这些功能之中。今天就来做个测试&#xff0c;针对不同的用户&#xff0c;实现头像上传功能。先给大家展示下成品效果图&#xff1a;思路针对不同的用户上传头像&#xff0c;我们要为每一…

执行计划中cpu耗时_面试被问怎么排查遇到的系统CPU飙高和频繁GC,到底该怎么回答?...

处理过线上问题的同学基本上都会遇到系统突然运行缓慢&#xff0c;CPU 100%&#xff0c;以及Full GC次数过多的问题。当然&#xff0c;这些问题的最终导致的直观现象就是系统运行缓慢&#xff0c;并且有大量的报警。本文主要针对系统运行缓慢这一问题&#xff0c;提供该问题的排…

可视化数据包分析工具-CapAnalysis

原创作品&#xff0c;允许转载&#xff0c;转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://chenguang.blog.51cto.com/350944/1325742 可视化数据包分析工具-CapAnalysis 我们知道&#xff0c;Xplico是一个从pcap文件中解析出IP流…

网易云歌单添加到php,给自己的网站添加网易云音乐歌单吧^ ^

这个是怎么实现的&#xff1f;一起来看看吧APlayer首先我们需要一个音频播放器&#xff0c;这里我用到了APlayer&#xff0c;这是由bilibili前端大神DIYgod开源的播放器&#xff0c;有兴趣的可以去TA的主页看看&#xff0c;非常惊艳&#xff0c;这里我就不多说了我们看一下APla…

python学完面向对象之后_Python学完基础语法后,再往后应该学什么?

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼第一阶段&#xff1a;Python语言及应用课程内容&#xff1a;Python语言基础&#xff0c;面向对象设计&#xff0c;多线程编程&#xff0c;数据库交互技术&#xff0c;前端特效&#xff0c;Web框架&#xff0c;爬虫框架&#xff0c;…

百度应用部署秘籍

2019独角兽企业重金招聘Python工程师标准>>> 【背景介绍】 传统PaaS采用sandbox实现app间的资源安全隔离&#xff0c;sandbox需要对运行环境和编程语言进行底层的功能限制&#xff0c;例如&#xff1a;禁止创建进程和线程&#xff0c;禁止部分系统调用&#xff0c;禁…

php新闻删除功能设计,php原生开发新闻站之删除新闻

我们前两篇文章都完成了新闻的添加、修改。那么我们这个节课程就给大家介绍删除新闻&#xff0c;这个比之前的两个都要简单点&#xff01;首先创建一个new_delete.php,接着我们要在新闻列表页找到删除的按钮&#xff0c;给这个按钮加一个连接&#xff0c;我们同样需要通过id来传…

java8新特性_JAVA8十大新特性详解

一、接口的默认方法Java 8允许我们给接口添加一个非抽象的方法实现&#xff0c;只需要使用 default关键字即可&#xff0c;这个特征又叫做扩展方法&#xff0c;示例如下&#xff1a;interface Formula { double calculate(int a); default double sqrt(int a) { return Math.sq…

spark1.6.1 on yarn搭建部署

注&#xff1a;本文是建立在hadoop已经搭建完成的基础上进行的。 Apache Spark是一个分布式计算框架&#xff0c;旨在简化运行于计算机集群上的并行程序的编写。该框架对资源调度&#xff0c;任务的提交、执行和跟踪&#xff0c;节点间的通信以及数据并行处理的内在底层操作都进…

php 精度问题怎么解决,JavaScript 中精度问题以及解决方案

JavaScript 中的数字按照 IEEE 754 的标准&#xff0c;使用 64 位双精度浮点型来表示。其中符号位 S&#xff0c;指数位 E&#xff0c;尾数位M分别占了 1&#xff0c;11&#xff0c;52 位&#xff0c;并且在 ES5 规范 中指出了指数位E的取值范围是 [-1074, 971]。精度问题汇总想…