从零开始编写自己的C#框架(17)——Web层后端首页
后端首页是管理员登陆后进入的第一个页面,主要是显示当前登陆用户信息、在线人数、菜单树列表、相关功能按键和系统介绍。让管理员能更方便的找到息想要的内容。
根据不同系统的需要,首页会显示不同的内容,比如显示公司公告、公司新闻、内部短消息、个人事务、各种业务提醒......等各种内容,这些大家可以需要去进行呈现。
先上代码
Main.aspx
- <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Main.aspx.cs" Inherits="Solution.Web.Managers.Main" %>
- <!DOCTYPE html>
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head id="Head2" runat="server">
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>从零开始编写自己的C#框架——后端管理系统</title>
- <style type="text/css">
- body.f-theme-neptune .header
- {
- background-color: #;
- border-bottom: 1px solid #1E95EC;
- }
- body.f-theme-neptune .header .x-panel-body
- {
- background-color: transparent;
- }
- body.f-theme-neptune .header .title a
- {
- font-weight: bold;
- font-size: 24px;
- text-decoration: none;
- line-height: 50px;
- margin-left: 10px;
- }
- .label
- {
- color: #80ACCC;
- }
- .content
- {
- color: #fff;
- }
- </style>
- </head>
- <body>
- <form id="form1" runat="server">
- <f:PageManager ID="PageManager1" AutoSizePanelID="regionPanel" runat="server" />
- <f:Timer ID="Timer1" Interval="" Enabled="false" OnTick="Timer1_Tick" runat="server">
- </f:Timer>
- <f:RegionPanel ID="regionPanel" ShowBorder="false" runat="server">
- <Regions>
- <f:Region ID="regionTop" ShowBorder="false" ShowHeader="false" Position="Top" Layout="Fit"
- runat="server">
- <Toolbars>
- <f:Toolbar ID="Toolbar1" Position="Bottom" runat="server" CssClass="topbar content"
- CssStyle="border-bottom: 1px solid #1E95EC;background-color: #005999;">
- <Items>
- <f:ToolbarText Text="欢迎您:" runat="server" CssClass="label">
- </f:ToolbarText>
- <f:ToolbarText ID="txtUser" runat="server" CssClass="content">
- </f:ToolbarText>
- <f:ToolbarText Text="部门:" runat="server" CssClass="label">
- </f:ToolbarText>
- <f:ToolbarText ID="txtBranchName" runat="server" CssClass="content">
- </f:ToolbarText>
- <f:ToolbarText Text="职位:" runat="server" CssClass="label">
- </f:ToolbarText>
- <f:ToolbarText ID="txtPositionInfoName" runat="server" CssClass="content">
- </f:ToolbarText>
- <f:ToolbarText Text="在线人数:" runat="server" CssClass="label">
- </f:ToolbarText>
- <f:ToolbarText ID="txtOnlineUserCount" runat="server" CssClass="content">
- </f:ToolbarText>
- <f:ToolbarFill runat="server" />
- <f:Button ID="btnClearCache" runat="server" Icon="controlblank" Text="清除后端缓存" OnClick="btnClearCache_Click"
- EnablePostBack="false" CssStyle="background-color: transparent;background-image: none !important;border-width: 0 !important;">
- </f:Button>
- <f:Button ID="btnCalendar" runat="server" Icon="Calendar" Text="万年历" EnablePostBack="false"
- CssStyle="background-color: transparent;background-image: none !important;border-width: 0 !important;">
- </f:Button>
- <f:Button ID="btnHelp" EnablePostBack="false" Icon="Help" Text="帮助" runat="server"
- CssStyle="background-color: transparent;background-image: none !important;border-width: 0 !important;">
- </f:Button>
- <f:Button ID="btnExit" runat="server" Icon="UserRed" Text="安全退出" ConfirmText="确定退出系统?"
- OnClick="btnExit_Click" CssStyle="background-color: transparent;background-image: none !important;border-width: 0 !important;">
- </f:Button>
- </Items>
- </f:Toolbar>
- </Toolbars>
- </f:Region>
- <f:Region ID="Region2" Split="true" Width="200px" ShowHeader="true" Title="菜单" EnableCollapse="true"
- Layout="Fit" Position="Left" runat="server">
- <Items>
- <f:Tree runat="server" ShowBorder="false" ShowHeader="false" EnableArrows="true"
- EnableLines="true" ID="leftMenuTree">
- </f:Tree>
- </Items>
- </f:Region>
- <f:Region ID="mainRegion" ShowHeader="false" Layout="Fit" Position="Center" runat="server">
- <Items>
- <f:TabStrip ID="mainTabStrip" EnableTabCloseMenu="true" ShowBorder="false" runat="server">
- <Tabs>
- <f:Tab ID="Tab1" Title="首页" Layout="Fit" Icon="House" runat="server">
- <Items>
- <f:ContentPanel ID="ContentPanel2" ShowBorder="false" BodyPadding="10px" ShowHeader="false"
- AutoScroll="true" runat="server">
- <h2>
- 从零开始编写自己的C#框架</h2>
- 本框架由AllEmpty原创并发布于博客园,采用Apache License v2.0软件授权许可,欢迎大家试用。大家在使用时,请在软件源码中保留本人的相关版权信息,谢谢。
- <br />
- 发表本框架源码,主要是为了和大家共同学习共同进步,如果你支持本系列文章的继续发表或有更好的建议,请对相关文章回复你的看法与点击推荐,有兴趣的朋友还可以加加Q群:
- ,大家一起探讨。
- <br />
- 更多内容,敬请关注博客:<a href="http://www.cnblogs.com/EmptyFS/" target="_blank">http://www.cnblogs.com/EmptyFS/</a>
- <br />
- <br />
- <a href="http://www.cnblogs.com/EmptyFS/tag/%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E7%BC%96%E5%86%99%E8%87%AA%E5%B7%B1%E7%9A%84C%23%E6%A1%86%E6%9E%B6/"
- target="_blank">从零开始编写自己的C#框架章节目录</a>
- <br />
- <br />
- <br />
- <h2>
- 使用技术</h2>
- <br />
- 本框架使用ASP.NET(C#)、MsSql、SubSonic3.、FineUI、Linq、T4模板、IIS缓存等相关技术
- <br />
- <br />
- <a href="https://github.com/subsonic" target="_blank">SubSonic</a>是<span style="font-size: 16px;"><a
- href="http://www.wekeroad.com/" target="_blank">Rob Conery</a><span style="font-size: 16px;">用c#语言写的</span></span>一
- 个ORM开源框架,使用BSD软件授权许可(The BSD -Clause License)。它是一个实用的快速开发框架,通过非常简单的配置,以及附带的T4模板,就可以帮我们生成功能强大的数据访问层工具,让开发人员远离SQL语句的拼接,专注于业务逻辑的开发。
- <br />
- <a target="_blank" style="font-weight: bold;" href="http://fineui.com/">FineUI</a>是<a
- href="http://cnblogs.com/sanshi/" target="_blank">三生石上</a> 和 <a href="http://www.codeplex.com/site/users/view/RingoDing"
- target="_blank">RingoDing</a> 创建并维护。使用Apache License v2.0软件授权许可(ExtJS 库在
- <a target="_blank" href="http://www.sencha.com/license">GPL v3</a> 协议下发布)。它基于 jQuery
- / ExtJS 的 ASP.NET 控件库,创建 No JavaScript,No CSS,No UpdatePanel,No ViewState,No WebServices
- 的网站应用程序
- <br />
- <br />
- <h2>
- 支持的浏览器</h2>
- IE 8.0+、Chrome、Firefox、Opera、Safari
- <br />
- <br />
- <br />
- <br />
- 注:本框架不内置 ExtJS 库,请自行下载ExtJS 库后手工添加:<a target="_blank" href="http://fineui.com/bbs/forum.php?mod=viewthread&tid=3218">http://fineui.com/bbs/forum.php?mod=viewthread&tid=3218</a>
- </f:ContentPanel>
- </Items>
- </f:Tab>
- </Tabs>
- </f:TabStrip>
- </Items>
- </f:Region>
- </Regions>
- </f:RegionPanel>
- <f:Window ID="Window1" runat="server" IsModal="true" Hidden="true" EnableIFrame="true"
- EnableResize="true" EnableMaximize="true" IFrameUrl="about:blank" Width="650px"
- Height="450px">
- </f:Window>
- </form>
- <script>
- var menuClientID = '<%= leftMenuTree.ClientID %>';
- var tabStripClientID = '<%= mainTabStrip.ClientID %>';
- // 页面控件初始化完毕后,会调用用户自定义的onReady函数
- F.ready(function () {
- // 初始化主框架中的树(或者Accordion+Tree)和选项卡互动,以及地址栏的更新
- // treeMenu: 主框架中的树控件实例,或者内嵌树控件的手风琴控件实例
- // mainTabStrip: 选项卡实例
- // createToolbar: 创建选项卡前的回调函数(接受tabConfig参数)
- // updateLocationHash: 切换Tab时,是否更新地址栏Hash值
- // refreshWhenExist: 添加选项卡时,如果选项卡已经存在,是否刷新内部IFrame
- // refreshWhenTabChange: 切换选项卡时,是否刷新内部IFrame
- F.util.initTreeTabStrip(F(menuClientID), F(tabStripClientID), null, true, false, false);
- });
- </script>
- </body>
- </html>
Main.aspx.cs
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Web;
- using DotNet.Utilities;
- using FineUI;
- using Solution.DataAccess.DataModel;
- using Solution.DataAccess.DbHelper;
- using Solution.Logic.Managers;
- using Solution.Web.Managers.WebManage.Application;
- using SubSonic.Query;
- namespace Solution.Web.Managers
- {
- public partial class Main : PageBase
- {
- //用户页面操作权限
- string _pagePower = "";
- #region Page_Load
- protected void Page_Load(object sender, EventArgs e)
- {
- if (!IsPostBack)
- {
- //添加万年历按键事件,在主窗口中添加新选项卡
- btnCalendar.OnClientClick = mainTabStrip.GetAddTabReference("calendar_tab", "/WebManage/Help/wannianli.htm", "万年历", IconHelper.GetIconUrl(Icon.Calendar), true);
- //加载信息
- LoadData();
- }
- }
- #endregion
- #region 接口函数,用于UI页面初始化,给逻辑层对象、列表等对象赋值
- public override void Init()
- {
- }
- #endregion
- #region 加载数据
- /// <summary>读取数据</summary>
- public override void LoadData()
- {
- #region 展示用户信息
- //在线人数
- txtOnlineUserCount.Text = OnlineUsersBll.GetInstence().GetUserOnlineCount() + "";
- //当前用户信息
- var userHashKey = OnlineUsersBll.GetInstence().GetUserHashKey();
- var model = OnlineUsersBll.GetInstence().GetModelForCache(x => x.UserHashKey == userHashKey);
- if (model == null)
- return;
- //用户名称
- txtUser.Text = model.Manager_CName + " [" + IpHelper.GetUserIp() + "]";
- //部门
- txtBranchName.Text = model.Branch_Name;
- //职位
- txtPositionInfoName.Text = model.Position_Name;
- #endregion
- #region 菜单栏数据绑定
- //获取用户页面操作权限
- _pagePower = OnlineUsersBll.GetInstence().GetPagePower();
- //创建查询条件
- var wheres = new List<ConditionFun.SqlqueryCondition>();
- //条件:只查询出需要显示的菜单
- wheres.Add(new ConditionFun.SqlqueryCondition(ConstraintType.And, MenuInfoTable.IsDisplay, Comparison.Equals, ));
- //进行查询,获取DataTable
- var dt = MenuInfoBll.GetInstence().GetDataTable(false, , null, , , wheres);
- //绑定树列表
- BandingTree(dt);
- #endregion
- #region 开启时钟检测
- Timer1.Enabled = true;
- #endregion
- }
- #endregion
- #region 页面按键
- #region 清空缓存并重新加载
- /// <summary>
- /// 清空缓存并重新加载
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- protected void btnClearCache_Click(object sender, EventArgs e)
- {
- //清空全部后端缓存HttpRuntime.Cache(在线列表缓存除外)
- CacheHelper.RemoveManagersAllCache();
- }
- #endregion
- #region 退出系统
- /// <summary>
- /// 退出系统
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- protected void btnExit_Click(object sender, EventArgs e)
- {
- LoginLogBll.GetInstence().UserExit();
- FineUI.Alert.ShowInTop("成功退出系统!", "安全退出", MessageBoxIcon.Information, "top.location='Login.aspx'");
- }
- #endregion
- #endregion
- #region 定时器
- /// <summary>
- /// 定时执行方法
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- protected void Timer1_Tick(object sender, EventArgs e)
- {
- Timer1.Enabled = false;
- #region 检测当前用户是否退出
- OnlineUsersBll.GetInstence().IsTimeOut();
- #endregion
- #region 检测用户登录的有效性(是否被系统踢下线或管理员踢下线)
- if (OnlineUsersBll.GetInstence().IsOffline(this))
- return;
- #endregion
- #region 更新信息(在线人数,未读取的短消息)
- if (HttpRuntime.Cache == null)
- {
- txtOnlineUserCount.Text = "--";
- }
- else
- {
- //更新当前在线用户数量
- txtOnlineUserCount.Text = OnlineUsersBll.GetInstence().GetUserOnlineCount() + "";
- }
- #endregion
- #region 修改用户最后在线时间
- //修改用户最后在线时间
- OnlineUsersBll.GetInstence().UpdateTime();
- #endregion
- Timer1.Enabled = true;
- }
- #endregion
- #region FineUI控件之--树控件(Tree)
- #region 绑定树控件
- /// <summary>树控件(Tree)
- /// </summary>
- /// <param name="dataTable">DataTable数据源</param>
- /// <returns>树控件(Tree)</returns>
- public void BandingTree(DataTable dataTable)
- {
- try
- {
- //检查指定的列是否在数据源中能否找到
- if (dataTable.Rows.Count == )
- {
- return;
- }
- //筛选出全部一级节点
- DataTable dtRoot = DataTableHelper.GetFilterData(dataTable, MenuInfoTable.ParentId, "", MenuInfoTable.Sort, "Asc");
- //判断是否有节点存在
- if (dtRoot.Rows.Count != )
- {
- //循环读取节点
- foreach (DataRow dr in dtRoot.Rows)
- {
- //判断当前节点是否有权限访问,没有则跳过本次循环
- //暂时先注释掉权限判断,等添加相关权限后再开启
- //if (_pagePower.IndexOf("," + dr[MenuInfoTable.Id].ToString() + ",") < 0)
- //{
- // continue;
- //}
- //创建树节点
- var treenode = new FineUI.TreeNode();
- //设置节点ID
- treenode.NodeID = dr[MenuInfoTable.Id].ToString();
- //设置节点名称
- treenode.Text = dr[MenuInfoTable.Name].ToString();
- treenode.Target = "mainRegion";
- //判断当前节点是否为最终节点
- if (int.Parse(dr[MenuInfoTable.IsMenu].ToString()) != )
- {
- //设置节点链接地址,并在Url后面添加页面加密参数
- treenode.NavigateUrl = dr[MenuInfoTable.Url].ToString() + "?" + MenuInfoBll.GetInstence().PageUrlEncryptString();
- treenode.Leaf = true;
- }
- else
- {
- treenode.NavigateUrl = "";
- treenode.Leaf = false;
- //设置树节点收缩起来
- treenode.Expanded = false;
- }
- //添加子节点
- AddChildrenNode(dataTable, treenode, dr[MenuInfoTable.Id].ToString());
- //将节点加入树列表中
- leftMenuTree.Nodes.Add(treenode);
- }
- }
- }
- catch (Exception ex)
- {
- CommonBll.WriteLog("", ex);
- }
- }
- #endregion
- #region 添加子节点
- /// <summary>
- /// 添加子节点
- /// </summary>
- /// <param name="dt">数据表</param>
- /// <param name="treenode">当前树节点</param>
- /// <param name="parentID">父节点ID值</param>
- private void AddChildrenNode(DataTable dt, FineUI.TreeNode treenode, string parentID)
- {
- //筛选出当前节点下面的子节点
- DataTable Childdt = DataTableHelper.GetFilterData(dt, MenuInfoTable.ParentId, parentID, MenuInfoTable.Sort, "Asc");
- //判断是否有节点存在
- if (Childdt.Rows.Count > )
- {
- //循环读取节点
- foreach (DataRow dr in Childdt.Rows)
- {
- //判断当前节点是否有权限访问,没有则跳过本次循环
- //if (_pagePower.IndexOf("," + dr[MenuInfoTable.Id].ToString() + ",") < 0)
- //{
- // continue;
- //}
- //创建子节点
- var TreeChildNode = new FineUI.TreeNode();
- //设置节点ID
- TreeChildNode.NodeID = dr[MenuInfoTable.Id].ToString();
- //设置节点名称
- TreeChildNode.Text = dr[MenuInfoTable.Name].ToString();
- TreeChildNode.Target = "mainRegion";
- //判断当前节点是否为最终节点
- if (int.Parse(dr[MenuInfoTable.IsMenu].ToString()) != )
- {
- //设置节点链接地址
- if (dr[MenuInfoTable.Url].ToString().IndexOf("?") > )
- {
- TreeChildNode.NavigateUrl = dr[MenuInfoTable.Url].ToString() + "&" + MenuInfoBll.GetInstence().PageUrlEncryptString();
- }
- else
- {
- TreeChildNode.NavigateUrl = dr[MenuInfoTable.Url].ToString() + "?" + MenuInfoBll.GetInstence().PageUrlEncryptString();
- }
- //TreeChildNode.NavigateUrl = dr[MenuInfoTable.Url].ToString() + "?" + MenuInfoBll.PageURLEncryptString();
- TreeChildNode.Leaf = true;
- }
- else
- {
- TreeChildNode.NavigateUrl = "";
- TreeChildNode.Leaf = false;
- //设置树节点扩张
- TreeChildNode.Expanded = true;
- }
- //将节点添加进树列表中
- treenode.Nodes.Add(TreeChildNode);
- //递归添加子节点
- AddChildrenNode(dt, TreeChildNode, dr[MenuInfoTable.Id].ToString());
- }
- }
- }
- #endregion
- #endregion
- }
- }
1、Main.aspx页面说明
Main.aspx页面主要使用的是FineUI发布的空项目改造而来的,在这个基础上,顶部添加了当前用户的相关信息、在线人数,以及清除缓存、万年历和退出等按键。
添加了<f:Timer ID="Timer1" Interval="60" Enabled="false" OnTick="Timer1_Tick" runat="server">定时器功能,它每60秒会运行一次,执行Timer1_Tick函数,检查当前用户是否已退出,检查当前用户帐号是否已在其他电脑或浏览器上登陆或给管理员踢出系统,更新顶部当前在线人数,更新用户最后在线时间(用于检查用户是否超时离线退出)
- #region 定时器
- /// <summary>
- /// 定时执行方法
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- protected void Timer1_Tick(object sender, EventArgs e)
- {
- Timer1.Enabled = false;
- #region 检测当前用户是否退出
- OnlineUsersBll.GetInstence().IsTimeOut();
- #endregion
- #region 检测用户登录的有效性(是否被系统踢下线或管理员踢下线)
- if (OnlineUsersBll.GetInstence().IsOffline(this))
- return;
- #endregion
- #region 更新信息(在线人数,未读取的短消息)
- if (HttpRuntime.Cache == null)
- {
- txtOnlineUserCount.Text = "--";
- }
- else
- {
- //更新当前在线用户数量
- txtOnlineUserCount.Text = OnlineUsersBll.GetInstence().GetUserOnlineCount() + "";
- }
- #endregion
- #region 修改用户最后在线时间
- //修改用户最后在线时间
- OnlineUsersBll.GetInstence().UpdateTime();
- #endregion
- Timer1.Enabled = true;
- }
- #endregion
2、Main.aspx.cs文件父类
它继承PageBase类,页面在加载的时间,就会自动调用父类的OnInit初始化函数,运行里面的程序,来检查当前用户是否退出,是否有当前页面的操作权限,设置放置在页面控件Id为toolBar中的各个按键是否有权限使用。并记录用户当前所在位置。
3、添加页面按键事件
对于FineUI的页面按键事件,共一两种,一种是服务器端事件OnClick,一种是客户端事件OnClientClick。
添加了服务器端事件OnClick事件后,必须在cs文件中添加对应的事件函数,比如清空缓存按键(btnClearCache_Click)与安全退出按键(btnExit_Click)
- #region 页面按键
- #region 清空缓存并重新加载
- /// <summary>
- /// 清空缓存并重新加载
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- protected void btnClearCache_Click(object sender, EventArgs e)
- {
- //清空全部后端缓存HttpRuntime.Cache(在线列表缓存除外)
- CacheHelper.RemoveManagersAllCache();
- }
- #endregion
- #region 退出系统
- /// <summary>
- /// 退出系统
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- protected void btnExit_Click(object sender, EventArgs e)
- {
- LoginLogBll.GetInstence().UserExit();
- FineUI.Alert.ShowInTop("成功退出系统!", "安全退出", MessageBoxIcon.Information, "top.location='Login.aspx'");
- }
- #endregion
清空缓存按键主要功能:清除当前IIS应用程序池中除在线缓存以外的所有HttpRuntime.Cache缓存
安全退出按键主要功能:删除当前登陆用户的所有缓存、Session与Cookies记录,并添加用户退出日志。
点击退出后日志记录信息(LoginLog表):
而客户端事件OnClientClick,只需要在页面中添加JS代码,它就会直接执行对应的JS函数,不与服务器端进行直接交互。
当前除了以上添加按键事件外,还可以直接在代码中绑定控件事件方法(添加新选项卡还有其他一些方法,不过以这一种最为方便)
- #region Page_Load
- protected void Page_Load(object sender, EventArgs e)
- {
- if (!IsPostBack)
- {
- //添加万年历按键事件,在主窗口中添加新选项卡
- btnCalendar.OnClientClick = mainTabStrip.GetAddTabReference("calendar_tab", "/WebManage/Help/wannianli.htm", "万年历", IconHelper.GetIconUrl(Icon.Calendar), true);
- //加载信息
- LoadData();
- }
- }
- #endregion
以上代码主要是为万年历按键添加一个事件,点击按键后,在首页标签旁边新增一个选项卡,打开万年历页面。这些FineUI的范例官网上有,大家自行学习就可以了。
4、展示用户信息
这个比较简单,在LoadData函数中,直接从在线缓存中读取当前用户实体后,为页面顶部控件赋值就可以了。
在这里简单的讲讲LoadData函数,这是父类的抽像函数(因为每个子类都必须将它实现,所以将它从虚函数改为抽像函数),在每个子类中都必须要重写它,它的主要功能是加载数据,列表页面主要加载的是列表中需要显示的记录,而编辑页面加载的是各个页面的实体,将它们与页面控件进行绑定并显示出来。实现了该函数后,它将会被父类中的其他各种函数引用,比如刷新、查询、翻页、保存排序、自动排序、删除、关闭子窗口......等函数执行完后会调用它来重新加载数据,刷新页面显示内容,具体大家可以查看PageBase.cs类,看看有那些函数引用了LoadData函数就知道了。
5、绑定菜单栏树列表
首先将所有可以显示的菜单全部读取出来
下面是LoadData函数中的一段代码
- #region 菜单栏数据绑定
- //获取用户页面操作权限
- _pagePower = OnlineUsersBll.GetInstence().GetPagePower();
- //创建查询条件
- var wheres = new List<ConditionFun.SqlqueryCondition>();
- //条件:只查询出需要显示的菜单
- wheres.Add(new ConditionFun.SqlqueryCondition(ConstraintType.And, MenuInfoTable.IsDisplay, Comparison.Equals, ));
- //进行查询,获取DataTable
- var dt = MenuInfoBll.GetInstence().GetDataTable(false, , null, , , wheres);
- //绑定树列表
- BandingTree(dt);
- #endregion
ConditionFun.SqlqueryCondition是封装好的查询条件类。
第一个参数为查询表达式,即当前条件与前一条件使用的表达式是And还是Or;
第二个参数是想要查询的列表名称,这里我们使用的是表名+Table.列名的方式调用,这样操作的话可以使我们的代码去除硬编码,好处是当我们万一修改了数据库字段名称后,重新生成相关的模板并按F6重新编译代码时,就会直接报出所有未同步修改的代码错误位置出来,让我们能快速定位并修改掉它,而硬编码(指的是直接使用类似"IsDisplay"这种字段书写格式的代码)则不会报错,代码量多时我们将很难找出问题,直接程序执行到对应位置时才会抛出异常。
第三个参数是条件值表达式,表示当前列与值的关系,比如:等于、大于、小于、in、not in、like......等;
第四个参数是条件值
在这里要同大家说明的是,SubSonic3.0对于括号支持的不是很多,只支持单层括号,嵌套括号时将会出错,为了避免这种问题,建议多括号做为条件值查询时,请使用Linq表达式来查询(Lambd表达式),或者存储过程。具体加括号后的使用方法在后面章节会详细的进行说明。
MenuInfoBll.GetInstence().GetDataTable()函数是我们逻辑层生成好的模板函数,我们直接调用就可以了。(我们后端开发对于数据的增、删、查、改等操作函数几乎都已经生成好了,直接调用就可以)
通过执行BandingTree函数与AddChildrenNode函数,将菜单树列表创建后绑定<f:Tree runat="server" ShowBorder="false" ShowHeader="false" EnableArrows="true" EnableLines="true" ID="leftMenuTree"></f:Tree>控件
下面通过向MenuInfo表添加一些菜单记录来演示我们首页中的树列表显示效果
- TRUNCATE TABLE MenuInfo
- GO
- set IDENTITY_INSERT MenuInfo on
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (1, '系统管理', '/WebManage/Systems/SysAuthority/', 0, 6, 0, 1, 0)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (2, '基本设置', '/WebManage/Systems/SysSet/', 1, 1, 1, 1, 0)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (3, '权限管理', '/WebManage/Systems/SysAuthority/', 1, 2, 1, 1, 0)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (5, '安全管理', '/WebManage/Systems/SysSecurity/', 1, 3, 1, 1, 0)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (6, '网站参数设置', '/WebManage/Systems/SysSet/WebConfigSet.aspx', 2, 1, 2, 1, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (11, '菜单管理', '/WebManage/Systems/SysAuthority/MenuPage.aspx', 3, 1, 2, 1, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (12, '菜单编辑', '/WebManage/Systems/SysAuthority/MenuPageEdit.aspx', 3, 2, 2, 0, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (13, '页面权限设置', '/WebManage/Systems/SysAuthority/PagePowerSignList.aspx', 3, 3, 2, 1, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (14, '部门管理', '/WebManage/Systems/SysAuthority/BranchList.aspx', 3, 7, 2, 1, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (15, '部门编辑', '/WebManage/Systems/SysAuthority/BranchEdit.aspx', 3, 8, 2, 0, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (16, '职位管理', '/WebManage/Systems/SysAuthority/PositionList.aspx', 3, 9, 2, 1, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (17, '职位编辑', '/WebManage/Systems/SysAuthority/PositionEdit.aspx', 3, 10, 2, 0, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (18, '管理员管理', '/WebManage/Systems/SysAuthority/ManagerList.aspx', 3, 12, 2, 1, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (19, '管理员编辑', '/WebManage/Systems/SysAuthority/ManagerEdit.aspx', 3, 13, 2, 0, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (20, '职位权限树状图', '/WebManage/Systems/SysAuthority/MenuPageTree.aspx', 3, 11, 2, 0, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (21, '登陆日志', '/WebManage/Systems/SysSecurity/LoginLogList.aspx', 5, 1, 2, 1, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (22, '操作日志', '/WebManage/Systems/SysSecurity/UseLogList.aspx', 5, 2, 2, 1, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (23, '在线用户', '/WebManage/Systems/SysSecurity/OnlineUsers.aspx', 5, 3, 2, 1, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (36, '信息发布', '/WebManage/Information/', 0, 1, 0, 1, 0)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (37, '文章管理', '/WebManage/Information/Info/', 36, 1, 1, 1, 0)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (38, '文章栏目管理', '/WebManage/Information/Info/InfoClassList.aspx', 37, 1, 2, 1, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (39, '文章栏目编辑', '/WebManage/Information/Info/InfoClassAdd.aspx', 37, 2, 2, 0, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (40, '文章内容管理', '/WebManage/Information/Info/InfoList.aspx', 37, 3, 2, 1, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (41, '文章内容编辑', '/WebManage/Information/Info/InfoAdd.aspx', 37, 4, 2, 0, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (127, '页面权限编辑', '/WebManage/Systems/SysAuthority/PagePowerSignEdit.aspx', 3, 4, 2, 0, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (129, '公共页面权限设置', '/WebManage/Systems/SysAuthority/PagePowerSignPublicList.aspx', 3, 5, 2, 1, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (130, '公共页面权限编辑', '/WebManage/Systems/SysAuthority/PagePowerSignPublicEdit.aspx', 3, 6, 2, 0, 1)
- GO
- INSERT INTO MenuInfo (Id, Name, Url, ParentId, Sort, Depth, IsDisplay, IsMenu) VALUES (203, '错误日志', '/WebManage/Systems/SysSecurity/ErrorLog.aspx', 5, 4, 2, 1, 1)
- GO
- set IDENTITY_INSERT MenuInfo off
6、小结
登陆页、父类与后端首页,是本系统三个最基本的组成零部件,完成了这三个部件后,接下来就是体验如何来进行快速开发的成果了。后面章节发表的内容,主要是针对框架中已生成函数或一些特殊功能(函数)的调用方法讲解,用实例来讲述这些功能的使用方法。
点击下载:
本框架不内置 ExtJS 库,请自行下载ExtJS 库后手工添加到Solution.Web.Managers项目的根目录中(如下图):http://fineui.com/bbs/forum.php?mod=viewthread&tid=3218
由于框架不是非常成熟,很多朋友不是用来学习而是直接用到项目中,但不熟悉框架引起不少小问题,所以停止提供下载,有需要学习的可以到群共享里下,不便之处敬请谅解。
版权声明:
本文由AllEmpty原创并发布于博客园,欢迎转载,未经本人同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。如有问题,可以通过1654937@qq.com 联系我,非常感谢。
发表本编内容,只要主为了和大家共同学习共同进步,有兴趣的朋友可以加加Q群:327360708 ,大家一起探讨。
更多内容,敬请观注博客:http://www.cnblogs.com/EmptyFS/
从零开始编写自己的C#框架(17)——Web层后端首页的更多相关文章
- 从零开始编写自己的C#框架(1)——前言
记得十五年前自学编程时,拿着C语言厚厚的书,想要上机都不知道要用什么编译器来执行书中的例子.十二年前在大学自学ASP时,由于身边没有一位同学和朋友学习这种语言,也只能整天混在图收馆里拼命的啃书.而再后 ...
- 从零开始编写自己的C#框架 ---- 系列文章
目录: 从零开始编写自己的C#框架(1)——前言从零开始编写自己的C#框架(2)——开发前的准备工作从零开始编写自己的C#框架(3)——开发规范从零开始编写自己的C#框架(4)——文档编写说明从零开始 ...
- 从零开始编写自己的C#框架(15)——Web层后端登陆功能
对于一个后端管理系统,最重要内容之一的就是登陆页了,无论是安全验证.用户在线记录.相关日志记录.单用户或多用户使用帐号控制等,都是在这个页面进行处理的. 1.在解决方案中创建一个Web项目,并将它设置 ...
- 从零开始编写自己的C#框架(25)——网站部署 【转】
服务器安全部署文档 目录1. 前言.. 3 2. 部署环境.. 3 2.1 服务器环境信息.. 3 3. 磁盘阵列配置.. 4 4. 安装操作系统.. ...
- 从零开始编写自己的C#框架(25)——网站部署
导航 1.关掉访问保护 2.发布网站 3.复制网站到服务器 4.添加新网站 5.设置网站访问权限 6.设置文件夹访问权限 7.控制可更新文件夹执行权限 8.设置“应用程序池”.net版本与模式 9.附 ...
- 从零开始编写自己的C#框架(8)——后台管理系统功能设计
还是老规矩先吐下槽,在规范的开发过程中,这个时候应该是编写总体设计(概要设计)的时候,不过对于中小型项目来说,过于规范的遵守软件工程,编写太多文档也会拉长进度,一般会将它与详细设计合并到一起来处理,所 ...
- 从零开始编写自己的C#框架(26)——小结
一直想写个总结,不过实在太忙了,所以一直拖啊拖啊,拖到现在,不过也好,有了这段时间的沉淀,发现自己又有了小小的进步.哈哈...... 原想框架开发的相关开发步骤.文档.代码.功能.部署等都简单的讲过了 ...
- 从零开始编写自己的C#框架(20)——框架异常处理及日志记录
最近很忙,杂事也多,所以开发本框架也是断断续续的,终于在前两天将前面设定的功能都基本完成了,剩下一些小功能遗漏的以后发现再补上.接下来的章节主要都是讲解在本框架的基础上进行开发的小巧. 本框架主要有四 ...
- 从零开始编写自己的C#框架(11)——创建解决方案
这段时间一直在充电,拜读了园子中大神们的博文(wayfarer的<设计之道>.TerryLee的<.NET设计模式系列文章>.卡奴达摩的<设计模式>还有其他一些零散 ...
随机推荐
- Git 子模块 - submodule
有种情况我们经常会遇到:某个工作中的项目需要包含并使用另一个项目. 也许是第三方库,或者你 独立开发的,用于多个父项目的库. 现在问题来了:你想要把它们当做两个独立的项目,同时又想在 一个项目中使用另 ...
- 异步编程 In .NET
概述 在之前写的一篇关于async和await的前世今生的文章之后,大家似乎在async和await提高网站处理能力方面还有一些疑问,博客园本身也做了不少的尝试.今天我们再来回答一下这个问题,同时我们 ...
- 再谈C#采集,一个绕过高强度安全验证的采集方案?方案很Low,慎入
说起采集,其实我是个外行,以前拔过阿里巴巴的客户数据,在我博客的文章:C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子) 中,介绍过采集用的工具,其实很Low的,分析 ...
- [C#] 走进异步编程的世界 - 开始接触 async/await
走进异步编程的世界 - 开始接触 async/await 序 这是学习异步编程的入门篇. 涉及 C# 5.0 引入的 async/await,但在控制台输出示例时经常会采用 C# 6.0 的 $&qu ...
- MySQL设置字段的默认值为当前系统时间
问题产生: 当我们在对某个字段进行设置时间默认值,该默认值必须是的当前记录的插入时间,那么就将当前系统时间作为该记录创建的时间. 应用场景: 1.在数据表中,要记录每条数据是什么时候创建的,应该由数据 ...
- iOS开发之ReactiveCocoa下的MVVM(干货分享)
最近工作比较忙,但还是出来更新博客了,今天给大家分享一些ReactiveCocoa以及MVVM的一些东西,干活还是比较足的.在之前发表过一篇博文,名字叫做<iOS开发之浅谈MVVM的架构设计与团 ...
- 用Java代码实现拦截区域网数据包
起因: 吃饭的时间在想如果区域网内都是通过路由器上网,那如何实现拦截整个区域网的数据包,从而实现某种窥探欲. 思路: 正常是通过电脑网卡预先设置或分配的IP+网关对路由器进行通讯,比如访问百 ...
- 如何dos命令打开服务窗口?
1.输入services.msc点击<确定>进入服务窗口.如图:
- 设计模式之工厂模式VS抽象工厂
一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类:1)简单工厂模式(Simple Factor ...
- SQL数据类型
1.Character 字符串: 数据类型 描述 存储 char(n) 固定长度的字符串.最多8,000个字符. n varchar(n) 可变长度的字符串.最多8,000个字符. varchar ...