引言
昨天加了一天班,今天閑來無事,就在想如何將之前的三層和最近一直在學的設計模式給聯系在一起,然后就動手弄了個下面的小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 }
結果