PageRenderTime 43ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/Src/NewLife.CommonEntity/Web/WebPageBase.cs

#
C# | 433 lines | 208 code | 59 blank | 166 comment | 32 complexity | 8f82c8bbd89abf8248752fc37705bd17 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Security.Principal;
  5. using System.Threading;
  6. using System.Web;
  7. using System.Web.UI;
  8. using System.Web.UI.WebControls;
  9. using NewLife.Log;
  10. using NewLife.Security;
  11. using XCode.DataAccessLayer;
  12. using NewLife.Configuration;
  13. namespace NewLife.CommonEntity.Web
  14. {
  15. ///// <summary>
  16. ///// 页面基类
  17. ///// </summary>
  18. //public class WebPageBase : WebPageBase<Administrator, Menu> { }
  19. /// <summary>
  20. /// 指定具体管理员类和菜单类的页面基类
  21. /// </summary>
  22. /// <typeparam name="TAdminEntity"></typeparam>
  23. /// <typeparam name="TMenuEntity"></typeparam>
  24. public class WebPageBase<TAdminEntity, TMenuEntity> : WebPageBase<TAdminEntity>
  25. where TAdminEntity : Administrator<TAdminEntity>, new()
  26. where TMenuEntity : Menu<TMenuEntity>, new()
  27. {
  28. //#region 菜单
  29. ///// <summary>
  30. ///// 导航 分为三级:栏目-子栏目-页面
  31. ///// </summary>
  32. //public virtual String Navigation
  33. //{
  34. // get
  35. // {
  36. // if (MyMenu == null) return null;
  37. // // 无限路径
  38. // EntityList<TMenuEntity> list = MyMenu.GetFullPath(true);
  39. // //StringBuilder sb = new StringBuilder();
  40. // //foreach (TMenuEntity item in list)
  41. // //{
  42. // // if (sb.Length > 0) sb.Append(" - ");
  43. // // sb.AppendFormat("[{0}]", item.Name);
  44. // //}
  45. // //return sb.ToString();
  46. // return MyMenu.GetFullPath(true, " - ", delegate(TMenuEntity item)
  47. // {
  48. // return String.Format("[{0}]", item.Name);
  49. // });
  50. // }
  51. //}
  52. //private List<String> hasLoaded = new List<String>();
  53. //private TMenuEntity _MyMenu;
  54. ///// <summary>本页菜单</summary>
  55. //public virtual TMenuEntity MyMenu
  56. //{
  57. // get
  58. // {
  59. // if (_MyMenu == null && !hasLoaded.Contains("MyMenu"))
  60. // {
  61. // _MyMenu = Menu<TMenuEntity>.FindForPerssion(PermissionName);
  62. // if (_MyMenu == null) _MyMenu = Menu<TMenuEntity>.Current;
  63. // hasLoaded.Add("MyMenu");
  64. // }
  65. // return _MyMenu;
  66. // }
  67. // set { _MyMenu = value; }
  68. //}
  69. //#endregion
  70. //#region 权限控制
  71. ///// <summary>
  72. ///// 申请指定操作的权限
  73. ///// </summary>
  74. ///// <param name="flag"></param>
  75. ///// <returns></returns>
  76. //public override Boolean Acquire(PermissionFlags flag)
  77. //{
  78. // if (MyMenu == null) return base.Acquire(flag);
  79. // // 当前管理员
  80. // IAdministrator entity = Current;
  81. // if (entity == null) return false;
  82. // return entity.Acquire(MyMenu.ID, flag);
  83. //}
  84. //#endregion
  85. }
  86. /// <summary>
  87. /// 指定具体管理员类的页面基类
  88. /// </summary>
  89. /// <typeparam name="TAdminEntity"></typeparam>
  90. public class WebPageBase<TAdminEntity> : WebPageBase
  91. where TAdminEntity : Administrator<TAdminEntity>, new()
  92. {
  93. /// <summary>
  94. /// 当前管理员
  95. /// </summary>
  96. public override IAdministrator Current
  97. {
  98. get
  99. {
  100. return Administrator<TAdminEntity>.Current;
  101. }
  102. }
  103. }
  104. /// <summary>
  105. /// 页面基类
  106. /// </summary>
  107. public class WebPageBase : System.Web.UI.Page
  108. {
  109. #region 菜单
  110. /// <summary>
  111. /// 导航 分为三级:栏目-子栏目-页面
  112. /// </summary>
  113. public virtual String Navigation
  114. {
  115. get
  116. {
  117. if (MyMenu == null) return null;
  118. // 无限路径
  119. //EntityList<TMenuEntity> list = MyMenu.GetFullPath(true);
  120. //StringBuilder sb = new StringBuilder();
  121. //foreach (TMenuEntity item in list)
  122. //{
  123. // if (sb.Length > 0) sb.Append(" - ");
  124. // sb.AppendFormat("[{0}]", item.Name);
  125. //}
  126. //return sb.ToString();
  127. return MyMenu.GetFullPath(true, " - ", delegate(IMenu item)
  128. {
  129. return String.Format("[{0}]", item.Name);
  130. });
  131. }
  132. }
  133. private List<String> hasLoaded = new List<String>();
  134. private IMenu _MyMenu;
  135. /// <summary>本页菜单</summary>
  136. public virtual IMenu MyMenu
  137. {
  138. get
  139. {
  140. if (_MyMenu == null && !hasLoaded.Contains("MyMenu"))
  141. {
  142. //_MyMenu = Menu<TMenuEntity>.FindForPerssion(PermissionName);
  143. //_MyMenu = EntityShip.Invoke<IMenu>("FindForPerssion", PermissionName) as IMenu;
  144. _MyMenu = Current.FindPermissionMenu(PermissionName);
  145. //if (_MyMenu == null) _MyMenu = Menu.CurrentMenu;
  146. hasLoaded.Add("MyMenu");
  147. }
  148. return _MyMenu;
  149. }
  150. set { _MyMenu = value; }
  151. }
  152. #endregion
  153. #region 权限控制
  154. private Boolean _ValidatePermission = true;
  155. /// <summary>是否检查权限</summary>
  156. [Obsolete("后续版本将不再支持该属性,请重写CheckPermission来判断是否验证授权!")]
  157. public virtual Boolean ValidatePermission
  158. {
  159. get { return _ValidatePermission; }
  160. set { _ValidatePermission = value; }
  161. }
  162. /// <summary>
  163. /// 权限名。默认是页面标题
  164. /// </summary>
  165. public virtual String PermissionName
  166. {
  167. get
  168. {
  169. // 默认使用标题
  170. if (!String.IsNullOrEmpty(Title)) return Title;
  171. // 计算 目录/文件 的形式
  172. String p = Request.PhysicalPath;
  173. String dirName = new DirectoryInfo(Path.GetDirectoryName(p)).Name;
  174. String fileName = Path.GetFileNameWithoutExtension(p);
  175. return String.Format(@"{0}/{1}", dirName, fileName);
  176. }
  177. }
  178. /// <summary>
  179. /// 检查是否已登录
  180. /// </summary>
  181. /// <returns></returns>
  182. public virtual Boolean CheckLogin()
  183. {
  184. // 当前管理员
  185. IAdministrator entity = Current;
  186. if (entity == null) return false;
  187. return true;
  188. }
  189. /// <summary>
  190. /// 检查权限,实际上就是Acquire(PermissionFlags.None)
  191. /// </summary>
  192. /// <returns></returns>
  193. public virtual Boolean CheckPermission()
  194. {
  195. return Acquire(PermissionFlags.None);
  196. }
  197. /// <summary>
  198. /// 申请指定操作的权限
  199. /// </summary>
  200. /// <param name="flag"></param>
  201. /// <returns></returns>
  202. public virtual Boolean Acquire(PermissionFlags flag)
  203. {
  204. // 当前管理员
  205. IAdministrator admin = Current;
  206. if (admin == null) return false;
  207. IMenu menu = MyMenu;
  208. //if (menu == null)
  209. //{
  210. // String name = PermissionName;
  211. // if (String.IsNullOrEmpty(name)) return false;
  212. // // 当前权限菜单
  213. // menu = admin.FindPermissionMenu(name);
  214. //}
  215. if (menu == null) return false;
  216. return admin.Acquire(menu.ID, flag);
  217. }
  218. #endregion
  219. #region 登录用户控制
  220. ///// <summary>
  221. ///// Http状态,名称必须和管理员类中一致
  222. ///// </summary>
  223. //static HttpState<IAdministrator> http = new HttpState<IAdministrator>("Admin");
  224. /// <summary>
  225. /// 当前管理员
  226. /// </summary>
  227. public virtual IAdministrator Current
  228. {
  229. get
  230. {
  231. //return http == null ? null : http.Current;
  232. //return (IAdministrator)Thread.CurrentPrincipal;
  233. return Administrator.CurrentAdministrator;
  234. }
  235. }
  236. /// <summary>
  237. /// 已重载。
  238. /// </summary>
  239. /// <param name="e"></param>
  240. protected override void OnPreLoad(EventArgs e)
  241. {
  242. Thread.CurrentPrincipal = (IPrincipal)Current;
  243. //Thread.CurrentPrincipal = (IPrincipal)http.Current;
  244. Unload += new EventHandler(WebPageBase_Unload);
  245. base.OnPreLoad(e);
  246. try
  247. {
  248. if (!CheckLogin())
  249. {
  250. Response.StatusCode = 403;
  251. Response.StatusDescription = "没有登录!";
  252. Response.Write("没有登录!");
  253. Response.End();
  254. }
  255. else if (!CheckPermission())
  256. {
  257. Response.StatusCode = 403;
  258. Response.SubStatusCode = 15;
  259. Response.StatusDescription = "没有权限访问该页!";
  260. Response.Write("没有权限访问该页!");
  261. Response.End();
  262. }
  263. }
  264. catch (ThreadAbortException) { }
  265. catch (Exception ex)
  266. {
  267. XTrace.WriteLine(ex.ToString());
  268. }
  269. }
  270. void WebPageBase_Unload(object sender, EventArgs e)
  271. {
  272. Thread.CurrentPrincipal = null;
  273. }
  274. #endregion
  275. #region 运行时输出
  276. private Int32 StartQueryTimes = DAL.QueryTimes;
  277. private Int32 StartExecuteTimes = DAL.ExecuteTimes;
  278. /// <summary>
  279. /// 是否输出执行时间
  280. /// </summary>
  281. [Obsolete("后续版本将不再支持该属性,请重写CheckPermission来判断是否验证授权!")]
  282. protected virtual Boolean IsWriteRunTime
  283. {
  284. get
  285. {
  286. if (!Request.PhysicalPath.EndsWith(".aspx", StringComparison.Ordinal)) return false;
  287. return XTrace.Debug;
  288. }
  289. }
  290. /// <summary>
  291. /// 执行时间字符串
  292. /// </summary>
  293. [Obsolete("后续版本将不再支持该属性,请重写CheckPermission来判断是否验证授权!")]
  294. protected virtual String RunTimeString { get { return "查询{0}次,执行{1}次,耗时{2}毫秒!"; } }
  295. /// <summary>
  296. ///
  297. /// </summary>
  298. /// <param name="writer"></param>
  299. protected override void Render(HtmlTextWriter writer)
  300. {
  301. Literal lt = FindControl("RunTime") as Literal;
  302. if (lt != null) WriteRunTime();
  303. base.Render(writer);
  304. if (lt == null) WriteRunTime();
  305. }
  306. /// <summary>
  307. /// 输出运行时间
  308. /// </summary>
  309. protected virtual void WriteRunTime()
  310. {
  311. if (!Request.PhysicalPath.EndsWith(".aspx", StringComparison.Ordinal)) return;
  312. if (!XTrace.Debug) return;
  313. //判断是否为Ajax 异步请求,以排除“Sys.WebForms.PageRequestManagerParserErrorException: 未能分析从服务器收到的消息 ”异常
  314. if (Request.Headers["X-MicrosoftAjax"] != null || Request.Headers["x-requested-with"] != null) return;
  315. TimeSpan ts = DateTime.Now - HttpContext.Current.Timestamp;
  316. String str = String.Format("查询{0}次,执行{1}次,耗时{2}毫秒!", DAL.QueryTimes - StartQueryTimes, DAL.ExecuteTimes - StartExecuteTimes, ts.TotalMilliseconds);
  317. Literal lt = FindControl("RunTime") as Literal;
  318. if (lt != null)
  319. lt.Text = str;
  320. else
  321. Response.Write(str);
  322. }
  323. #endregion
  324. #region 压缩ViewState
  325. /// <summary>
  326. /// 设定序列化后的字符串长度为多少后启用压缩
  327. /// </summary>
  328. private static Int32 LimitLength = 1096;
  329. /// <summary>
  330. /// 是否压缩ViewState
  331. /// </summary>
  332. protected virtual Boolean CompressViewState { get { return Config.GetConfig<Boolean>("NewLife.CommonEntity.CompressViewState", true); } }
  333. /// <summary>
  334. /// 重写保存页的所有视图状态信息
  335. /// </summary>
  336. /// <param name="state">要在其中存储视图状态信息的对象</param>
  337. protected override void SavePageStateToPersistenceMedium(Object state)
  338. {
  339. if (!CompressViewState)
  340. {
  341. base.SavePageStateToPersistenceMedium(state);
  342. return;
  343. }
  344. MemoryStream ms = new MemoryStream();
  345. new LosFormatter().Serialize(ms, state);
  346. String vs = null;
  347. //判断序列化对象的字符串长度是否超出定义的长度界限
  348. if (ms.Length > LimitLength)
  349. vs = "1$" + Convert.ToBase64String(DataHelper.Compress(ms.ToArray()));
  350. else
  351. vs = Convert.ToBase64String(ms.ToArray());
  352. //注册在页面储存ViewState状态的隐藏文本框,并将内容写入这个文本框
  353. ClientScript.RegisterHiddenField("__VSTATE", vs);
  354. }
  355. /// <summary>
  356. /// 重写将所有保存的视图状态信息加载到页面对象
  357. /// </summary>
  358. /// <returns>保存的视图状态</returns>
  359. protected override Object LoadPageStateFromPersistenceMedium()
  360. {
  361. if (!CompressViewState) return base.LoadPageStateFromPersistenceMedium();
  362. //使用Request方法获取序列化的ViewState字符串
  363. String vs = Request.Form.Get("__VSTATE");
  364. Byte[] bts = null;
  365. if (vs.StartsWith("1$"))
  366. bts = DataHelper.Decompress(Convert.FromBase64String(vs.Substring(2)));
  367. else
  368. bts = Convert.FromBase64String(vs);
  369. //将指定的视图状态值转换为有限对象序列化 (LOS) 格式化的对象
  370. return new LosFormatter().Deserialize(new MemoryStream(bts));
  371. }
  372. #endregion
  373. }
  374. }