AdminLTE 一個基於 bootstrap 的輕量級後臺模板,這個前端界面個人感覺很清爽,對於一個大後端的我來說,可以減少較多的時間去承擔前端的工作但又必須去獨立去完成一個後臺系統開發的任務,並且,文檔還算比較齊全,對著demo可以完成一個基本的前端框架搭建了。大家如有更為好看的又方便後端上手的 ...
AdminLTE
一個基於 bootstrap 的輕量級後臺模板,這個前端界面個人感覺很清爽,對於一個大後端的我來說,可以減少較多的時間去承擔前端的工作但又必須去獨立去完成一個後臺系統開發的任務,並且,文檔還算比較齊全,對著demo可以完成一個基本的前端框架搭建了。大家如有更為好看的又方便後端上手的前端框架,也可以在留言區分享一下唄。
AdminLTE 文檔
線上中文Demo:http://adminlte.la998.com/
線上中文文檔:http://adminlte.la998.com/documentation/index.html
Github:https://github.com/almasaeed2010/AdminLTE/releases
AdminLTE 佈局
AdminLTE依賴於兩個主要框架:JQ和Bootstrap,其他插件可以按需增加。
從文檔可以知道,使用AdminLTE主要有四個部分:
- 包裝
.wrapper
。包裹整個網站的div。 - 主標題
.main-header
。包含徽標和導航欄。 - 邊欄
.sidebar-wrapper
。包含用戶面板和側邊欄菜單。 - 內容
.content-wrapper
。包含頁眉和內容。
在文檔中,可以找到下載地址,本文示例是使用最新的版本V2.4.5。
Asp.Net Core Razor
新建項目Asp.net Core Web應用程式,預設就是Razor Pages,然後添加相應的模塊,如圖:本文使用的SDK版本為:dotNet Core 2.1。
First
在Asp.Net Core項目中,引用AdminLTE,在wwwroot僅添加如圖三個文件夾即可:
- bower_components 基本組件。
- dist adminlte的主要文件。
- plugins 其他插件。
Second
在_Layout.cshtml文件中添加引入相關文件:
<!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> <!-- Bootstrap 3.3.7 --> <link rel="stylesheet" href="~/adminlte/bower_components/bootstrap/dist/css/bootstrap.min.css"> <!-- Font Awesome --> <link rel="stylesheet" href="~/adminlte/bower_components/font-awesome/css/font-awesome.min.css"> <!-- Ionicons --> <link href="~/adminlte/bower_components/Ionicons/css/ionicons.min.css" rel="stylesheet" /> <!-- Theme style --> <link rel="stylesheet" href="~/adminlte/dist/css/AdminLTE.min.css"> <!-- AdminLTE Skins. Choose a skin from the css/skins folder instead of downloading all of them to reduce the load. --> <link rel="stylesheet" href="~/adminlte/dist/css/skins/_all-skins.min.css"> <!-- Pace style --> <link href="~/adminlte/plugins/pace/pace.min.css" rel="stylesheet" /> <link href="~/css/common.css" rel="stylesheet" /> <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script> <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> <![endif]--> <!-- Google Font --> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic">
在body中,添加js:
<!-- jQuery 3 --> <script src="~/adminlte/bower_components/jquery/dist/jquery.min.js"></script> <!-- jQuery UI 1.11.4 --> <script src="~/adminlte/bower_components/jquery-ui/jquery-ui.min.js"></script> <!-- Resolve conflict in jQuery UI tooltip with Bootstrap tooltip --> <script> $.widget.bridge('uibutton', $.ui.button); </script> <!-- Bootstrap 3.3.7 --> <script src="~/adminlte/bower_components/bootstrap/dist/js/bootstrap.min.js"></script> <!-- Slimscroll --> <script src="~/adminlte/bower_components/jquery-slimscroll/jquery.slimscroll.min.js"></script> <!-- FastClick --> <script src="~/adminlte/bower_components/fastclick/lib/fastclick.js"></script> <!-- AdminLTE App --> <script src="~/adminlte/dist/js/adminlte.min.js"></script> <!-- Skin --> <script type="text/javascript" src="~/adminlte/dist/js/sidebarskins.js" charset="gbk"></script>
sidebarskins.js是本人漢化的側邊欄皮膚
坑1:一般情況,發現某些功能運行不起來的都是引用不正確導致的,這個要耐心對照好Demo來檢查,或者直接用Demo來修改吧。
Third
開始使用AdminLTE,這裡直接貼圖吧,圖上有註釋和代碼摺疊比較直觀點,重要的地方在放代碼。
最後就可以運行項目來預覽一下效果了:
都使用到bootstrap,必須得看看移動端的效果,還不錯吧。
坑2:需要註意的是,點擊這個小圖標可以實現左側邊欄收縮展開的功能,當只有側邊欄可以正常收縮展開但Logo無動於衷的時候,你可能是少了【sidebar-mini】樣式和【logo-mini】logo小圖的引用
添加一個登陸
登錄界面寫得比較簡約,我比較喜歡這種風格。前端寫得不多,所以還得前端的女票指導一二,不然就是後端的設計的界面了,你懂的。
在Pages文件夾中,添加一個Razor界面,並擼好界面代碼:
@page @model AdminLTE.Net.Web.Pages.LoginModel @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>登錄 - AdminLTE.Net.Web</title> <meta name="developer" content="EminemJK"> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" /> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap-theme.min.css" rel="stylesheet" /> <link href="~/adminlte/dist/css/AdminLTE.min.css" rel="stylesheet" /> <link href="~/css/login.css" rel="stylesheet" /> </head> <body> <div> <div class="row"> <div class="loginHeader"> <img class="logo-img" src="~/images/banana_logo.ico" /> <h1 class="logo-name">Banana</h1> <div class="clearfix"></div> </div> </div> <div class="row login-bg"> <div class="loginInBox"> @if (!string.IsNullOrEmpty(Model.Message)) { <p class="login-box-msg" style="color:red">@Model.Message</p> } else { <p class="login-box-msg">Sign in to start your session</p> } <form method="post"> <div class="form-group has-feedback"> <input type="text" class="form-control" asp-for="Login.UserName"> <span class="glyphicon glyphicon-user form-control-feedback"></span> </div> <div class="form-group has-feedback"> <input type="password" class="form-control" asp-for="Login.Password"> <span class="glyphicon glyphicon-lock form-control-feedback"></span> </div> <button type="submit" class="btn btn-primary btn-block btn-flat login-btn">Sign In</button> </form> </div> </div> </div> <footer class="footer"> <strong>Copyright © 2018 <a href="http://www.cnblogs.com/EminemJK/">EminemJK</a>.</strong> All rights reserved. </footer> </body> </html>View Code
在Startup中引入Authentication身份驗證:
services.AddAuthentication(CookieService.AuthenticationScheme) .AddCookie(CookieService.AuthenticationScheme, o => { o.LoginPath = new PathString("/Login"); });
Configure方法內調用
app.UseAuthentication();
在Login.cshtml.cs中增加一個OnPostAsync的方法:
[HttpPost] public async Task<IActionResult> OnPostAsync() { if (!ModelState.IsValid) { Message = ModelState.Root.Errors[0].ErrorMessage; } else { var user = userService.Login(Login.UserName, Login.Password); if (user != null) { VUserModel model = new VUserModel() { Id = user.Id, UserName = user.UserName, Time = DateTime.Now }; var identity = new ClaimsIdentity(CookieService.AuthenticationScheme); identity.AddClaim(new Claim(ClaimTypes.Sid, CookieService.GetDesEncrypt(model))); await HttpContext.SignInAsync(CookieService.AuthenticationScheme, new ClaimsPrincipal(identity), new AuthenticationProperties() { //記住我 IsPersistent = true, //過期時間 ExpiresUtc = DateTimeOffset.Now.Add(TimeSpan.FromMinutes(30)) }); return RedirectToPage("./Index"); } Message = "登錄失敗,用戶名密碼不正確。"; } return Page(); }
userService和CookieService都是在業務層定義的,gayhub會在文章末尾。
在.Net Core Razor中,xx.cshtml.cs中預設觸發的是Get和Post方法,
- OnGet
- OnPost
- OnGetAsync
- OnPostAsync
如果是需要自定義的,舉個慄子,定義為:OnPostLoginAsync,然後在Form表單提交的【按鈕】增加asp-page-handler="Login",詳細的推薦大家閱讀這篇文章:ASP.NET Core - Razor頁面之Handlers處理方法。
接著,然後再Index和需要身份驗證的地方都加上Authorize特性即可:
namespace AdminLTE.Net.Web.Pages { [Authorize(AuthenticationSchemes = CookieService.AuthenticationScheme)] public class IndexModel : BasePageModel { public void OnGet() { } } }
踩坑
一、Ajax Post請求,HttpCore 400
function uploadfile() { var file = $("#input-userimg")[0].files[0]; var data = new FormData(); data.append('file', file); $.ajax({ url: "/Account/UserList?handler=Upload", type: 'POST', data: data, contentType: false, processData: false, success: function (returndata) { $("#user-img").attr('src', returndata.path); }, error: function (a, b, c) { alert('上傳失敗') } }); };
折騰許久,原因是Razor被設計為可以自動防止跨站請求偽造(CSRF / XSRF)攻擊。你不必編寫任何其他代碼。Razor頁面中自動包含防偽令牌生成和驗證。這裡請求失敗,是因為POST沒有提交AntiForgeryToken。
解決方法:
1.增加"XSRF-TOKEN"標識到框架中
//增加了"XSRF-TOKEN"標識,值為表單自動生成的防偽標記 services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
2.頁面*.cshtml頭部加上
@Html.AntiForgeryToken()
3.ajax引入
function uploadfile() { var file = $("#input-userimg")[0].files[0]; var data = new FormData(); data.append('file', file); $.ajax({ url: "/Account/UserList?handler=Upload", type: 'POST', data: data, contentType: false, processData: false, beforeSend: function (xhr) { xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val()); }, success: function (returndata) { $("#user-img").attr('src', returndata.path); }, error: function (a, b, c) { alert('上傳失敗') } }); };
然後既可以正常訪問Handler
二、DataTables參數實例加說明
var table = $('#userListTable').DataTable({ "processing": true, "serverSide": true, "ajax": function (data, callback, settings) { //data的參數請參考: https://segmentfault.com/a/1190000004478726 var param = {}; param.draw = data.draw; param.pageNum = (data.start / data.length) + 1; param.pageSize = data.length; param.sex = $('#select-sex option:selected').val(); param.phone = $('#input-phone').val(); param.name = $('#input-name').val(); $.ajax({ type: "GET", data: param, url: "/Account/UserList?handler=UserPage", dataType: "json", success: function (data) { //成功後回調自動渲染 callback(data); } }); }, 'columns': [ { 'data': 'id' }, { 'data': 'name' }, { 'data': 'userName' }, { 'data': 'sexString' }, { 'data': 'phone' }, { 'data': 'createTime' }, { 'data': 'enableString', 'render': function (data, type, row) { if (row.enable == 1) return '<span style="color:#19be6b" >' + row.enableString + '</span>'; else return '<span style="color:#ed3f14" >' + row.enableString + '</span>'; } }, { 'data': null, 'render': function (data, type, row) { return '<a id="btn-edit" class="btn btn-success btn-xs" title="編輯" onClick=btn_edit(' + row.id + ')><i class="fa fa-edit"></i>編輯</a> ' + '<a id="btn-edit" class="btn btn-danger btn-xs" title="刪除" onClick=btn_edit(' + row.id + ')><i class="fa fa-trash " title="刪除" style="cursor:pointer"></i>刪除</a>'; } }, ], //datatable設置參數 http://www.datatables.club/reference/option/ 'paging': true, //啟用分頁 'lengthChange': true, //設置每頁數量 'searching': false, 'ordering': false, 'info': true, 'autoWidth': false, //設置中文 'language': { "sProcessing": "玩命載入中...", "sLengthMenu": "每頁顯示顯示 _MENU_", "sZeroRecords": "沒有匹配結果", "sInfo": "顯示第 _START_ 至 _END_ 項結果,共 _TOTAL_ 項", "sInfoEmpty": "顯示第 0 至 0 項結果,共 0 項", "sInfoFiltered": "(由 _MAX_ 項結果過濾)", "sInfoPostFix": "", "sSearch": "搜索:", "sUrl": "", "sEmptyTable": "表中數據為空", "sLoadingRecords": "玩命載入中...", "sInfoThousands": ",", "oPaginate": { "sFirst": "首頁", "sPrevious": "上頁", "sNext": "下頁", "sLast": "末頁" }, "oAria": { "sSortAscending": ": 以升序排列此列", "sSortDescending": ": 以降序排列此列" } } });View Code
Last
附上這些天來的成果,發現,我並不適合寫前端,太醜了,哈哈。
最後,Show me the code。
Github:https://github.com/EminemJK/AdminLTE.Net.Web
Banana
Banana Github:https://github.com/EminemJK/Banana
Demo中會使用到這兩個個人封裝的組件:
Banana.Uow是基於Dapper封裝的工作單元和倉儲;
Banana.Utility是常用的工具類,有Redis,加解密,拼音等等;
歡迎大家在Issues中提出意見,大家共同進步。