Web应用程序系统的多用户权限控制设计及实现-项目架构【3】
本章主要讲述Web权限管理系统的项目架构,及开发中需要的基本类和相关的CSS,JS文件。
1.1系统结构
本系统搭建开发工具为Visual Studio 2012,采用ASP.NET MVC 4.0技术开发。系统的框架图如下所示:
特别说明:系统需要用到的CSS文件在Content目录下,公有的JS文件在Scripts目录下。其下载链接为:https://files.cnblogs.com/files/wlandwl/CSS-JS.zip
系统页面前台展示主要运用EasyUI1.4.3的展示控件及其扩展控件,引用到Content目录。系统后台管理主要通过区域的方式开发,运用区域管理可以模块化的开发系统的功能,有助于中大型系统在后期的开发和维护。
1.2系统共有类
1.2.1数据表对应Model
AccountInfo.cs,主要管理账户的基本信息,及可以访问的目录信息,页面信息。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Models 7 { 8 /// <summary> 9 /// 用户信息 10 /// </summary> 11 public class AccountInfo 12 { 13 public string OperatorId { get; set; } //用户ID 14 public string OperatorName { get; set; } //用户名字 15 public string AliasName { get; set; } //别名 16 public string Sex { get; set; } //性别 17 public int IsOnStaff { get; set; } 18 public string OperatorGroupId { get; set; } //用户组ID 19 public string OperatorGroupName { get; set; } //用户组名称 20 public IList<Catalog> NavigationList { get; set; } //用户能够访问的一级导航列表 21 public IList<Catalog> RightList { get; set; } //用户权限列表 22 } 23 }
Catalog.cs,主要是用于目录结构信息管理。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System.Collections.Generic; 2 3 namespace Models 4 { 5 /// <summary> 6 /// 栏目 7 /// </summary> 8 public class Catalog 9 { 10 public int CatalogId { get; set; } 11 public int ParentId { get; set; } 12 public string CatalogName { get; set; } 13 public string PictureUrl { get; set; } 14 public string Remark { get; set; } 15 public int ShowNo { get; set; } 16 public int IsAvailable { get; set; } 17 public IList<Catalog> Childern { get; set; } 18 public IList<Page> PageList { get; set; } 19 public Catalog() 20 { 21 Childern = new List<Catalog>(); 22 PageList = new List<Page>(); 23 } 24 } 25 }
OperatorGroup.cs,主要是用于分组信息的管理。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 6 namespace Models 7 { 8 /// <summary> 9 /// 用户组 10 /// </summary> 11 public class OperatorGroup 12 { 13 public int GroupId { get; set; } 14 public string GroupName { get; set; } 15 public int OrderNum { get; set; } //排序值 16 public int ParentId { get; set; } //父节点 17 public int State { get; set; } //是否启用 18 19 } 20 }
Page.cs,主要是用于页面信息的管理。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Models 7 { 8 /// <summary> 9 /// 页面 10 /// </summary> 11 public class Page 12 { 13 public int CategoryId { get; set; } //一级分类ID 14 public string CategoryName { get; set; } //一级分类名称 15 public decimal SubcategoryId { get; set; } //二级分类ID 16 public string SubcategoryName { get; set; } //二级分类名称 17 public decimal PageIndex { get; set; } 18 public string PageName { get; set; } 19 public string PageUrl { get; set; } 20 public string ProcedureName { get; set; } //对应的存储过程的名称 21 public string ReportRdlcName { get; set; } //报表名称(对应的rdlc的名称) 22 public string Title { get; set; } //报表标题 23 public string Subtitle { get; set; } //副标题 24 public string LeftHeader { get; set; } //左侧页眉显示信息 25 public string MiddelHeader { get; set; } //中间页眉显示信息 26 public string RightHeader { get; set; } //右侧页眉显示信息 27 public string LeftFooter { get; set; } //左侧页脚显示信息 28 public string MiddleFooter { get; set; } //中间页脚显示信息 29 public string RightFooter { get; set; } //右侧页脚显示信息 30 public int ShowNum { get; set; } //显示顺序,排序值 31 public int IsAvailable { get; set; } //是否可用 32 public string Operate { get; set; } 33 } 34 }
TreeModel.cs,主要是为了生成一课权限管理树,定义的节点类。
为了生成节点信息的安全和高效,引用了DotNetOpenAuth.Messaging动态链接库,需要下载才可以加入到项目中。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Data; using System.Linq; using DotNetOpenAuth.Messaging; namespace Models { /// <summary> /// 树模型 /// </summary> public class TreeModel { public decimal id { get; set; } public string text { get; set; } public string state { get; set; } public IList<TreeModel> children { get; set; } public object attributes { get; set; } /// <summary> /// 从数据行生成树节点列表 /// </summary> /// <param name="rows">行数组</param> /// <param name="idName">id对应的数据库列</param> /// <param name="textName">text对应的数据库列</param> /// <param name="parentIdName">父节点ID对应的数据库列</param> /// <param name="needRoot">是否需要显示根节点</param> /// <param name="attributes">自定义属性</param> /// <returns></returns> public static IList<TreeModel> BuildTreeNodeList(DataRowCollection rows, string idName, string textName, string parentIdName, bool needRoot, params string[] attributes) { IList<TreeModel> tree = new List<TreeModel>(); IList<TreeModel> resultList = new List<TreeModel>(); if (rows.Count > 0) { foreach (DataRow dr in rows) { var node = new TreeModel { id = DBNull.Value.Equals(dr[idName]) ? 0 : Convert.ToDecimal(dr[idName]), text = DBNull.Value.Equals(dr[textName]) ? "" : Convert.ToString(dr[textName]), state = "open", children = new List<TreeModel>() }; int isavailable = DBNull.Value.Equals(dr["isavailable"]) ? 0 : Convert.ToInt32(dr["isavailable"]); int showno = DBNull.Value.Equals(dr["showno"]) ? 0 : Convert.ToInt32(dr["showno"]); string remark = DBNull.Value.Equals(dr["remark"]) ? "" : Convert.ToString(dr["remark"]); string picUrl = DBNull.Value.Equals(dr["picurl"]) ? "" : Convert.ToString(dr["picurl"]); node.attributes = new CatalogAttributes { isavailable = isavailable, remark = remark, showno = showno, picurl = picUrl }; decimal parentId = DBNull.Value.Equals(dr[parentIdName]) ? 0 : Convert.ToDecimal(dr[parentIdName]); bool hasFound = FoundTreeNode(resultList, node, parentId); if (!hasFound) { resultList.Add(node); } } } if (needRoot) { var rootNode = new TreeModel { id = 0, text = "栏目树", state = "open", children = new List<TreeModel>() }; rootNode.children.AddRange(resultList); tree.Add(rootNode); return tree; } return resultList; } public static IList<TreeModel> BuildTreeNodeListIncludeAll(DataRowCollection rows, string idName, string textName, string parentIdName) { IList<TreeModel> resultList = new List<TreeModel>(); var root = new TreeModel { id = 0, text = "所有栏目", state = "open", children = new List<TreeModel>() }; resultList.Add(root); if (rows.Count > 0) { foreach (DataRow dr in rows) { var node = new TreeModel { id = DBNull.Value.Equals(dr[idName]) ? 0 : Convert.ToDecimal(dr[idName]), text = DBNull.Value.Equals(dr[textName]) ? "" : Convert.ToString(dr[textName]), state = "open", children = new List<TreeModel>() }; decimal parentId = DBNull.Value.Equals(dr[parentIdName]) ? 0 : Convert.ToDecimal(dr[parentIdName]); bool hasFound = FoundTreeNode(resultList, node, parentId); if (!hasFound) { resultList.Add(node); } } } return resultList; } /// <summary> /// 在节点列表中查找父节点位置,并将新的节点插入 /// </summary> /// <param name="nodeList">原始节点列表</param> /// <param name="newNode">新节点</param> /// <param name="parentId">父节点ID</param> /// <returns></returns> public static bool FoundTreeNode(IList<TreeModel> nodeList, TreeModel newNode, decimal parentId) { bool hasFound = false; var parent = nodeList.FirstOrDefault(n => n.id == parentId); if (parent != null) { parent.children.Add(newNode); hasFound = true; } else { //在孩子节点中查找 foreach (TreeModel node in nodeList) { IList<TreeModel> children = node.children; //孩子节点 if (children != null && children.Count > 0) { hasFound = FoundTreeNode(children, newNode, parentId); if (hasFound) break; } } } return hasFound; } } public class CustomAttributes { public string url { get; set; } public string pageName { get; set; } } public class CatalogAttributes { public string remark { get; set; } //备注 public int showno { get; set; } //排序值 public int isavailable { get; set; } //状态 public string picurl { get; set; } //图标路径 } }
1.2.1数据库处理类
数据库模板类主要是把常用sql语句的增,删,改,查及事务集中起来。便于开发中通过类的实例化调用。
该类位于目录OdbcDbAcess文件夹中。文件名称:SqlHelper.cs。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Data; 6 using System.Configuration; 7 using System.Data.SqlClient; 8 9 namespace OdbcDbAccess 10 { 11 public class SqlHelper 12 { 13 /// <summary> 14 /// **************************** 15 /// 功能:数据库连接处理类 16 /// 作者:王令 17 /// 时间:2015-7-10 18 /// 邮箱:1129137758@qq.com 19 /// **************************** 20 21 private static SqlCommand CreateCommand(SqlConnection conn) 22 { 23 var comm = conn.CreateCommand(); 24 comm.CommandTimeout = 600; 25 return comm; 26 } 27 28 /// <summary> 29 /// 执行单一数据返回查询 30 /// </summary> 31 /// <typeparam name="T">返回类型</typeparam> 32 /// <param name="connName">配置文件中连接字符串的名称</param> 33 /// <param name="sql">查询语句</param> 34 /// <returns></returns> 35 public static T ExecuteScalar<T>(string connName, string sql) 36 { 37 object result = null; 38 SqlConnection conn = new SqlConnection(connName); 39 { 40 var comm = CreateCommand(conn); 41 conn.Open(); 42 comm.CommandText = sql; 43 result = comm.ExecuteScalar(); 44 conn.Close(); 45 } 46 if (result != null && result != DBNull.Value) 47 return (T)Convert.ChangeType(result, typeof(T)); 48 return default(T); 49 } 50 51 /// <summary> 52 /// 查询结果,返回多行数据【sql语句】 53 /// </summary> 54 /// <param name="sql">sql查询语句</param> 55 56 public static DataSet ExecuteQuery(string connectionString, string sql) 57 { 58 SqlConnection con = new SqlConnection(connectionString); 59 string cmdText = sql; 60 SqlDataAdapter da = new SqlDataAdapter(cmdText, con); ///创建SqlDataAdapter 61 DataSet dss = new DataSet(); 62 try 63 { 64 con.Open(); 65 da.Fill(dss, "table1"); 66 con.Close(); 67 68 } 69 catch (Exception ex) 70 { ///抛出异常 71 throw new Exception(ex.Message, ex); 72 } 73 finally 74 { ///关闭连接 75 con.Close(); 76 } 77 return dss; 78 } 79 80 /// <summary> 81 /// 执行事务操作 82 /// </summary> 83 /// <param name="sql">sql查询语句</param> 84 public static int ExecuteTran(string connectionString, string sql) 85 { 86 try 87 { 88 using (var conn = new SqlConnection(connectionString)) 89 { 90 var comm = conn.CreateCommand(); 91 conn.Open(); 92 var tran = conn.BeginTransaction(); 93 comm.Transaction = tran; 94 try 95 { 96 comm.CommandText = sql; 97 comm.ExecuteNonQuery(); 98 tran.Commit(); 99 return 1; 100 } 101 catch (Exception) 102 { 103 tran.Rollback(); 104 conn.Close(); 105 return 0; 106 throw; 107 108 } 109 } 110 } 111 catch (Exception ex) 112 { 113 throw new Exception(ex.Message, ex); 114 } 115 } 116 117 118 /// <summary> 119 /// 数据集删除,修改,添加【sql语句】 120 /// </summary> 121 /// <param name="sql">sql操作语句</param> 122 123 public static int ExecuteNonQuery(string connectionString, string sql) 124 { ///创建连接 125 SqlConnection con = new SqlConnection(connectionString); 126 ///创建SQL语句 127 string cmdText = sql; 128 ///创建SqlCommand 129 SqlCommand cmd = new SqlCommand(cmdText, con); 130 131 int result = -1; 132 try 133 { ///打开连接 134 con.Open(); 135 ///操作数据 136 result = cmd.ExecuteNonQuery(); 137 } 138 catch (Exception ex) 139 { ///抛出异常 140 throw new Exception(ex.Message, ex); 141 } 142 finally 143 { ///关闭连接 144 con.Close(); 145 } 146 147 return result; 148 149 } 150 151 /// <summary> 152 /// 查询结果,返回多行数据【存储过程】 153 /// </summary> 154 /// <param name="storage">存储过程</param> 155 156 public static DataSet ExecuteQueryWithParameter(string connectionString, string storage) 157 { 158 SqlConnection con = new SqlConnection(connectionString); 159 string cmdText = storage; 160 SqlDataAdapter da = new SqlDataAdapter(cmdText, con); ///创建SqlDataAdapter 161 ///设置执行方式为存储过程 162 da.SelectCommand.CommandType = CommandType.StoredProcedure; 163 164 165 DataSet dss = new DataSet(); 166 try 167 { 168 con.Open(); 169 da.Fill(dss, "table1"); 170 con.Close(); 171 172 } 173 catch (Exception ex) 174 { ///抛出异常 175 throw new Exception(ex.Message, ex); 176 } 177 finally 178 { ///关闭连接 179 con.Close(); 180 } 181 return dss; 182 } 183 } 184 }
读取webconfig中的数据库连接字符串封装在ConnectionHelper.cs中。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Configuration; 4 using System.Data.Odbc; 5 using System.Linq; 6 using System.Text; 7 8 namespace OdbcDbAccess 9 { 10 public class ConnectionHelper 11 { 12 public static string GeSqlDbConnectionStr() 13 { 14 return ConfigurationManager.ConnectionStrings["sqlSeverCenter"].ConnectionString; 15 } 16 17 } 18 }
1.2.2数据集转换类
数据集转换类,主要是为了把得到的数据如DataSet封装成指定的格式数据,用于与前台网页数据作特定的交互。
该类位于OdbcDbAcess文件夹中。文件名称:DataTransfor.cs。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Data; 4 using System.Text; 5 6 7 namespace OdbcDbAccess 8 { 9 /// <summary> 10 /// **************************** 11 /// 功能:数据转换类 12 /// 作者:王令 13 /// 时间:2015-7-10 14 /// 邮箱:1129137758@qq.com 15 /// **************************** 16 /// 17 public class DataTransfor 18 { 19 /// <summary> 20 /// 数据转换 21 /// </summary> 22 /// <typeparam name="T">数据类型</typeparam> 23 /// <param name="dataSet">数据集,其字段顺序必需与T的属性顺序一直</param> 24 /// <returns></returns> 25 public static IList<T> DataSetTransfor<T>(DataSet dataSet) where T : class,new() 26 { 27 IList<T> resultList = new List<T>(); //结果数据集合 28 //获取T的属性集合 29 Type tType = new T().GetType(); 30 var propertyArray = tType.GetProperties(); 31 32 if (dataSet != null && dataSet.Tables.Count > 0) 33 { 34 DataTable table = dataSet.Tables[0]; 35 foreach (DataRow dr in table.Rows) 36 { 37 T item = new T(); 38 //为属性设值 39 for (int i = 0; i < propertyArray.Length; i++) 40 { 41 if (!DBNull.Value.Equals(dr[i])) 42 { 43 var propertyInfo = propertyArray[i]; //获取属性 44 Type propertyType = propertyInfo.PropertyType; 45 object value = Convert.ChangeType(dr[i], propertyType); //将DataSet中的值转换为属性同类型的值 46 propertyInfo.SetValue(item, value, null); //为属性设置值 47 } 48 } 49 resultList.Add(item); 50 } 51 } 52 return resultList; 53 } 54 55 56 /// <summary> 57 /// 数据转换--指定部分属性 58 /// </summary> 59 /// <typeparam name="T">数据类型</typeparam> 60 /// <param name="dataSet">数据集,其字段顺序必需与T的属性propertyArray顺序一直</param> 61 /// <param name="propertyArray">指定类的属性数组</param> 62 /// <returns></returns> 63 public static IList<T> DataSetTransfor<T>(DataSet dataSet, string[] propertyArray) where T : class,new() 64 { 65 IList<T> resultList = new List<T>(); //结果数据集合 66 67 //获取T的数据类型 68 Type tType = new T().GetType(); 69 70 if (dataSet != null && dataSet.Tables.Count > 0) 71 { 72 DataTable table = dataSet.Tables[0]; 73 foreach (DataRow dr in table.Rows) 74 { 75 var item = new T(); 76 //为属性设值 77 for (int i = 0; i < propertyArray.Length; i++) 78 { 79 var propertyInfo = tType.GetProperty(propertyArray[i]); //获取属性 80 81 if (!DBNull.Value.Equals(dr[i])) 82 { 83 string propertyTypeName = propertyInfo.PropertyType.FullName.Trim(); 84 object value; 85 switch (propertyTypeName) 86 { 87 case "System.DateTime": 88 value = Convert.ToDateTime(dr[i]); 89 break; 90 case "System.Decimal": 91 value = Convert.ToDecimal(dr[i]); 92 break; 93 case "System.Double": 94 value = Convert.ToDouble(dr[i]); 95 break; 96 case "System.Int32": 97 value = Convert.ToInt32(dr[i]); 98 break; 99 default: 100 value = Convert.ToString(dr[i]); 101 break; 102 } 103 propertyInfo.SetValue(item, value, null); //为属性设置值 104 } 105 106 } 107 resultList.Add(item); 108 } 109 } 110 return resultList; 111 } 112 113 114 /// <summary> 115 /// 数据转换--指定部分属性 116 /// </summary> 117 /// <typeparam name="T">数据类型</typeparam> 118 /// <param name="dataSet">数据集,其字段顺序必需与T的属性propertyArray顺序一直</param> 119 /// <param name="columnIndexArray">DataSet中的字段对应的下表数组,其长度和PropertyArray相同</param> 120 /// <param name="propertyArray">指定类的属性数组</param> 121 /// <returns></returns> 122 public static IList<T> DataSetTransfor<T>(DataSet dataSet, int[] columnIndexArray, string[] propertyArray) where T : class,new() 123 { 124 IList<T> resultList = new List<T>(); //结果数据集合 125 126 //获取T的数据类型 127 Type tType = new T().GetType(); 128 129 if (dataSet != null && dataSet.Tables.Count > 0) 130 { 131 if (columnIndexArray != null && propertyArray != null && columnIndexArray.Length == propertyArray.Length) 132 { 133 DataTable table = dataSet.Tables[0]; 134 foreach (DataRow dr in table.Rows) 135 { 136 var item = new T(); 137 for (int i = 0; i < columnIndexArray.Length; i++) 138 { 139 int index = columnIndexArray[i]; 140 if (!DBNull.Value.Equals(dr[index])) 141 { 142 //为属性设值 143 var propertyInfo = tType.GetProperty(propertyArray[i]); //获取属性 144 object value = Convert.ChangeType(dr[index], propertyInfo.PropertyType); //将DataSet中的值转换为属性同类型的值 145 propertyInfo.SetValue(item, value, null); //为属性设置值 146 } 147 } 148 resultList.Add(item); 149 } 150 } 151 } 152 return resultList; 153 } 154 155 156 /// <summary> 157 /// 将List中的数据,封装为Combobox的Html 158 /// </summary> 159 /// <typeparam name="T">数据类型</typeparam> 160 /// <param name="dataList">数据列表</param> 161 /// <param name="valueProperty">value绑定的属性名称,多个用“,”分隔</param> 162 /// <param name="textProperty">text绑定的属性名称</param> 163 /// <param name="containAll">是否包含"全部"选项</param> 164 /// <returns></returns> 165 public static string ListToComboboxHtml<T>(IList<T> dataList, string valueProperty, string textProperty, bool containAll) where T : class, new() 166 { 167 var htmlStr = new StringBuilder(); 168 169 if (dataList != null && dataList.Count > 0) 170 { 171 if (containAll && dataList.Count > 1) 172 { 173 htmlStr.Append("<option value=\"-1\">全部</option>"); 174 } 175 176 string[] valuePropertyArray = valueProperty.Split(','); 177 178 //获取T的数据类型 179 Type tType = new T().GetType(); 180 foreach (T item in dataList) 181 { 182 var textPropertyInfo = tType.GetProperty(textProperty); //获取Text属性 183 184 htmlStr.Append("<option value=\""); 185 for (int i = 0; i < valuePropertyArray.Length; i++) 186 { 187 string s = valuePropertyArray[i]; 188 var valuePropertyInfo = tType.GetProperty(s); //获取Value属性 189 htmlStr.Append(valuePropertyInfo.GetValue(item, null)); 190 if (i != valuePropertyArray.Length - 1) 191 { 192 htmlStr.Append("_"); 193 } 194 } 195 196 htmlStr.Append("\">"); 197 htmlStr.Append(textPropertyInfo.GetValue(item, null)); 198 htmlStr.Append("</option>"); 199 } 200 } 201 return htmlStr.ToString(); 202 } 203 /// <summary> 204 /// 将List中的数据,封装为datagrid body的Html 205 /// </summary> 206 /// <typeparam name="T">数据类型</typeparam> 207 /// <param name="dataList">数据列表</param> 208 /// <param name="propertyArray">属性数组,其顺序和前台显示顺序一致</param> 209 /// <returns></returns> 210 public static string ListToTableHtml<T>(IList<T> dataList, string[] propertyArray) 211 where T : class, new() 212 { 213 var htmlStr = new StringBuilder(); 214 215 if (dataList != null && dataList.Count > 0) 216 { 217 //获取T的数据类型 218 Type tType = new T().GetType(); 219 foreach (T item in dataList) 220 { 221 htmlStr.Append("<tr>"); 222 for (int i = 0; i < propertyArray.Length; i++) 223 { 224 htmlStr.Append("<td>"); 225 htmlStr.Append(tType.GetProperty(propertyArray[i]).GetValue(item, null)); 226 htmlStr.Append("</td>"); 227 } 228 htmlStr.Append("</tr>"); 229 } 230 } 231 return htmlStr.ToString(); 232 } 233 /// <summary> 234 /// 数据转换-2015-4-17添加 235 /// </summary> 236 /// <typeparam name="T">数据类型</typeparam> 237 /// <param name="dataSet">数据集,所有数据转换为string</param> 238 public static IList<T> DataSetTransforString<T>(DataSet dataSet) where T : class,new() 239 { 240 IList<T> resultList = new List<T>(); //结果数据集合 241 242 //获取T的属性集合 243 Type tType = new T().GetType(); 244 var propertyArray = tType.GetProperties(); 245 246 if (dataSet != null && dataSet.Tables.Count > 0) 247 { 248 DataTable table = dataSet.Tables[0]; 249 var temp = dataSet.Tables[0].Columns.Count; 250 foreach (DataRow dr in table.Rows) 251 { 252 T item = new T(); 253 //为属性设值 254 for (int i = 0; i < temp; i++) 255 { 256 var propertyInfo = propertyArray[i]; //获取属性 257 Type propertyType = propertyInfo.PropertyType; 258 object value = DBNull.Value.Equals(dr[i]) ? "" : dr[i].ToString(); //将DataSet中的值转换为属性同类型的值 259 propertyInfo.SetValue(item, value, null); //为属性设置值 260 } 261 resultList.Add(item); 262 } 263 } 264 return resultList; 265 } 266 267 268 269 270 271 } 272 }
1.2.3会话管理类
会话管理类是权限管理系统的核心类,它主要是根据登录者的id和密码获取相应信息,同时把登录者可以点击的目录,访问的网页存在session中。供系统自动配置出用户的可访问信息。
该类位于BaseBag文件夹中。文件名称:SessionManage.cs。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 using Models; 7 using OdbcDbAccess; 8 using System.Data; 9 using LogInfo; 10 11 namespace Session 12 { 13 /// <summary> 14 /// **************************** 15 /// 功能:会话管理类 16 /// 作者:王令 17 /// 时间:2015-7-18 18 /// 邮箱:1129137758@qq.com 19 /// **************************** 20 21 public class SessionManage 22 { 23 24 /// <summary> 25 /// Web虚拟目录路径 26 /// </summary> 27 public static string AppPath 28 { 29 get 30 { 31 return HttpContext.Current.Request.ApplicationPath; 32 } 33 } 34 35 36 /// <summary> 37 /// 当前访问的Web域名 38 /// </summary> 39 public static string WebRoot 40 { 41 get 42 { 43 string url = HttpContext.Current.Request.Url.AbsoluteUri; 44 url = url.Remove(0, 7); 45 url = "http://" + url.Substring(0, url.IndexOf('/')) + AppPath; 46 return url.ToLower(); 47 } 48 } 49 50 51 /// <summary> 52 /// 用户认证信息KEY 53 /// </summary> 54 private const string UserInfoKey = "USER_INFO_KEY"; 55 56 57 /// <summary> 58 /// 当前登陆用户信息 59 /// </summary> 60 public static AccountInfo CurrentUser 61 { 62 get 63 { 64 if (HttpContext.Current.Session[UserInfoKey] == null) 65 return null; 66 67 return (AccountInfo)HttpContext.Current.Session[UserInfoKey]; 68 } 69 set { HttpContext.Current.Session[UserInfoKey] = value; } 70 } 71 72 73 /// <summary> 74 /// 用户权限验证 75 /// </summary> 76 /// <returns></returns> 77 public static bool CheckRight() 78 { 79 try 80 { 81 if (CurrentUser == null) 82 { 83 //当前用户信息是否为空,为空,验证失败 84 return false; 85 } 86 else 87 { 88 string fUrl = HttpContext.Current.Request.Url.AbsoluteUri.Trim(); //用户当前请求的地址 89 if (fUrl.EndsWith("/")) 90 { 91 fUrl = fUrl.Substring(0, fUrl.Length - 1); 92 } 93 else 94 { 95 if (fUrl.Contains("?")) 96 { 97 fUrl = fUrl.Substring(0, fUrl.LastIndexOf("?", System.StringComparison.Ordinal)); 98 } 99 } 100 fUrl = fUrl.Substring(0, fUrl.LastIndexOf("/", System.StringComparison.Ordinal) + 1);//只取到控制器名称,具体的ActionName不在考虑,因为不同的Action都会形成不同的URL 101 fUrl = fUrl.Trim('/'); 102 string[] url = fUrl.Split('/'); 103 string righturl = ""; 104 for (int i = 3; i < url.Length; i++) 105 { 106 righturl += url[i] + "/"; 107 } 108 string strSql = "select PageUrl from pageinfo,rightlist where pageinfo.PageUrl like '" + righturl + "%' and pageinfo.pageid=rightlist.pageid and operatorgroupid='" + CurrentUser.OperatorGroupId + "' "; 109 110 DataSet dataSet = SqlHelper.ExecuteQuery(ConnectionHelper.GeSqlDbConnectionStr(), strSql); 111 if (dataSet != null && dataSet.Tables.Count > 0 && dataSet.Tables[0].Rows.Count > 0) 112 { 113 return true; 114 } 115 else 116 { 117 return false; 118 } 119 } 120 } 121 catch (Exception ex) 122 { 123 Log.SaveErrorLog(ex.ToString(), "用户权限判断出错!"); 124 return false; 125 } 126 } 127 128 129 } 130 131 }
1.2.4页面权限检测控制器
页面权限检测控制器主要是每访问一个页面信息时,校验该用户是否具有访问该页面的权限。定义为BaseControl.cs控制器,其他的控制器均继承该控制器。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using Session; 3 using OdbcDbAccess; 4 using System.Data; 5 using Models; 6 using System.Web; 7 using System.Web.Mvc; 8 using System.Collections.Generic; 9 using System.Configuration; 10 using System.IO; 11 using System.Web.Caching; 12 13 namespace Controllers 14 { 15 /// <summary> 16 /// **************************** 17 /// 功能:页面权限检测 18 /// 作者:王令 19 /// 时间:2015-7-15 20 /// 邮箱:1129137758@qq.com 21 /// **************************** 22 23 public class BaseController : Controller 24 { 25 /// <summary> 26 /// sql sever连接字符串 27 /// </summary> 28 protected static string SqlSeverConnectionName = ConfigurationManager.ConnectionStrings["sqlSeverCenter"].ConnectionString; 29 30 /// <summary> 31 /// 控制器初始化,判断用户权限以及登陆是否过期 32 /// </summary> 33 /// <param name="requestContext"></param> 34 protected override void Initialize(System.Web.Routing.RequestContext requestContext) 35 { 36 base.Initialize(requestContext); 37 if (!SessionManage.CheckRight()) 38 { 39 Response.Write("<script> window.parent.location.href = '/Login/Login';</script>"); 40 } 41 } 42 43 } 44 }
1.3系统模板页
由于登录到首页后,其他页面均是在生成的iframe标签中展示,这些页面都需要引用一些相同的CSS文件,JS文件,为了网页的统一管理,开发了一个共享页面,作为其他页面的模板页。
模板页位于Views/Shared目录中,文件名称为:_BaseLayout.cshtml。引用它的页面通过 @RenderBody()的方式即可把html代码渲染在网页中。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta name="viewport" content="width=device-width" /> 5 <link type="text/css" rel="stylesheet" href="~/Content/easyui143/themes/gray/easyui.css" /> 6 <link type="text/css" rel="stylesheet" href="~/Content/easyui143/themes/icon.css" /> 7 <link type="text/css" rel="stylesheet" href="~/Content/easyui143/themes/color.css" /> 8 <style type="text/css"> 9 .panel-title { 10 text-align: center; 11 } 12 13 .datagrid-header-inner { 14 width: 100%; 15 } 16 17 .datagrid-htable, .datagrid-btable, .datagrid-ftable { 18 width: 100%; 19 } 20 </style> 21 22 <style type="text/css"> 23 .panel-title { 24 text-align: center; 25 } 26 27 .panel-title { 28 line-height: 22px; 29 letter-spacing: 1px; 30 } 31 32 33 .datagrid-header-inner { 34 width: 100%; 35 } 36 37 .datagrid-htable, .datagrid-btable, .datagrid-ftable { 38 width: 100%; 39 } 40 41 span.datagrid-row-expander.datagrid-row-expand { 42 display: block !important; 43 } 44 45 span.datagrid-row-expander.datagrid-row-collapse { 46 display: block !important; 47 } 48 49 div[id^='ddv-'] table { 50 font-size: smaller; 51 border-right: 1px groove rgba(248, 243, 243, 0.27); 52 border-bottom: 1px groove rgba(248, 243, 243, 0.27); 53 width: 1000px; 54 margin-bottom: 20px; 55 } 56 57 div[id^='ddv-'] table td, div[id^='ddv-'] table th { 58 line-height: 20px; 59 border-left: 1px groove rgba(248, 243, 243, 0.27); 60 border-top: 1px groove rgba(248, 243, 243, 0.27); 61 border-bottom: none; 62 border-right: none; 63 64 padding-left: 10px; 65 color: #808080; 66 font-weight: 100; 67 } 68 69 div[id^='ddv-'] .easyui-tabs .tabtitle { 70 color: lightblue; 71 } 72 </style> 73 @RenderSection("style", required: false) 74 <title>@ViewBag.Title</title> 75 </head> 76 77 <body> 78 <div style="margin: 10px 0 10px 10px; font-weight: bold; font-size: 14px; font-family: 宋体,Arial,Helvetica,sans-serif" id="titleDiv"> 79 <input type="hidden" value="true" id="firstLoadFlag" /> 80 </div> 81 82 @RenderBody() 83 84 <script src="@Url.Content("~/Scripts/jquery-1.7.1.js")"></script> 85 <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")"></script> 86 <script src="@Url.Content("~/Scripts/jquery.validate.js")"></script> 87 <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")"></script> 88 <script type="text/javascript" src="@Url.Content("~/Content/easyui143/jquery.easyui.min.js")"></script> 89 <script type="text/javascript" src="@Url.Content("~/Content/easyui143/locale/easyui-lang-zh_CN.js")"></script> 90 <script src="@Url.Content("~/Scripts/CustomJs/common.js")"></script> 91 <script src="@Url.Content("~/Content/easyui143/datagrid-detailview.js")" type="text/javascript"></script> 92 @RenderSection("scripts", required: false) 93 94 </body> 95 96 </html>
总结:本章主要介绍了项目的基本架构,常用的基本信息类。通过前前三章的介绍,已经完成了项目开发的前期准备工作,第四章开始,就以模块化的方式讲述每个模块的开发流程。
喜欢请赞赏一下啦^_^
微信赞赏
支付宝赞赏