一、安裝插件。
展示層前端框架以Bootstrap為主,因為Bootstrap的js功能較弱,這里添加一些插件作補充。其實很多js插件可以通過NuGet安裝,只是NuGet安裝時添加的內(nèi)容較多,不如自己復(fù)制來的干凈,所以這里所有的插件都是下載然后復(fù)制到項目中。
1、Bootstrap 3 Datepicker 4.17.37
網(wǎng)址:https://eonasdan.github.io/bootstrap-datetimepicker/
下載并解壓壓縮包->將bootstrap-datetimepicker.js和bootstrap-datetimepicker.min.js復(fù)制到Ninesy.Web項目的Scripts文件夾,將bootstrap-datetimepicker.css和bootstrap-datetimepicker.min.css復(fù)制到Content文件夾。
2、bootstrap-dialog 3.3.4.1
網(wǎng)址:https://github.com/nakupanda/bootstrap3-dialog
下載并解壓壓縮包->將.js復(fù)制到Ninesy.Web項目的Scripts文件夾,將.css復(fù)制到Content文件夾。
3、bootstrap-select 1.10.0
網(wǎng)址:http://silviomoreto.github.io/bootstrap-select/
下載并解壓壓縮包->將bootstrap-select.js復(fù)制到Ninesy.Web項目的Scripts文件夾,和defaults-zh_CN.js重命名為bootstrap-select-zh_CN.js復(fù)制到Ninesy.Web項目的Scripts文件夾,將bootstrap-select.css、bootstrap-select.css.map和bootstrap-select.min.css復(fù)制到Content文件夾。
4、bootstrap-table 1.10.1
網(wǎng)址:http://bootstrap-table.wenzhixin.net.cn/
下載并解壓壓縮包->將bootstrap-table.js和bootstrap-table-zh-CN.js復(fù)制到Ninesy.Web項目的Scripts文件夾,將bootstrap-table.css復(fù)制到Content文件夾。
5、Bootstrap TreeView 1.2.0
網(wǎng)址:https://github.com/jonmiles/bootstrap-treeview
下載并解壓壓縮包->將bootstrap-treeview.js復(fù)制到Ninesy.Web項目的Scripts文件夾,將bootstrap-treeview.css復(fù)制到Content文件夾。
6、twbs-pagination
網(wǎng)址:http://esimakin.github.io/twbs-pagination/
下載并解壓壓縮包->將jquery.twbsPagination.js和jquery.twbsPagination.min.js復(fù)制到Ninesy.Web項目的Scripts文件夾。
7、對js和css進行捆綁和壓縮
打開Ninesky.Web->App_Start->BundleConfig.cs。添加紅框內(nèi)的代碼。
二、獲取ModelState錯誤信息的方法
在項目中有些內(nèi)容是通過AJAX方法提交,如果提交時客戶端沒有進行驗證,在服務(wù)器端進行驗證時會將錯誤信息保存在ModelState中,這里需要寫一個方法來獲取ModelState的錯誤信息,以便反饋給客戶端。
1、Ninesk.Web【右鍵】->添加->類,輸入類名General。
引用命名空間using System.Web.Mvc和System.Text。
添加靜態(tài)方法GetModelErrorString(),該方法用來獲取模型的錯誤字符串。
using System.Linq;
using System.Text;
using System.Web.Mvc;
namespace Ninesky.Web
{
/// summary>
/// 通用類
/// /summary>
public class General
{
/// summary>
/// 獲取模型錯誤
/// /summary>
/// param name="modelState">模型狀態(tài)/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 - 系統(tǒng)管理/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 系統(tǒng)管理", "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> 欄目設(shè)置/a>/li>
li>a>span class="glyphicon glyphicon-cog">/span> 網(wǎng)站設(shè)置/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>copy; Ninesky v0.1 BASE BY 洞庭夕照 http://mzwhj.cnblogs.com/p>
/footer>
/div>
/body>
/html>
反正效果就是這個樣子了。
三、功能實現(xiàn)
按照設(shè)想,要在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")
}
添加側(cè)欄導(dǎo)航視圖
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: "創(chuàng)建時間", 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>" } }
]
});
//表格結(jié)束
});
/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腳本區(qū)域,“//表格結(jié)束”后面添加js代碼
//表格結(jié)束
//工具欄
//添加按鈕
$("#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: "關(guān)閉",
action: function (dialogItself) {
dialogItself.close();
}
}]
});
addDialog.open();
});
//添加按鈕結(jié)束
3、刪除管理員
考慮到批量刪除,上次寫AdministratorManager沒有寫批量刪除方法,這次補上。
打開Ninesky.Core/AdministratorManager.cs, 添加如下代碼
/// summary>
/// 刪除【批量】返回值Code:1-成功,2-部分刪除,0-失敗
/// /summary>
/// param name="administratorIDList">/param>
/// returns>/returns>
public Response Delete(Listint> 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時返回受影響的對象的數(shù)目,為False時直接返回0/returns>
public int Delete(T entity, bool isSave)
{
DbContext.SetT>().Attach(entity);
DbContext.EntryT>(entity).State = EntityState.Deleted;
return isSave ? DbContext.SaveChanges() : 0;
}
打開AdminController 添加DeleteJson(Listint> ids)方法
// summary>
/// 刪除
/// Response.Code:1-成功,2-部分刪除,0-失敗
/// Response.Data:刪除的數(shù)量
/// /summary>
/// returns>/returns>
[HttpPost]
public JsonResult DeleteJson(Listint> 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腳本區(qū)域,“//添加按鈕結(jié)束”后面添加刪除js代碼
//添加按鈕結(jié)束
//刪除按鈕
$("#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("請選擇要刪除的行");
});
//刪除按鈕結(jié)束
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調(diào)用ResetPassword方法,所以ResetPassword方法要放在表格生成前面,不然會出現(xiàn) 方法未定義的錯誤。
這里把代碼放到$(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");
}
});
};
//重置密碼結(jié)束
$(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
代碼下載:https://ninesky.codeplex.com 點擊SOURCE CODE 點擊Download下載源文件。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
您可能感興趣的文章:- ASP.NET MVC5網(wǎng)站開發(fā)用戶修改資料和密碼(六)
- Asp.NEt郵箱驗證修改密碼通過郵箱找回密碼功能