ASP.NET MVC5网站开发之添加删除重置密码修改密码列表浏览管理员篇2(六)
一、安装插件。
展示层前端框架以bootstrap为主,因为bootstrap的js功能较弱,这里添加一些插件作补充。其实很多js插件可以通过nuget安装,只是nuget安装时添加的内容较多,不如自己复制来的干净,所以这里所有的插件都是下载然后复制到项目中。
1、bootstrap 3 datepicker 4.17.37
网址:
下载并解压压缩包->将bootstrap-datetimepicker.js和bootstrap-datetimepicker.min.js复制到ninesy.web项目的scripts文件夹,将bootstrap-datetimepicker.css和bootstrap-datetimepicker.min.css复制到content文件夹。
2、bootstrap-dialog 3.3.4.1
网址:
下载并解压压缩包->将.js复制到ninesy.web项目的scripts文件夹,将.css复制到content文件夹。
3、bootstrap-select 1.10.0
网址:
下载并解压压缩包->将bootstrap-select.js复制到ninesy.web项目的scripts文件夹,和defaults-zh_cn.js重命名为bootstrap-select-zh_cn.js复制到ninesy.web项目的scripts文件夹,将bootstrap-select.css、bootstrap-select.css.map和bootstrap-select.min.css复制到content文件夹。
4、bootstrap-table 1.10.1
网址:
下载并解压压缩包->将bootstrap-table.js和bootstrap-table-zh-cn.js复制到ninesy.web项目的scripts文件夹,将bootstrap-table.css复制到content文件夹。
5、bootstrap treeview 1.2.0
网址:
下载并解压压缩包->将bootstrap-treeview.js复制到ninesy.web项目的scripts文件夹,将bootstrap-treeview.css复制到content文件夹。
6、twbs-pagination
网址:
下载并解压压缩包->将jquery.twbspagination.js和jquery.twbspagination.min.js复制到ninesy.web项目的scripts文件夹。
7、对js和css进行捆绑和压缩
打开ninesky.web->app_start->bundleconfig.cs。添加红框内的代码。
二、获取modelstate错误信息的方法
在项目中有些内容是通过ajax方法提交,如果提交时客户端没有进行验证,在服务器端进行验证时会将错误信息保存在modelstate中,这里需要写一个方法来获取modelstate的错误信息,以便反馈给客户端。
1、ninesk.web【右键】->添加->类,输入类名general。
引用命名空间using system.web.mvc和system.text。
添加静态方法getmodelerrorstring(),该方法用来获取模型的错误字符串。
using system.linq; using system.text; using system.web.mvc; namespace ninesky.web { /// <summary> /// 通用类 /// </summary> public class general { /// <summary> /// 获取模型错误 /// </summary> /// <param name="modelstate">模型状态</param> /// <returns></returns> public static string getmodelerrorstring(modelstatedictionary modelstate) { stringbuilder _sb = new stringbuilder(); var _errormodelstate = modelstate.where(m => m.value.errors.count() > 0); foreach(var item in _errormodelstate) { foreach (var modelerror in item.value.errors) { _sb.appendline(modelerror.errormessage); } } return _sb.tostring(); } } }
三、完善布局页
上次完成了管理员登录,这次要进行登录后的一些功能,要先把后台的布局页充实起来。
打开 ninesky.web/areas/control/views/_layout.cshtml。整成下面的代码。自己渣一样的美工,具体过程就不写了。
<!doctype html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@viewbag.title - 系统管理</title> @styles.render("~/content//controlcss") @rendersection("style", required: false) @scripts.render("~/bundles/modernizr") @scripts.render("~/bundles/jquery") @scripts.render("~/bundles/bootstrap") @rendersection("scripts", required: false) </head> <body> <div class="navbar navbar-default navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> @html.actionlink("ninesky 系统管理", "index", "home", new { area = "control" }, new { @class = "navbar-brand" }) </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a><span class="glyphicon glyphicon-user"></span> 用户管理</a></li> <li><a href="@url.action("index","admin")"><span class='glyphicon glyphicon-lock'></span> 管理员</a></li> <li><a><span class="glyphicon glyphicon-list"></span> 栏目设置</a></li> <li><a><span class="glyphicon glyphicon-cog"></span> 网站设置</a></li> </ul> <ul class="nav navbar-nav navbar-right"> <li> <a href="@url.action("myinfo","admin")"><span class="glyphicon glyphicon-envelope"></span> @context.session["accounts"].tostring()</a> </li> <li> <a href="@url.action("logout","admin")"><span class="glyphicon glyphicon-log-out"></span> 退出</a> </li> </ul> </div> </div> </div> <div class="container body-content"> <div class="row"> <div class="col-lg-3 col-md-3 col-sm-4">@rendersection("sidenav", false)</div> <div class="col-lg-9 col-md-9 col-sm-8">@renderbody()</div> </div> <hr /> <footer class="navbar navbar-fixed-bottom text-center bg-primary "> <p>© ninesky v0.1 base by 洞庭夕照 http://mzwhj.cnblogs.com</p> </footer> </div> </body> </html>
反正效果就是这个样子了。
三、功能实现
按照设想,要在index界面完成管理员的浏览、添加和删除功能。这些功能采用ajax方式。
在添加admincontroller的时候自动添加了index()方法。
添加index视图
在index方法上右键添加视图
@{ viewbag.title = "管理员"; } <ol class="breadcrumb"> <li><span class="glyphicon glyphicon-home"></span> @html.actionlink("首页", "index", "home")</li> <li class="active">@html.actionlink("管理员", "index", "admin")</li> </ol> @section style{ @styles.render("~/content/bootstrapplugincss") } @section scripts{ @scripts.render("~/bundles/jqueryval") @scripts.render("~/bundles/bootstrapplugin") }
添加侧栏导航视图
ninesky.web/areas/control/views/admin【右键】->添加->视图
视图代码如下
<div class="panel panel-default"> <div class="panel-heading"> <div class="panel-title"><span class="glyphicon glyphicon-lock"></span> 管理员</div> </div> <div class="panel-body"> <div class="list-group"> <div class="list-group-item"><span class="glyphicon glyphicon-list"></span> @html.actionlink("管理","index")</div> </div> </div> </div>
在index视图中添加@section sidenav{@html.partial("sidenavpartialview")}(如图)
1、管理员列表
在admin控制器中添加listjson()方法
/// <summary> /// 管理员列表 /// </summary> /// <returns></returns> public jsonresult listjson() { return json(adminmanager.findlist()); }
为在index中使用bootstrap-table显示和操作管理员列表,在index视图中添加下图代码。
<div id="toolbar" class="btn-group" role="group"> <button id="btn_add" class="btn btn-default"><span class="glyphicon glyphicon-plus"></span> 添加</button> <button id="btn_del" class="btn btn-default"><span class="glyphicon glyphicon-remove"></span> 删除</button> </div> <table id="admingrid"></table>
在@section scripts{ } 中添加js代码
<script type="text/javascript"> $(document).ready(function () { //表格 var $table = $('#admingrid'); $table.bootstraptable({ toolbar: "#toolbar", showrefresh: true, showcolumns: true, showfooter: true, method: "post", url: "@url.action("listjson")", columns: [ { title: "state", checkbox: true }, { title: "id", field: "administratorid" }, { title: "帐号", field: "accounts" }, { title: "登录时间", field: "logintime", formatter: function (value) { return moment(value).format("yyyy-mm-dd hh:mm:ss") } }, { title: "登录ip", field: "loginip" }, { title: "创建时间", field: "createtime", formatter: function (value) { return moment(value).format("yyyy-mm-dd hh:mm:ss") } }, { title: "操作", field: "administratorid", formatter: function (value, row, index) { return "<a href=\"javascript:void(0)\" onclick=\"resetpassword(" + value + ",'" + row.accounts + "')\">重置密码</a>" } } ] }); //表格结束 }); </script> }
显示效果如图:
2、添加管理员
在控制器中添加addpartialview()方法
/// <summary> /// 添加【分部视图】 /// </summary> /// <returns></returns> public partialviewresult addpartialview() { return partialview(); }
models文件夹【右键】->添加->类,输入类名 addadminviewmodel。
using system.componentmodel.dataannotations; namespace ninesky.web.areas.control.models { /// <summary> /// 添加管理员模型 /// </summary> public class addadminviewmodel { /// <summary> /// 帐号 /// </summary> [required(errormessage = "必须输入{0}")] [stringlength(30, minimumlength = 4, errormessage = "{0}长度为{2}-{1}个字符")] [display(name = "帐号")] public string accounts { get; set; } /// <summary> /// 密码 /// </summary> [datatype(datatype.password)] [required(errormessage = "必须输入{0}")] [stringlength(20,minimumlength =6, errormessage = "{0}长度少于{1}个字符")] [display(name = "密码")] public string password { get; set; } } }
右键添加视图
注意:抓图的时候忘记勾上引用脚本库了就抓了,记得勾上。
@model ninesky.web.areas.control.models.addadminviewmodel @using (html.beginform()) { @html.antiforgerytoken() <div class="form-horizontal"> @html.validationsummary(true, "", new { @class = "text-danger" }) <div class="form-group"> @html.labelfor(model => model.accounts, htmlattributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @html.editorfor(model => model.accounts, new { htmlattributes = new { @class = "form-control" } }) @html.validationmessagefor(model => model.accounts, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @html.labelfor(model => model.password, htmlattributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @html.editorfor(model => model.password, new { htmlattributes = new { @class = "form-control" } }) @html.validationmessagefor(model => model.password, "", new { @class = "text-danger" }) </div> </div> </div> } @scripts.render("~/bundles/jqueryval")
在index视图 script脚本区域,“//表格结束”后面添加js代码
//表格结束 //工具栏 //添加按钮 $("#btn_add").click(function () { var adddialog = new bootstrapdialog({ title: "<span class='glyphicon glyphicon-plus'></span>添加管理员", message: function (dialog) { var $message = $('<div></div>'); var pagetoload = dialog.getdata('pagetoload'); $message.load(pagetoload); return $message; }, data: { 'pagetoload': '@url.action("addpartialview")' }, buttons: [{ icon: "glyphicon glyphicon-plus", label: "添加", action: function (dialogitself) { $.post($("form").attr("action"), $("form").serializearray(), function (data) { if (data.code == 1) { bootstrapdialog.show({ message: data.message, buttons: [{ icon: "glyphicon glyphicon-ok", label: "确定", action: function (dialogitself) { $table.bootstraptable("refresh"); dialogitself.close(); adddialog.close(); } }] }); } else bootstrapdialog.alert(data.message); }, "json"); $("form").validate(); } }, { icon: "glyphicon glyphicon-remove", label: "关闭", action: function (dialogitself) { dialogitself.close(); } }] }); adddialog.open(); }); //添加按钮结束
3、删除管理员
考虑到批量删除,上次写administratormanager没有写批量删除方法,这次补上。
打开ninesky.core/administratormanager.cs, 添加如下代码
/// <summary> /// 删除【批量】返回值code:1-成功,2-部分删除,0-失败 /// </summary> /// <param name="administratoridlist"></param> /// <returns></returns> public response delete(list<int> administratoridlist) { response _resp = new response(); int _totaldel = administratoridlist.count; int _totaladmin = count(); foreach (int i in administratoridlist) { if (_totaladmin > 1) { base.repository.delete(new administrator() { administratorid = i }, false); _totaladmin--; } else _resp.message = "最少需保留1名管理员"; } _resp.data = base.repository.save(); if(_resp.data == _totaldel) { _resp.code = 1; _resp.message = "成功删除" + _resp.data + "名管理员"; } else if (_resp.data > 0) { _resp.code = 2; _resp.message = "成功删除" + _resp.data + "名管理员"; } else { _resp.code = 0; _resp.message = "删除失败"; } return _resp; }
另外要修改一下ninesky.datalibrary.repository的删除public int delete(t entity, bool issave)代码将remove方式 改为attach,不然会出错。
/// <summary> /// 删除实体 /// </summary> /// <param name="entity">实体</param> /// <param name="issave">是否立即保存</param> /// <returns>在“issave”为true时返回受影响的对象的数目,为false时直接返回0</returns> public int delete(t entity, bool issave) { dbcontext.set<t>().attach(entity); dbcontext.entry<t>(entity).state = entitystate.deleted; return issave ? dbcontext.savechanges() : 0; }
打开admincontroller 添加deletejson(list<int> ids)方法
// <summary> /// 删除 /// response.code:1-成功,2-部分删除,0-失败 /// response.data:删除的数量 /// </summary> /// <returns></returns> [httppost] public jsonresult deletejson(list<int> ids) { int _total = ids.count(); response _res = new core.types.response(); int _currentadminid = int.parse(session["adminid"].tostring()); if (ids.contains(_currentadminid)) { ids.remove(_currentadminid); } _res = adminmanager.delete(ids); if(_res.code==1&& _res.data < _total) { _res.code = 2; _res.message = "共提交删除"+_total+"名管理员,实际删除"+_res.data+"名管理员。\n原因:不能删除当前登录的账号"; } else if(_res.code ==2) { _res.message = "共提交删除" + _total + "名管理员,实际删除" + _res.data + "名管理员。"; } return json(_res); }
在index视图 script脚本区域,“//添加按钮结束”后面添加删除js代码
//添加按钮结束 //删除按钮 $("#btn_del").click(function () { var selected = $table.bootstraptable('getselections'); if ($(selected).length > 0) { bootstrapdialog.confirm("确定删除选中的" + $(selected).length + "位管理员", function (result) { if (result) { var ids = new array($(selected).length); $.each(selected, function (index, value) { ids[index] = value.administratorid; }); $.post("@url.action("deletejson","admin")", { ids: ids }, function (data) { if (data.code != 0) { bootstrapdialog.show({ message: data.message, buttons: [{ icon: "glyphicon glyphicon-ok", label: "确定", action: function (dialogitself) { $table.bootstraptable("refresh"); dialogitself.close(); } }] }); } else bootstrapdialog.alert(data.message); }, "json"); } }); } else bootstrapdialog.warning("请选择要删除的行"); }); //删除按钮结束
4、重置密码
在admincontroller中 添加resetpassword(int id)方法。方法中将密码重置为ninesky。
/// <summary> /// 重置密码【ninesky】 /// </summary> /// <param name="id">管理员id</param> /// <returns></returns> [httppost] public jsonresult resetpassword(int id) { string _password = "ninesky"; response _resp = adminmanager.changepassword(id, security.sha256(_password)); if (_resp.code == 1) _resp.message = "密码重置为:" + _password; return json(_resp); }
在添加script代码中表格代码段可以看到,这里通过 连接的onclick调用resetpassword方法,所以resetpassword方法要放在表格生成前面,不然会出现 方法未定义的错误。
这里把代码放到$(document).ready的前面。
<script type="text/javascript"> //重置密码 function resetpassword(id, accounts) { bootstrapdialog.confirm("确定重置" + accounts + "的密码", function (result) { if (result) { $.post("@url.action("resetpassword", "admin")", { id: id }, function (data) { bootstrapdialog.alert(data.message); }, "json"); } }); }; //重置密码结束 $(document).ready(function () { //表格
5、修改管理员密码
在在admincontroller中 添加myinfo()方法。
/// <summary> /// 我的资料 /// </summary> /// <returns></returns> public actionresult myinfo() { return view(adminmanager.find(session["accounts"].tostring())); }
右键添加视图
@model ninesky.core.administrator @{ viewbag.title = "我的资料"; } @section sidenav{@html.partial("sidenavpartialview")} <ol class="breadcrumb"> <li><span class="glyphicon glyphicon-home"></span> @html.actionlink("首页", "index", "home")</li> <li>@html.actionlink("管理员", "index", "admin")</li> <li class="active">我的资料</li> </ol> @html.raw(viewbag.message) @using (html.beginform()) { @html.antiforgerytoken() <div class="form-horizontal"> @html.validationsummary(true, "", new { @class = "text-danger" }) <div class="form-group"> @html.labelfor(model => model.accounts, htmlattributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @html.displaytextfor(model => model.accounts) </div> </div> <div class="form-group"> @html.labelfor(model => model.password, htmlattributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @html.editorfor(model => model.password, new { htmlattributes = new { @class = "form-control" } }) @html.validationmessagefor(model => model.password, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @html.labelfor(model => model.loginip, htmlattributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @html.displaytextfor(model => model.loginip) </div> </div> <div class="form-group"> @html.labelfor(model => model.logintime, htmlattributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @html.displaytextfor(model => model.logintime) </div> </div> <div class="form-group"> @html.labelfor(model => model.createtime, htmlattributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @html.displaytextfor(model => model.createtime) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="保存" class="btn btn-default" /> </div> </div> </div> } @section scripts { @scripts.render("~/bundles/jqueryval") }
在在admincontroller中 添加处理方法myinfo(formcollection form)方法。
[validateantiforgerytoken] [httppost] public actionresult myinfo(formcollection form) { var _admin = adminmanager.find(session["accounts"].tostring()); if (_admin.password != form["password"]) { _admin.password = security.sha256(form["password"]); var _resp = adminmanager.changepassword(_admin.administratorid, _admin.password); if(_resp.code ==1) viewbag.message = "<div class=\"alert alert-success\" role=\"alert\"><span class=\"glyphicon glyphicon-ok\"></span>修改密码成功!</div>"; else viewbag.message = "<div class=\"alert alert-danger\" role=\"alert\"><span class=\"glyphicon glyphicon-remove\"></span>修改密码失败!</div>"; } return view(_admin); }
==========================================================
管理员功能到此写完。感慨一下:时间太少,熬夜到凌晨真不容易!
代码见:https://ninesky.codeplex.com/sourcecontrol/latest
代码下载: 点击source code 点击download下载源文件。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: WinForm中的登录实现
下一篇: Java教程各种接口的介绍