通過前三個模塊的介紹,把web權限系統開發所需要的基本類,Css文件,EasyUI框架等准備好后,就可以着手開始系統的編碼了。
登陸模塊是權限處理系統的關鍵,根據輸入用戶的的信息,可自動從數據庫中加載該用戶可以訪問的頁面,匹配出可以操作的模塊。
由於登錄模塊是系統的基本模塊,因此沒有單獨放在一個域里面。登錄的控制器在項目默認的Controllers文件夾下。登錄對應的視圖在項目默認的Views文件夾下。
1.1視圖
登錄視圖中比較重要的是通過.NET MVC的Ajax異步方式提交用戶名和密碼到后台服務。
提交格式如下:@using (Ajax.BeginForm("Login", "Login",
new AjaxOptions
{
OnBegin = "loginBefore",
OnSuccess = "showMessage"
}))
在提交數據前做必要的數據格式校驗,提交成功后,通過Login.js文件中的函數跳轉到首頁。登錄模塊的詳細視圖內容如下:

1 @{ 2 Layout = null; 3 } 4 5 <!DOCTYPE html> 6 7 <html> 8 <head> 9 <meta name="viewport" content="width=device-width" /> 10 <title>用戶登錄</title> 11 <script src="~/Scripts/jquery-1.7.1.js"></script> 12 <link href="~/Content/css/login.css" rel="stylesheet" /> 13 <link href="~/Content/easyui143/themes/bootstrap/easyui.css" rel="stylesheet" /> 14 <style type="text/css"> 15 .passwordtxt { 16 height: 35px; 17 width: 117px; 18 line-height: 27px; 19 border: none; 20 border: none; 21 font-size: 14px; 22 text-indent: 10px; 23 background: url(../../Content/images/passwordtxt.png); 24 vertical-align: middle; 25 color: black; 26 margin-left: 5px; 27 } 28 29 30 .inputicon { 31 margin-left: -410px; 32 vertical-align: middle; 33 } 34 35 .btn, .yzm { 36 cursor: pointer; 37 } 38 39 40 .txtfocus { 41 height: 42px; 42 width: 262px; 43 line-height: 27px; 44 border: none; 45 border: none; 46 font-size: 14px; 47 text-indent: 10px; 48 background: url(../../Content/images/inputing.png) no-repeat; 49 vertical-align: middle; 50 color: black; 51 } 52 53 54 .passwordfocustxt { 55 height: 35px; 56 width: 117px; 57 line-height: 27px; 58 border: none; 59 border: none; 60 font-size: 14px; 61 text-indent: 10px; 62 background: url(../../Content/images/checkcodeinputing.png); 63 vertical-align: middle; 64 color: black; 65 margin-left: 5px; 66 } 67 </style> 68 <script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script> 69 70 </head> 71 <body> 72 <div class="all"> 73 <div class="loginContent"> 74 <div class="loginContent-inner"> 75 <h1 class="loginTitle"></h1> 76 <div class="main"> 77 <div class="erro"> 78 </div> 79 <ul class="loginList"> 80 @using (Ajax.BeginForm("Login", "Login", 81 new AjaxOptions 82 { 83 OnBegin = "loginBefore", 84 OnSuccess = "showMessage" 85 })) 86 { 87 <li> 88 <span>用戶名</span> 89 <input type="text" tabindex="1" class="txt" name="userName" id="UserName" style="padding-left: 35px;" /> 90 <input type="submit" name="LoginBut" class="btn" value="登錄" style="border-width: 0px;" onclick=" return Login();" /> 91 <img src="/Content/Images/user1.png" class="inputicon" id="userNameImg" /> 92 </li> 93 94 <li> 95 <span>密 碼</span> 96 <input name="password" id="Password" type="password" tabindex="2" class="txt" style="padding-left: 35px;" /> 97 <input type="button" onclick="javascript: Cancel();" class="submit" value="重置" style="border: 0px; cursor: pointer;" /> 98 <img src="/Content/Images/password1.png" class="inputicon" id="passwordImg" /> 99 </li> 100 <li> 101 <span>驗證碼</span> 102 <input type="text" tabindex="3" name="checkCode" id="txtCheckCode" class="passwordtxt" /> 103 <img src="/ValidateCode/ValidateCode" id="CheckImage" 104 onclick="ChangeCode()" width="69" height="27" class="yzm" /> 105 <a href="javascript:ChangeCode();" style="color: #00689d; text-decoration: underline;">換一張</a> 106 </li> 107 } 108 </ul> 109 </div> 110 <div class="loginFooter"> 111 支持FireFox、IE8及其以上版本的瀏覽器 112 <br /> 113 技術支持:######<span></span> 114 </div> 115 @if (ViewData["AA"] == null) 116 { 117 <div> 118 </div> 119 } 120 </div> 121 </div> 122 </div> 123 124 <script type="text/javascript" src="~/Scripts/CustomJs/login.js"> 125 </script> 126 127 </body> 128 </html>
1.2 JS文件
登錄模塊所用的JS文件在項目的根目錄Scripts目錄下。它主要是提交登錄信息,根據服務器返回的結果判斷登錄信息是否有效。詳細的JS代碼如下:

1 //顯示遮罩層 2 function LoadMask(msg) { 3 var panel = $("body"); 4 if (msg == undefined) { 5 msg = "正在登陸,請稍候..."; 6 } 7 $("<div class=\"datagrid-mask\"></div>").css({ display: "block", width: panel.width(), height: panel.height() }).appendTo(panel); 8 $("<div class=\"datagrid-mask-msg\"></div>").html(msg).appendTo(panel).css({ display: "block", left: (panel.width() - $("div.datagrid-mask-msg", panel).outerWidth()) / 2, top: (panel.height() - $("div.datagrid-mask-msg", panel).outerHeight()) / 2 }); 9 }; 10 11 //隱藏遮罩層 12 function HideMask() { 13 var panel = $("body"); 14 panel.find("div.datagrid-mask-msg").remove(); 15 panel.find("div.datagrid-mask").remove(); 16 }; 17 18 //刷新驗證碼 19 function ChangeCode() { 20 $("#CheckImage").prop("src", "/ValidateCode/ValidateCode/" + Math.ceil(Math.random() * 1000)); 21 $("#txtCheckCode").val(""); 22 }; 23 24 //前台驗證用戶輸入信息 25 function Login() { 26 if ($("#UserName").val().replace(/ /g, "") == "") { 27 alert("請輸入帳號!"); 28 return false; 29 } 30 if ($("#Password").val().replace(/ /g, "") == "") { 31 alert("請輸入密碼!"); 32 return false; 33 } 34 35 if ($("#txtCheckCode").val().replace(/ /g, "") == "") { 36 alert("請輸入驗證碼!"); 37 return false; 38 } 39 return true; 40 } 41 42 //重置,清空用戶已經輸入的信息 43 function Cancel() { 44 $("#UserName").val(""); 45 $("#Password").val(""); 46 $("#txtCheckCode").val(""); 47 ChangeCode(); 48 } 49 50 function loginBefore() { 51 if ($("#UserName").val().replace(/ /g, "") == "") { 52 alert("請輸入帳號!"); 53 return false; 54 } 55 if ($("#Password").val().replace(/ /g, "") == "") { 56 alert("請輸入密碼!"); 57 return false; 58 } 59 60 if ($("#txtCheckCode").val().replace(/ /g, "") == "") { 61 alert("請輸入驗證碼!"); 62 return false; 63 } 64 LoadMask(); 65 return true; 66 }; 67 68 //將用戶信息提交到后台,經后台驗證后的操作,回調函數 69 function showMessage(data) { 70 HideMask(); 71 if (data == "1") { 72 window.location.href = "/IndexHome/IndexHome"; 73 } 74 else { 75 alert(data); 76 $("#Password").val(""); 77 //刷新驗證碼 78 ChangeCode(); 79 } 80 } 81 82 83 $(function () { 84 85 $("#UserName").focus(function () { 86 $(this).removeClass("txt"); 87 $(this).addClass("txtfocus"); 88 $("#userNameImg").attr("src", "/Content/Images/user2.png"); 89 }).blur(function () { 90 $(this).removeClass("txtfocus"); 91 $(this).addClass("txt"); 92 $("#userNameImg").attr("src", "/Content/Images/user1.png"); 93 }); 94 95 96 $("#Password").focus(function () { 97 $(this).removeClass("txt"); 98 $(this).addClass("txtfocus"); 99 $("#passwordImg").attr("src", "/Content/Images/password2.png"); 100 }).blur(function () { 101 $(this).removeClass("txtfocus"); 102 $(this).addClass("txt"); 103 $("#passwordImg").attr("src", "/Content/Images/password1.png"); 104 }); 105 106 $("#txtCheckCode").focus(function () { 107 $(this).removeClass("passwordtxt"); 108 $(this).addClass("passwordfocustxt"); 109 }).blur(function () { 110 $(this).removeClass("passwordfocustxt"); 111 $(this).addClass("passwordtxt"); 112 }); 113 114 115 });
1.3 控制器
登錄控制器是整個權限處理的核心模塊,它根據用戶的信息自動加載出用戶可以訪問的目錄信息,可以訪問的網頁信息通過Session的方式,把信息通過SessionManage基本類進行會話管理。部分代碼如下:
SessionManage.CurrentUser = null;先清空會話信息
#region 封裝用戶信息
var currentUser = new AccountInfo();
currentUser.OperatorId = Convert.ToString(dr["accountid"]);
currentUser.OperatorName = DBNull.Value.Equals(dr["accountname"]) ? "" : Convert.ToString(dr["accountname"]);
currentUser.AliasName = DBNull.Value.Equals(dr["aliasname"]) ? "" : Convert.ToString(dr["aliasname"]);
currentUser.Sex = DBNull.Value.Equals(dr["sex"]) ? "" : (Convert.ToInt32(dr["sex"]) == 0 ? "男" : "女");
currentUser.OperatorGroupId = DBNull.Value.Equals(dr["groupid"]) ? "" : Convert.ToString(dr["groupid"]);
currentUser.OperatorGroupName = (string.IsNullOrEmpty(groupName) ? "" : groupName.Substring(0, groupName.Length - 1));
SessionManage.CurrentUser = currentUser; //保存基本信息
#endregion
//目錄列表(存儲登錄人員可以訪問的一級目錄和訪問的網頁)
IList<Catalog> navigationList = new List<Catalog>();
IList<Catalog> rightList = new List<Catalog>();
控制器的完整代碼如下:

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 using Session; 7 using OdbcDbAccess; 8 using System.Data; 9 using Models; 10 using LogInfo; 11 12 namespace CqReportSystem 13 { 14 public class LoginController : Controller 15 { 16 /// <summary> 17 /// **************************** 18 /// 功能:登陸類 19 /// 作者:王令 20 /// 時間:2015-7-18 21 /// 郵箱:1129137758@qq.com 22 /// **************************** 23 24 public ActionResult Login() 25 { 26 SessionManage.CurrentUser = null; 27 Session.Clear(); 28 return View(); 29 } 30 31 /// <summary> 32 /// 用戶登陸信息驗證 33 /// </summary> 34 /// <param name="userName">賬號</param> 35 /// <param name="password">密碼</param> 36 /// <param name="checkCode">驗證碼</param> 37 /// <returns></returns> 38 [HttpPost] 39 public ContentResult Login(string userName, string password, string checkCode) 40 { 41 #region 不為空、驗證碼驗證 42 43 if (string.IsNullOrEmpty(userName) || userName.Trim() == "") 44 { 45 return Content("請輸入用戶名!"); 46 } 47 if (string.IsNullOrEmpty(password) || password.Trim() == "") 48 { 49 return Content("請輸入登陸密碼!"); 50 } 51 if (string.IsNullOrEmpty(checkCode) || checkCode.Trim() == "") 52 { 53 return Content("請輸入驗證碼!"); 54 } 55 if (Session["CheckCode"] == null) 56 { 57 Log.SaveLoginLog(0, "驗證碼過期"); 58 return Content("驗證碼已過期,請刷新驗證碼!"); 59 } 60 if (String.Compare(Session["CheckCode"].ToString(), checkCode, true) != 0) 61 { 62 Log.SaveLoginLog(0, "驗證碼有誤"); 63 return Content("驗證碼有誤!"); 64 } 65 #endregion 66 67 //移除驗證碼信息 68 Session.Remove("CheckCode"); 69 string sql = "select * from operatorinfo where accountid='" + userName.Trim() + "' and passwords='" + password.Trim() + "' "; 70 try 71 { 72 string groupName = ""; 73 #region 基本信息判斷 74 //判斷用戶名和密碼是否正確 75 DataSet dataSet = SqlHelper.ExecuteQuery(ConnectionHelper.GeSqlDbConnectionStr(), sql); 76 if (dataSet == null || dataSet.Tables.Count < 1 || dataSet.Tables[0].Rows.Count < 1) 77 { 78 Log.SaveLoginLog(0, "用戶名或密碼有誤"); 79 return Content("用戶名或密碼有誤!"); 80 } 81 //賬號是否啟用 82 DataRow dr = dataSet.Tables[0].Rows[0]; 83 if (DBNull.Value.Equals(dr["isonstaff"]) || Convert.ToInt32(dr["isonstaff"]) != 1) 84 { 85 Log.SaveLoginLog(0, "該賬號未啟用"); 86 return Content("該賬號未啟用!"); 87 } 88 //查找用戶所屬組 89 sql = "select groupname,state from operatorgroup where groupid in (" + Convert.ToString(dr["groupid"]) + ")"; 90 DataSet groupSet = SqlHelper.ExecuteQuery(ConnectionHelper.GeSqlDbConnectionStr(), sql); 91 if (groupSet == null || groupSet.Tables.Count < 1 || groupSet.Tables[0].Rows.Count < 1) 92 { 93 Log.SaveLoginLog(0, "未找到該用戶所屬用戶組"); 94 return Content("未找到該用戶所屬用戶組!"); 95 } 96 97 foreach (DataRow groupRow in groupSet.Tables[0].Rows) 98 { 99 if (DBNull.Value.Equals(groupRow["state"]) || Convert.ToInt32(groupRow["state"]) != 1) 100 { 101 Log.SaveLoginLog(0, "該用戶所屬用戶組未被啟用"); 102 return Content("該用戶所屬用戶組未被啟用!"); 103 } 104 if (!DBNull.Value.Equals(groupRow["groupname"])) 105 { 106 groupName += Convert.ToString(groupRow["groupname"]) + ","; 107 } 108 } 109 110 #endregion 111 var currentUser = new AccountInfo(); 112 #region 封裝用戶信息 113 currentUser.OperatorId = Convert.ToString(dr["accountid"]); 114 currentUser.OperatorName = DBNull.Value.Equals(dr["accountname"]) ? "" : Convert.ToString(dr["accountname"]); 115 currentUser.AliasName = DBNull.Value.Equals(dr["aliasname"]) ? "" : Convert.ToString(dr["aliasname"]); 116 currentUser.Sex = DBNull.Value.Equals(dr["sex"]) ? "" : (Convert.ToInt32(dr["sex"]) == 0 ? "男" : "女"); 117 currentUser.OperatorGroupId = DBNull.Value.Equals(dr["groupid"]) ? "" : Convert.ToString(dr["groupid"]); 118 currentUser.OperatorGroupName = (string.IsNullOrEmpty(groupName) ? "" : groupName.Substring(0, groupName.Length - 1)); 119 #endregion 120 SessionManage.CurrentUser = currentUser; 121 //驗證通過,設置用戶權限 122 if (!SetOperatorRight(currentUser.OperatorGroupId, currentUser.OperatorId)) 123 { 124 Log.SaveLoginLog(0, "權限設置失敗"); 125 return Content("權限設置失敗!"); 126 } 127 128 Log.SaveLoginLog(1, "登陸成功"); 129 130 return Content("1"); 131 } 132 catch (Exception ex) 133 { 134 Log.SaveLoginLog(0, ex.ToString()); 135 return Content("服務器內部錯誤!"); 136 } 137 } 138 139 /// <summary> 140 /// 設置用戶權限 141 /// </summary> 142 /// <param name="operatorGroupId">用戶組ID</param> 143 /// <param name="operatorId">用戶登錄賬號</param> 144 /// <returns></returns> 145 private bool SetOperatorRight(string operatorGroupId, string operatorId) 146 { 147 try 148 { 149 //目錄列表 150 IList<Catalog> navigationList = new List<Catalog>(); 151 IList<Catalog> rightList = new List<Catalog>(); 152 153 //獲取首級導航欄信息 154 string strSql = "select distinct parentid,parentcatalogname,parentshowno from (select a.catalogid,a.parentid,b.parentid as granparendid," + 155 "a.catalogname,b.catalogname as parentcatalogname,a.showno,b.showno as parentshowno ,b.isavailable from catalog a left join " + 156 "catalog b on a.parentid=b.catalogid) as temptable where granparendid=0 and isavailable=1 and catalogid in (select categoryid from rightlist " + 157 "where operatorgroupid in (" + operatorGroupId + ")) order by parentshowno"; 158 DataSet navigationDs = SqlHelper.ExecuteQuery(ConnectionHelper.GeSqlDbConnectionStr(), strSql); 159 if (navigationDs != null && navigationDs.Tables.Count > 0 && navigationDs.Tables[0].Rows.Count > 0) 160 { 161 #region 封裝導航欄到List 162 163 foreach (DataRow row in navigationDs.Tables[0].Rows) 164 { 165 int parentId = DBNull.Value.Equals(row["parentid"]) ? 0 : Convert.ToInt32(row["parentid"]); 166 string parentName = DBNull.Value.Equals(row["parentcatalogname"]) ? "" : Convert.ToString(row["parentcatalogname"]); 167 168 var item = new Catalog 169 { 170 CatalogId = parentId, 171 ParentId = 0, 172 CatalogName = parentName 173 }; 174 navigationList.Add(item); 175 } 176 177 #endregion 178 179 #region 獲取二級欄目信息及頁面信息 180 181 //獲取二級分類信息 182 strSql = "select * from catalog where catalogid in (select categoryid from rightlist where operatorgroupid in (" + 183 operatorGroupId + ")) and isavailable=1 order by showno"; 184 DataSet catalogDs = SqlHelper.ExecuteQuery(ConnectionHelper.GeSqlDbConnectionStr(), strSql); 185 //獲取頁面信息 186 strSql = "select * from pageinfo where pageid in ( select pageid from rightlist where operatorgroupid in (" + 187 operatorGroupId + ")) and isavailable=1 order by catalogid,showno"; 188 DataSet pageDs = SqlHelper.ExecuteQuery(ConnectionHelper.GeSqlDbConnectionStr(), strSql); 189 190 //無欄目,則返回false 191 if (catalogDs == null || catalogDs.Tables.Count <= 0 || catalogDs.Tables[0].Rows.Count <= 0) 192 { 193 return false; 194 } 195 //無權限頁面,則返回false 196 if (pageDs == null || pageDs.Tables.Count <= 0 || pageDs.Tables[0].Rows.Count <= 0) 197 { 198 return false; 199 } 200 201 #endregion 202 #region 封裝用戶權限 203 204 DataTable catalogTb = catalogDs.Tables[0]; 205 DataTable pageTb = pageDs.Tables[0]; 206 207 foreach (DataRow catalogDr in catalogTb.Rows) 208 { 209 int catalogId = Convert.ToInt32(catalogDr["catalogid"]); 210 int parentId = Convert.ToInt32(catalogDr["parentid"]); 211 string catalogName = Convert.ToString(catalogDr["catalogname"]); 212 string picUrl = DBNull.Value.Equals(catalogDr["picurl"]) ? "" : Convert.ToString(catalogDr["picurl"]); 213 var catalogItem = new Catalog { CatalogId = catalogId, ParentId = parentId, CatalogName = catalogName, PictureUrl = picUrl, PageList = new List<Page>() }; 214 215 //獲取目錄下的頁面行 216 DataRow[] pageRows = pageTb.Select("catalogid=" + catalogId); 217 if (pageRows.Length > 0) 218 { 219 foreach (DataRow pageDr in pageRows) 220 { 221 int pageId = Convert.ToInt32(pageDr["pageid"]); 222 string pageName = Convert.ToString(pageDr["pagename"]); 223 string pageUrl = Convert.ToString(pageDr["pageurl"]); 224 var pageItem = new Page { PageIndex = pageId, PageName = pageName, PageUrl = pageUrl, CategoryId = catalogId }; 225 catalogItem.PageList.Add(pageItem); 226 } 227 } 228 rightList.Add(catalogItem); 229 } 230 #endregion 231 AccountInfo info = SessionManage.CurrentUser; 232 info.NavigationList = navigationList; 233 info.RightList = rightList; 234 SessionManage.CurrentUser = info; 235 return true; 236 } 237 return false; 238 } 239 catch (Exception e1) 240 { 241 Log.SaveErrorLog(e1.ToString(), "設置用戶權限出錯"); 242 return false; 243 } 244 } 245 } 246 }
1.4界面運行截圖
1.5驗證碼生成控制器
驗證碼的處理方式也是一個控制器,它對應一個視圖頁面。視圖頁面中不需要編寫代碼,只是需要視圖這個文件。供登錄模塊調用。對於視圖的生成,只需要右鍵ValidateCode,點擊添加視圖就可以了。
public ActionResult ValidateCode()
{
CreateCheckCodeImage(GenerateCheckCode());
return View();
}
驗證碼生成的控制器代碼如下:

1 using System; 2 using System.Collections.Generic; 3 using System.Drawing; 4 using System.Linq; 5 using System.Web; 6 using System.Web.Mvc; 7 8 namespace Controllers 9 { 10 /// <summary> 11 /// **************************** 12 /// 功能:驗證碼 13 /// 作者:王令 14 /// 時間:2015-7-01 15 /// 郵箱:1129137758@qq.com 16 /// **************************** 17 18 public class ValidateCodeController : Controller 19 { 20 public ActionResult ValidateCode() 21 { 22 CreateCheckCodeImage(GenerateCheckCode()); 23 return View(); 24 } 25 26 27 /// <summary> 28 /// 生成驗證碼 29 /// </summary> 30 /// <returns></returns> 31 private string GenerateCheckCode() 32 { 33 int number; 34 char code; 35 string checkCode = String.Empty; 36 System.Random random = new Random(); 37 38 bool F = true; 39 while (F) 40 { 41 number = random.Next(); 42 if (number % 2 == 0) 43 code = (char)('0' + (char)(number % 10)); 44 else 45 code = (char)('A' + (char)(number % 26)); 46 47 if (code == '0' || code == 'O' || code == '1' || code == 'I' || code == '2' || code == 'Z') 48 { 49 //排序0、O、1、L等字符 50 } 51 else 52 { 53 checkCode += code.ToString(); 54 if (checkCode.Length == 4) 55 { 56 F = false; 57 } 58 } 59 } 60 61 Session.Add("CheckCode", checkCode); 62 return checkCode; 63 } 64 65 66 67 /// <summary> 68 /// 生成驗證碼圖片 69 /// </summary> 70 /// <param name="checkCode"></param> 71 private void CreateCheckCodeImage(string checkCode) 72 { 73 if (checkCode == null || checkCode.Trim() == String.Empty) 74 return; 75 System.Drawing.Bitmap image = new System.Drawing.Bitmap((int)Math.Ceiling((checkCode.Length * 12.5)), 22); 76 Graphics g = Graphics.FromImage(image); 77 78 try 79 { 80 //生成隨機生成器 81 Random random = new Random(); 82 83 //清空圖片背景色 84 g.Clear(Color.White); 85 86 //畫圖片的背景噪音線 87 for (int i = 0; i < 25; i++) 88 { 89 int x1 = random.Next(image.Width); 90 int x2 = random.Next(image.Width); 91 int y1 = random.Next(image.Height); 92 int y2 = random.Next(image.Height); 93 g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2); 94 } 95 // 96 Font font = new System.Drawing.Font("Arial", 12, (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic)); 97 System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2f, true); 98 g.DrawString(checkCode, font, brush, 2, 2); 99 100 //畫圖片的前景噪音點 101 for (int i = 0; i < 100; i++) 102 { 103 int x = random.Next(image.Width); 104 int y = random.Next(image.Height); 105 image.SetPixel(x, y, Color.FromArgb(random.Next())); 106 } 107 108 //畫圖片的邊框線 109 g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1); 110 System.IO.MemoryStream ms = new System.IO.MemoryStream(); 111 image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif); 112 Response.ClearContent(); 113 Response.ContentType = "image/Gif"; 114 Response.BinaryWrite(ms.ToArray()); 115 } 116 117 finally 118 { 119 g.Dispose(); 120 image.Dispose(); 121 122 } 123 } 124 125 } 126 }