ShenNiu.MVC管理系统
本篇将要和大家分享的是一个简单的后台管理系统,这里先发个地址http://www.lovexins.com:8081/(登陆账号:youke,密码:123123;高级用户账号:gaoji,密码:123123)有兴趣的各位可以先简单看下效果,此系统采用:Ace的h5样式+Mvc5.0 + redis+sqlserver+shenniu.pager.js构建完成,构建此项目初衷为了有一套自己现成的h5后台系统,为了以后能快速开发搭建一些系统;项目源码暂时不开源(完善后开源),如果您的确认可或者想研究下,可以扫博客下方二维码支持一下获取源码(哪怕1分钱都可),当然此文章主要目的不是为了广告,而是为了分享一些重要或者常用的代码处理方式,希望大家喜欢,多多支持:
. Controller中使用自带生成的Dispose(bool)好与坏
. List集合生成权限树
. 对比集合,加载checkboxlist
. 为啥使用redis来保存session
下面一步一个脚印的来分享:
. Controller中使用自带生成的Dispose(bool)好与坏
首先,咋们先来看下mvc模板自动生成的Dispose重写方法:
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
因为Controller实现了接口IDisposable,所以里面可以使用Dispose方法,再看db.dispose()这是用来释放连接数据库对象的,如果细心的朋友可以在调试的时候发现,我们在执行某个连接数据库操作后,退出action的时候会进入这个重新的Dispose方法中去,主要目的用来释放在Controller最上面生成的连接数据库对象,我这里是:
看到这里个人觉吧这个对象放在这使用起来挺方便的,不过带来一个问题就是,如果在业务逻辑复杂的地方,直接使用这个db,直到最后执行完整个action退出Controller的时候才dispose释放连接会不会有问题,心中存疑,再加上前几天看了一篇博文,分享的内容大概有如此的字样:ef不需要使用using(原理也就是dispose)自己就能在操作完数据库后释放,原因底层已经实现了这个dispose;如此更让人感觉直接在Controller类下面申明数据库链接方便的很,但试为什么微软mvc模板Controller中会再自带一个dispose方法呢,这两种情况存在不排除的说法,当然今天的主要目的不是为了验证这两种到底哪个是对的,此文章暂时以自动生成的dispose为合理说法来分享内容(注:朋友们请勿抠字眼);
一起来看,假如自动模板生成的全部靠Controller重写的这个dispose来释放数据连接,那么在多业务逻辑下,比如我在登陆的时候我们除了匹配唯一用户外,还需要记录获取权限树,加入redis的session储存其中等操作,不可能等这些操作完了再来释放数据连接,这样登陆用户多了一定会有问题吧,如果是这种情况的问题,或许只能通过在某处操作数据库后即时释放连接了;以上是格式观点和看法,或许有不妥之处,请联系指正,谢谢,特别是using真的不需要吗这个问题;
. List集合生成权限树
首先,我这里定义了一个固定的实体:
/// <summary>
/// 菜单类
/// </summary>
public class MoMenu
{ /// <summary>
/// 菜单Id (必填)
/// </summary>
public int Id { get; set; } /// <summary>
/// 名称
/// </summary>
public string Name { get; set; } /// <summary>
/// 链接地址 (建议填写,每个需要登录访问的Action需要使用这个对比是否有权限)
/// </summary>
public string Link { get; set; } /// <summary>
/// 描述
/// </summary>
public string Des { get; set; } /// <summary>
/// 图标样式,对应StageClass.MoIcon
/// </summary>
public string Icon { get; set; } /// <summary>
/// 排序(升序)
/// </summary>
public int Sort { get; set; } /// <summary>
/// 父级菜单Id,最顶层父级默认0
/// </summary>
public int ParentId { get; set; } /// <summary>
/// 是否导航栏
/// </summary>
public bool IsMenu { get; set; } /// <summary>
/// 菜单子级集合
/// </summary>
public List<MoMenu> ListMenu { get; set; }
}
主要用来装系统中所有菜单的数据,并且区分层级关系,然后通过如下方法:
/// <summary>
/// List集合生成菜单树
/// </summary>
/// <typeparam name="T">对比选中菜单的对象</typeparam>
/// <param name="html"></param>
/// <param name="list">系统全部菜单(需要有层级关系)</param>
/// <param name="name">生成的checkboxlist的name</param>
/// <param name="checkList">选中菜单的集合</param>
/// <param name="defValFiled">选中匹配的默认值</param>
/// <param name="isEnable">是否启用(查看状态不需要启用)</param>
/// <param name="nLoop">循环层次(可能多余的吧)</param>
/// <returns></returns>
public static MvcHtmlString CheckBoxMenuByList<T>(
this HtmlHelper html,
List<StageModel.MoMenu> list,
string name = "RadStatus",
IEnumerable<T> checkList = null,
string defValFiled = "Id", bool isEnable = true,
int nLoop = )
where T : class ,new()
{
var sbHtml = new StringBuilder(string.Empty);
sbHtml.AppendFormat("<ul class='divmenu' style=\"list-style:none;{0}\">", nLoop <= ? "display:block" : "display:none");
foreach (var item in list)
{
var isCheck = false;
if (checkList != null)
{
foreach (var checkItem in checkList)
{
var ty = checkItem.GetType();
var val = ty.GetProperty(defValFiled).GetValue(checkItem, null);
isCheck = val.ToString().Equals(item.Id.ToString());
if (isCheck) { break; }
}
} sbHtml.Append("<li>");
sbHtml.AppendFormat("<input id=\"{0}{1}\" name=\"{0}\" type=\"checkbox\" value=\"{1}\" {3} {4}/><label>{2}<b>{5}</b></label>", // class=\"arrow fa fa-angle-down\"
name,
item.Id,
item.Name,
isCheck ? "checked=\"checked\"" : "",
isEnable ? "" : "disabled=\"disabled\"", item.ListMenu == null ? "" : (item.ListMenu.Count > ? string.Format("[{0}]", item.ListMenu.Count) : "")
);
if (item.ListMenu == null) { sbHtml.Append("</li>"); continue; }
if (item.ListMenu.Count > )
{
sbHtml.Append(CheckBoxMenuByList(html, item.ListMenu, name, checkList, defValFiled, isEnable, isCheck ? : nLoop++));
}
sbHtml.Append("</li>");
}
sbHtml.Append("</ul>");
return MvcHtmlString.Create(sbHtml.ToString());
}
遍历生成菜单树,功能有:1.在查看状态即可使其禁用选择,2.编辑状态匹配对象选中菜单;然后需要在试图中增加如js代码:
$("ul[class='divmenu'] li input[type='checkbox']").on("click", function () { var isCheck = $(this).is(":checked");
//子级
$(this).nextAll("ul").find("li input[type='checkbox']").prop("checked", isCheck);
});
$("ul[class='divmenu'] li label").on("click", function () {
$(this).next("ul[class='divmenu']").toggle("normal");
});
最后,只需要在需要用到该菜单树的地方添加代码如: @Html.CheckBoxMenuByList(Stage.Com.Extend.StageClass.GetAllMenus(), "MenuIds", Model.MoRoleAndMenus, "MenuId") 即可,看到的效果图:
具体大家可以登陆ShenNiu.MVC试试效果
. 对比集合,加载checkboxlist
首先,直接贴代码如:
/// <summary>
/// 对比集合,加载checkboxlist
/// </summary>
/// <typeparam name="T">目标对象</typeparam>
/// <param name="html"></param>
/// <param name="orgList">目标集合</param>
/// <param name="orgFiledVal">目标对应checkbox的value值的属性名称</param>
/// <param name="orgFiledText">对应的checkbox文本的text值的属性名称</param>
/// <param name="destList">匹配集合</param>
/// <param name="destFiled">匹配列的属性名称</param>
/// <param name="sClass">样式</param>
/// <param name="name">checkboxlist的Name</param>
/// <returns></returns>
public static MvcHtmlString CheckBoxRoleByList<T, TT>(
this HtmlHelper html,
IEnumerable<T> orgList,
string orgFiledVal,
string orgFiledText, IEnumerable<TT> destList = null,
string destFiled = "", string sClass = "",
string name = "cbAll")
where T : class ,new()
where TT : class,new()
{
var sbHtml = new StringBuilder(string.Empty);
if (orgList.Count() <= ) { return MvcHtmlString.Create(string.Empty); } sbHtml.AppendFormat("<div class=\"{0}\">", sClass);
foreach (var item in orgList)
{
var ty = item.GetType();
var val = ty.GetProperty(orgFiledVal).GetValue(item, null);
var text = ty.GetProperty(orgFiledText).GetValue(item, null); var isMatch = false;
if (destList != null)
{
foreach (var destItem in destList)
{
var destty = destItem.GetType();
var destval = destty.GetProperty(destFiled).GetValue(destItem, null); if (val.ToString().ToUpper().Equals(destval.ToString().ToUpper()))
{
isMatch = true;
break;
}
}
}
sbHtml.AppendFormat("<label><input type='checkbox' name='{0}' value='{1}' {3} />{2}</label>", name, val, text, isMatch ? "checked='checked'" : "");
}
sbHtml.Append("</div>");
return MvcHtmlString.Create(sbHtml.ToString());
}
使用编辑页面的效果图如:
看到效果是默认绑定了该用户对应的权限“高级用户”,代码需要重点是:
var ty = item.GetType();
var val = ty.GetProperty(orgFiledVal).GetValue(item, null);
var text = ty.GetProperty(orgFiledText).GetValue(item, null);
主要作用就是指定特定的属性,获取特定属性的value值;item是List集合中的某个对象,具体参数说明可以看下代码备注;
. 为啥使用redis来保存session
这个小标题不好定义,我个人的见解,大家可以看看罢了;1:redis存储数据可以设置失效时间,这就类似于session失效的效果一样,所以redis能很好的来当做session容器;2:用上面一点我们可以再增加nginx等分布式服务,以此来打架一个分布式架构,这样在更新子系统的时候不会造成所以的业务瘫痪,可以不对用户的操作造成阻碍,仿佛没有更细过一样;3:基于redis搭建session服务器后session服务器这个时候可以单独分到另外一台服务器上,这样减少了内存占有率,应用程序和session分布多个服务器,大大提高承载率,不至于说什么千万级别就把您系统cpu爆满了,session还各种丢失的情况;4.使用redis打架服务后可以利用剩余空间存储一些不长变动的数据和消息,列如:系统中的菜单栏,一些消息提醒,邮件发送等数据,都可以使用其保存;
以上是个人的观点和总结,希望能对大家有帮助;由于本人经验有限,如有不合理的地方请多多指正,谢谢。
ShenNiu.MVC管理系统的更多相关文章
- MVC - 单点登录中间件
本章将要和大家分享的是一个单点登录中间件,中间件听起来高深其实这里只是吧单点登录要用到的逻辑和处理流程封装成了几个方法而已,默认支持采用redis服务保存session的方式,也可以使用参数Func& ...
- MVC - 单点登录中间件 (转)
http://www.cnblogs.com/wangrudong003/p/6435013.html 本章将要和大家分享的是一个单点登录中间件,中间件听起来高深其实这里只是吧单点登录要用到的逻辑和处 ...
- MVC - 云服务器部署
本章将和大家分享的是如果在云服务器上部署mvc,云服务器部署其实也不高大上,就和咋们在自己电脑上用iis发布部署站点一样,只是需要使用云解析把自己购买的域名解析到对应的自己的云服务器上,这些都是用的云 ...
- MVC如何使用开源分页插件shenniu.pager.js
最近比较忙,前期忙公司手机端接口项目,各种开发+调试+发布现在几乎上线无问题了:虽然公司项目忙不过在期间抽空做了两件个人觉得有意义的事情,一者使用aspnetcore开发了个人线上项目(要说线上其实只 ...
- 分享基于EF+MVC+Bootstrap的通用后台管理系统及架构
基于EF+MVC+Bootstrap构建通用后台管理系统,集成轻量级的缓存模块.日志模块.上传缩略图模块.通用配置及服务调用, 提供了OA.CRM.CMS的原型实例,适合快速构建中小型互联网及行业 ...
- jsp学习之基于mvc学生管理系统的编写
mvc开发模式:分别是 model层 view层 Control层 在学生管理系统中,model层有学生实体类,数据访问的dao层,view层主要是用于显示信息的界面,Control层主要是servl ...
- 使用MiniProfiler跟踪MVC + EF + Bootstrap 2 权限管理系统的性能消耗
安装MiniProfiler 在MVC + EF + Bootstrap 2 权限管理系统入门级(附源码)文章中下载了它的源码,调试模式下打开一个页面都要再2.5秒以上,所以使用MiniProfile ...
- MVC + EF + Bootstrap 2 权限管理系统入门级(附源码)
MVC .EF 学习有大半年了,用的还不是很熟练,正好以做这样一个简单的权限管理系统作为学习的切入点,还是非常合适的. 开发环境: VS 2013 + Git + MVC 5 + EF 6 Code ...
- SpringMVC学习系列(12) 完结篇 之 基于Hibernate+Spring+Spring MVC+Bootstrap的管理系统实现
到这里已经写到第12篇了,前11篇基本上把Spring MVC主要的内容都讲了,现在就直接上一个项目吧,希望能对有需要的朋友有一些帮助. 一.首先看一下项目结构: InfrastructureProj ...
随机推荐
- Scrapy框架爬虫初探——中关村在线手机参数数据爬取
关于Scrapy如何安装部署的文章已经相当多了,但是网上实战的例子还不是很多,近来正好在学习该爬虫框架,就简单写了个Spider Demo来实践.作为硬件数码控,我选择了经常光顾的中关村在线的手机页面 ...
- 让姑姑不再划拳 码农也要有原则 : SOLID via C#
“姑娘,别这样.我们是有原则的.” “一个有原则的程序猿是不会写出 “摧毁地球” 这样的程序的,他们会写一个函数叫 “摧毁行星”而把地球当一个参数传进去.” “对,是时候和那些只会滚键盘的麻瓜不同了, ...
- HTML DOM 介绍
本篇主要介绍DOM内容.DOM 节点.节点属性以及获取HTML元素的方法. 目录 1. 介绍 DOM:介绍DOM,以及对DOM分类和功能的说明. 2. DOM 节点:介绍DOM节点分类和节点层次. 3 ...
- 预览github里面的网页或dome
1.问题所在: 之前把项目提交到github都可以在路径前面加上http://htmlpreview.github.io/?来预览demo,最近发现这种方式预览的时候加载不出来css,js(原因不详) ...
- iOS开发之Alamofire源码深度解析
今天博客中的Alamofire源码的版本是以现在最新的3.4版本为例.上篇博客系统的对NSURLSession相关的东西进行了详细的解析,详情请看<详解NSURLSession>,为了就是 ...
- ASP.NET MVC开发日常一:SessionID合理清除
在MVC Web开发中临时存储数据一般会用到Session,Cookie,ViewBag,ViewData,TempData.每个的使用场景是不同,具体区别有空再补上. Session数据最敏感,最需 ...
- Redis链表实现
链表在 Redis 中的应用非常广泛, 比如列表键的底层实现之一就是链表: 当一个列表键包含了数量比较多的元素, 又或者列表中包含的元素都是比较长的字符串时, Redis 就会使用链表作为列表键的底层 ...
- 来吧,HTML5之基础标签(上)
什么是html5 HTML 5 是下一代的 HTML.HTML5 仍处于完善之中.然而,大部分现代浏览器已经具备了某些 HTML5 支持. 学习过程中标签的理解 <a>标签 定义超链接, ...
- [Egret]优雅的写http
首先,自从使用链式调用的写法后,就一发不可收拾的喜爱上了这种优雅的方式.不管是写架构还是写模块,我都会不自觉的使用这种最优雅的方式.链式写法既减少了代码量,又非常优雅的. 在使用 egret 的htt ...
- golang语言构造函数
1.构造函数定义 构造函数 ,是一种特殊的方法.主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中.特别的一个类可以有多个构造函数 ,可根据其参数个 ...