系列目錄javascript
系統須要愈來愈自動化,咱們須要引入日誌記錄和異常捕獲
管理員的操做記錄須要被記錄,看出哪些模塊是頻繁操做,分析哪些是沒必要要的功能,哪些是須要被優化的。
系統的異常須要被捕獲,而不是將系統出錯顯示出來給用戶就不了了知。咱們須要異常日誌不斷改進系統。
咱們老說用戶,咱們尚未用戶權限的表,因此咱們在Home中先加入一個虛擬用戶吧!html
首先咱們建立一個用戶類AccountModel放在App.Models下的Sys文件夾下java
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace App.Models.Sys { public class AccountModel { public string Id { get; set; } public string TrueName { get; set; } } }
在HomeController或者AccountController插入代碼jquery
AccountModel account = new AccountModel(); account.Id = "admin"; account.TrueName = "admin"; Session["Account"] = account;
下面將帶來系統日誌的記錄,主要記錄管理員的增、刪、改等操做的成功與失敗的異常記錄
日誌插件有著名的log4net,能夠輸出多種格式,如文本,xml,數據庫等,咱們沒有必要作到這麼強大,咱們只作符合系統的就能夠了,記錄到數據庫,方便作統計等操
做,咱們什麼時候何地記錄日誌?數據庫
首先建立數據庫存放表:SysLogjson
USE DB GO /****** Object: Table [dbo].[SysLog] Script Date: 11/20/2013 21:13:38 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [dbo].[SysLog]( [Id] [varchar](50) NOT NULL, --GUID [Operator] [varchar](50) NULL,--操做人 [Message] [varchar](500) NULL,--操做信息 [Result] [varchar](20) NULL,--結果 [Type] [varchar](20) NULL,--操做類型 [Module] [varchar](20) NULL,--操做模塊 [CreateTime] [datetime] NULL,--操做事件 CONSTRAINT [PK_SysLog] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET ANSI_PADDING OFF GO
EF更新模型,建立SysLogModel類放在App.Models下的Sys文件夾下mvc
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel.DataAnnotations; namespace App.Models.Sys { public class SysLogModel { [Display(Name = "ID")] public string Id { get; set; } [Display(Name = "操做人")] public string Operator { get; set; } [Display(Name = "信息")] public string Message { get; set; } [Display(Name = "結果")] public string Result { get; set; } [Display(Name = "類型")] public string Type { get; set; } [Display(Name = "模塊")] public string Module { get; set; } [Display(Name = "建立時間")] public DateTime? CreateTime { get; set; } } }
建立SysLog的BLL層和DAL層ide
using System; using App.Models; using System.Linq; namespace App.IDAL { public interface ISysLogRepository { int Create(SysLog entity); void Delete(DBContainer db, string[] deleteCollection); IQueryable<SysLog> GetList(DBContainer db); SysLog GetById(string id); } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using App.Models; using App.IDAL; namespace App.DAL { public class SysLogRepository:IDisposable, ISysLogRepository { /// <summary> /// 獲取集合 /// </summary> /// <param name="db">數據庫</param> /// <returns>集合</returns> public IQueryable<SysLog> GetList(DBContainer db) { IQueryable<SysLog> list = db.SysLog.AsQueryable(); return list; } /// <summary> /// 建立一個對象 /// </summary> /// <param name="db">數據庫</param> /// <param name="entity">實體</param> public int Create(SysLog entity) { using (DBContainer db = new DBContainer()) { db.SysLog.AddObject(entity); return db.SaveChanges(); } } /// <summary> /// 刪除對象集合 /// </summary> /// <param name="db">數據庫</param> /// <param name="deleteCollection">集合</param> public void Delete(DBContainer db, string[] deleteCollection) { IQueryable<SysLog> collection = from f in db.SysLog where deleteCollection.Contains(f.Id) select f; foreach (var deleteItem in collection) { db.SysLog.DeleteObject(deleteItem); } } /// <summary> /// 根據ID獲取一個實體 /// </summary> /// <param name="id"></param> /// <returns></returns> public SysLog GetById(string id) { using (DBContainer db = new DBContainer()) { return db.SysLog.SingleOrDefault(a => a.Id == id); } } public void Dispose() { } } }
using System; using System.Collections.Generic; using App.Common; using App.Models; namespace App.IBLL { public interface ISysLogBLL { List<SysLog> GetList(ref GridPager pager,string queryStr); SysLog GetById(string id); } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Practices.Unity; using App.IDAL; using App.Common; using App.Models.Sys; using App.Models; using App.IBLL; namespace App.BLL { public class SysLogBLL: ISysLogBLL { [Dependency] public ISysLogRepository logRepository { get; set; } public List<SysLog> GetList(ref GridPager pager, string queryStr) { DBContainer db = new DBContainer(); List<SysLog> query = null; IQueryable<SysLog> list = logRepository.GetList(db); if (!string.IsNullOrWhiteSpace(queryStr)) { list = list.Where(a => a.Message.Contains(queryStr) || a.Module.Contains(queryStr)); pager.totalRows = list.Count(); } else { pager.totalRows = list.Count(); } if (pager.order == "desc") { query = list.OrderByDescending(c => c.CreateTime).Skip((pager.page - 1) * pager.rows).Take(pager.rows).ToList(); } else { query = list.OrderBy(c => c.CreateTime).Skip((pager.page - 1) * pager.rows).Take(pager.rows).ToList(); } return query; } public SysLog GetById(string id) { return logRepository.GetById(id); } } }
建立SysLog的Controllerpost
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using App.Common; using App.Models; using Microsoft.Practices.Unity; using App.IBLL; using App.Models.Sys; namespace App.Admin.Controllers { public class SysLogController : Controller { // // GET: /SysLog/ [Dependency] public ISysLogBLL logBLL { get; set; } public ActionResult Index() { return View(); } public JsonResult GetList(GridPager pager, string queryStr) { List<SysLog> list = logBLL.GetList(ref pager, queryStr); var json = new { total = pager.totalRows, rows = (from r in list select new SysLogModel() { Id= r.Id, Operator= r.Operator, Message= r.Message, Result= r.Result, Type= r.Type, Module= r.Module, CreateTime= r.CreateTime }).ToArray() }; return Json(json); } #region 詳細 public ActionResult Details(string id) { SysLog entity = logBLL.GetById(id); SysLogModel info = new SysLogModel() { Id = entity.Id, Operator = entity.Operator, Message = entity.Message, Result = entity.Result, Type = entity.Type, Module = entity.Module, CreateTime = entity.CreateTime, }; return View(info); } #endregion } }
建立SysLog的Index視圖和Details視圖,咱們暫時提示Index和Details,刪除功能童鞋們本身擴展,咱們有樣例程序SysSample嘛,什麼都是必然的了性能
@using App.Admin; @using App.Common; @using App.Models.Sys; @{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Index_Layout.cshtml"; } <script src="~/Scripts/jquery.easyui.plus.js"></script> <div class="mvctool"> <input id="txtQuery" type="text" class="searchText"/> <a id="btnQuery" style="float: left;" class="l-btn l-btn-plain"><span class="l-btn-left"><span class="l-btn-text icon-search" style="padding-left: 20px;">查詢</span></span></a><div class="datagrid-btn-separator"></div> <a id="btnDetails" style="float: left;" class="l-btn l-btn-plain"><span class="l-btn-left"><span class="l-btn-text icon-details" style="padding-left: 20px;">詳細</span></span></a><div class="datagrid-btn-separator"></div> <a id="btnDelete" style="float: left;" class="l-btn l-btn-plain"><span class="l-btn-left"><span class="l-btn-text icon-remove" style="padding-left: 20px;">刪除</span></span></a> </div> <table id="List"></table> <div id="Pager"></div> <div id="modalwindow" class="easyui-window" data-options="modal:true,closed:true,minimizable:false,shadow:false"></div> @*Jqgrid*@ <script type="text/javascript"> //ifram 返回 function frameReturnByClose() { $("#modalwindow").window('close'); } function frameReturnByReload(flag) { if (flag) $("#List").datagrid('load'); else $("#List").datagrid('reload'); } function frameReturnByMes(mes) { $.messageBox5s('提示', mes); } $(function () { $('#List').datagrid({ url: '/SysLog/GetList', width: $(window).width() - 10, methord: 'post', height: $(window).height() - 35, fitColumns: true, sortName: 'Id', sortOrder: 'desc', idField: 'Id', pageSize: 15, pageList: [15, 20, 30, 40, 50], pagination: true, striped: true, //奇偶行是否區分 singleSelect: true,//單選模式 columns: [[ { field: 'Id', title: 'ID', width: 40, hidden: true }, { field: 'Operator', title: '操做人', width: 40 }, { field: 'Message', title: '信息', width: 280 }, { field: 'Result', title: '結果', width: 40, align: 'center' }, { field: 'Type', title: '類型', width: 40, align: 'center' }, { field: 'Module', title: '模塊', width: 60, align: 'center' }, { field: 'CreateTime', title: '添加時間', width: 65, align: 'center' } ]] }); }); </script> @*operation*@ <script type="text/javascript"> $(function () { $("#btnDetails").click(function () { var row = $('#List').datagrid('getSelected'); if (row != null) { $("#modalwindow").html("<iframe width='100%' height='98%' frameborder='0' src='/SysLog/Details?id=" + row.Id + "'></iframe>"); $("#modalwindow").window({ title: '詳細', width: 500, height: 400, iconCls: 'icon-details' }).window('open'); } else { $.messageBox5s('提示', '請選擇要操做的行!'); } }); $("#btnQuery").click(function () { var queryStr = $("#txtQuery").val(); //若是查詢條件爲空默認查詢所有 if (queryStr == null) { queryStr = "%"; } $('#List').datagrid({ url: '/SysLog/GetList?queryStr=' + encodeURI(queryStr)}); }); }); </script>
@model App.Models.Sys.SysLogModel @using App.Common; @using App.Admin; @using App.Models.Sys; @{ ViewBag.Title = "Details"; Layout = "~/Views/Shared/_Index_LayoutEdit.cshtml"; } <script type="text/javascript"> $(function () { $("#btnReturn").click(function () { window.parent.frameReturnByClose(); }); }); </script> <div class="mvctool bgb"> <a id="btnReturn" style="float: left;" class="l-btn l-btn-plain"><span class="l-btn-left"><span class="l-btn-text icon-return" style="padding-left: 20px;">返回</span></span></a> </div> @using (Html.BeginForm()) { <table class="form_table setinput355"> <tbody> <tr> <th> @Html.LabelFor(model => model.Operator) </th> <td> @Html.EditorFor(model => model.Operator) </td> </tr> <tr> <th> @Html.LabelFor(model => model.Message) </th> <td> @Html.TextAreaFor(model => model.Message, new { @style="height:100px;"}) </td> </tr> <tr> <th> @Html.LabelFor(model => model.Result) </th> <td> @Html.EditorFor(model => model.Result) </td> </tr> <tr> <th> @Html.LabelFor(model => model.Type) </th> <td> @Html.EditorFor(model => model.Type) </td> </tr> <tr> <th> @Html.LabelFor(model => model.Module) </th> <td> @Html.EditorFor(model => model.Module) </td> </tr> <tr> <th> @Html.LabelFor(model => model.CreateTime) </th> <td> @Html.TextBoxFor(model => model.CreateTime) </td> </tr> </tbody> </table> }
有看過前面的童鞋,應該很熟悉這一步很機械化的建立了
你看了不累我都以爲累了,咱們之後會講用T4,咱們自動生成
預覽下效果,你會發現咱們的左邊的菜單欄能夠點出來了。oh yeh...(別忘記注入)
分頁和詳細都沒有問題了。
接下來是是異常的捕獲,咱們在什麼時候處理異常?咱們沒有處理的異常該怎麼辦?咱們處理異常時出現異常怎麼又怎麼辦?反正我是要捕獲到這異常了...、
咱們通常先對數據進行判斷避免捕獲異常,由於try catch會下降程序的性能,咱們通常在業務層捕獲異常,處理邏輯容易致使異常
建立異常存放數據表SysException
USE DB GO /****** Object: Table [dbo].[SysException] Script Date: 11/20/2013 21:17:44 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [dbo].[SysException]( [Id] [varchar](50) NOT NULL, --GUID [HelpLink] [varchar](500) NULL,--幫助連接 [Message] [varchar](500) NULL,--異常信息 [Source] [varchar](500) NULL,--來源 [StackTrace] [text] NULL,--堆棧 [TargetSite] [varchar](500) NULL,--目標頁 [Data] [varchar](500) NULL,--程序集 [CreateTime] [datetime] NULL,--發生時間 CONSTRAINT [PK_SysException] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO SET ANSI_PADDING OFF GO
EF更新模型,建立SysExceptionModel類放在App.Models下的Sys文件夾下
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel.DataAnnotations; namespace App.Models.Sys { /// <summary> /// 異常處理類 /// </summary> public class SysExceptionModel { [Display(Name = "ID")] public string Id { get; set; } [Display(Name = "幫助連接")] public string HelpLink { get; set; } [Display(Name = "錯誤信息")] public string Message { get; set; } [Display(Name = "來源")] public string Source { get; set; } [Display(Name = "堆棧")] public string StackTrace { get; set; } [Display(Name = "目標頁")] public string TargetSite { get; set; } [Display(Name = "程序集")] public string Data { get; set; } [Display(Name = "發生時間")] public DateTime? CreateTime { get; set; } } }
建立SysException的BLL層和DAL層
using System; using App.Models; using System.Linq; namespace App.IDAL { public interface ISysExceptionRepository { int Create(SysException entity); IQueryable<SysException> GetList(DBContainer db); SysException GetById(string id); } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using App.Models; using App.IDAL; namespace App.DAL { public class SysExceptionRepository:IDisposable, ISysExceptionRepository { /// <summary> /// 獲取集合 /// </summary> /// <param name="db">數據庫</param> /// <returns>集合</returns> public IQueryable<SysException> GetList(DBContainer db) { IQueryable<SysException> list = db.SysException.AsQueryable(); return list; } /// <summary> /// 建立一個對象 /// </summary> /// <param name="db">數據庫</param> /// <param name="entity">實體</param> public int Create( SysException entity) { using (DBContainer db = new DBContainer()) { db.SysException.AddObject(entity); return db.SaveChanges(); } } /// <summary> /// 根據ID獲取一個實體 /// </summary> /// <param name="id"></param> /// <returns></returns> public SysException GetById(string id) { using (DBContainer db = new DBContainer()) { return db.SysException.SingleOrDefault(a => a.Id == id); } } public void Dispose() { } } }
using System; using System.Collections.Generic; using App.Common; using App.Models; namespace App.IBLL { public interface ISysExceptionBLL { List<SysException> GetList(ref GridPager pager,string queryStr); SysException GetById(string id); } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Practices.Unity; using App.IDAL; using App.Common; using App.Models.Sys; using App.Models; using App.IBLL; namespace App.BLL { public class SysExceptionBLL: ISysExceptionBLL { [Dependency] public ISysExceptionRepository exceptionRepository { get; set; } public List<SysException> GetList(ref GridPager pager, string queryStr) { DBContainer db = new DBContainer(); List<SysException> query = null; IQueryable<SysException> list = exceptionRepository.GetList(db); if (!string.IsNullOrWhiteSpace(queryStr)) { list = list.Where(a => a.Message.Contains(queryStr)); pager.totalRows = list.Count(); } else { pager.totalRows = list.Count(); } if (pager.order == "desc") { query = list.OrderByDescending(c => c.CreateTime).Skip((pager.page - 1) * pager.rows).Take(pager.rows).ToList(); } else { query = list.OrderBy(c => c.CreateTime).Skip((pager.page - 1) * pager.rows).Take(pager.rows).ToList(); } return query; } public SysException GetById(string id) { return exceptionRepository.GetById(id); } } }
建立SysException的Controller
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Reflection; using System.Text; using App.Common; using App.Models; using App.IBLL; using App.Models.Sys; using Microsoft.Practices.Unity; namespace App.Admin.Controllers { public class SysExceptionController : Controller { // // GET: /SysException/ [Dependency] public ISysExceptionBLL exceptionBLL { get; set; } public ActionResult Index() { return View(); } public JsonResult GetList(GridPager pager, string queryStr) { List<SysException> list = exceptionBLL.GetList(ref pager, queryStr); var json = new { total = pager.totalRows, rows = (from r in list select new SysException() { Id = r.Id, HelpLink =r.HelpLink, Message = r.Message, Source = r.Source, StackTrace = r.StackTrace, TargetSite = r.TargetSite, Data = r.Data, CreateTime = r.CreateTime }).ToArray() }; return Json(json); } #region 詳細 public ActionResult Details(string id) { SysException entity = exceptionBLL.GetById(id); SysExceptionModel info = new SysExceptionModel() { Id = entity.Id, HelpLink = entity.HelpLink, Message = entity.Message, Source = entity.Source, StackTrace = entity.StackTrace, TargetSite = entity.TargetSite, Data = entity.Data, CreateTime = entity.CreateTime, }; return View(info); } #endregion } }
建立SysException的Index視圖和Details視圖
@using App.Admin; @using App.Common; @using App.Models.Sys; @{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Index_Layout.cshtml"; } <script src="~/Scripts/jquery.easyui.plus.js"></script> <div class="mvctool"> <input id="txtQuery" type="text" class="searchText"/> <a id="btnQuery" style="float: left;" class="l-btn l-btn-plain"><span class="l-btn-left"><span class="l-btn-text icon-search" style="padding-left: 20px;">查詢</span></span></a><div class="datagrid-btn-separator"></div> <a id="btnDetails" style="float: left;" class="l-btn l-btn-plain"><span class="l-btn-left"><span class="l-btn-text icon-details" style="padding-left: 20px;">詳細</span></span></a><div class="datagrid-btn-separator"></div> <a id="btnDelete" style="float: left;" class="l-btn l-btn-plain"><span class="l-btn-left"><span class="l-btn-text icon-remove" style="padding-left: 20px;">刪除</span></span></a> </div> <table id="List"></table> <div id="Pager"></div> <div id="modalwindow" class="easyui-window" data-options="modal:true,closed:true,minimizable:false,shadow:false"></div> @*Jqgrid*@ <script type="text/javascript"> $(function () { $('#List').datagrid({ url: '/SysException/GetList', width: $(window).width() - 10, methord: 'post', height: $(window).height() - 35, fitColumns: true, sortName: 'Id', sortOrder: 'desc', idField: 'Id', pageSize: 15, pageList: [15, 20, 30, 40, 50], pagination: true, striped: true, //奇偶行是否區分 singleSelect: true,//單選模式 columns: [[ { field: 'Id', title: 'ID', width: 40, hidden: true }, { field: 'HelpLink', title: '幫助連接', width: 40 }, { field: 'Message', title: '異常信息', width: 200 }, { field: 'Source', title: '來源', width: 140 }, { field: 'StackTrace', title: '堆棧', width: 40, align: 'center' }, { field: 'TargetSite', title: '目標頁', width: 40, align: 'center' }, { field: 'Data', title: '程序集', width: 60, align: 'center' }, { field: 'CreateTime', title: '發生時間', width: 65, align: 'center' } ]] }); }); </script> @*operation*@ <script type="text/javascript"> //ifram 返回 function frameReturnByClose() { $("#modalwindow").window('close'); } $(function () { $("#btnDetails").click(function () { var row = $('#List').datagrid('getSelected'); if (row != null) { $("#modalwindow").html("<iframe width='100%' height='98%' frameborder='0' src='/SysException/Details?id=" + row.Id + "'></iframe>"); $("#modalwindow").window({ title: '詳細', width: 700, height: 400, iconCls: 'icon-details' }).window('open'); } else { $.messageBox5s('提示', '請選擇要操做的行!'); } }); $("#btnQuery").click(function () { var queryStr = $("#txtQuery").val(); //若是查詢條件爲空默認查詢所有 if (queryStr == null) { queryStr = "%"; } $('#List').datagrid({ url: '/SysException/GetList?queryStr=' + encodeURI(queryStr) }); }); }); </script>
@model App.Models.Sys.SysExceptionModel @using App.Admin; @using App.Common; @using App.Models.Sys; @{ ViewBag.Title = "Details"; Layout = "~/Views/Shared/_Index_LayoutEdit.cshtml"; } <script type="text/javascript"> $(function () { $("#btnReturn").click(function () { window.parent.frameReturnByClose(); }); }); </script> <div class="mvctool bgb"> <a id="btnReturn" style="float: left;" class="l-btn l-btn-plain"><span class="l-btn-left"><span class="l-btn-text icon-return" style="padding-left: 20px;">返回</span></span></a> </div> @using (Html.BeginForm()) { <div id="ErrMesList"> <div id="ErrMesListContent"> @Html.ValidationSummary(false) </div> </div> <table class="form_table setinput355"> <tbody> <tr> <th> @Html.LabelFor(model => model.HelpLink) </th> <td> @Html.EditorFor(model => model.HelpLink) </td> </tr> <tr> <th> @Html.LabelFor(model => model.Message) </th> <td> @Html.TextAreaFor(model => model.Message, new { @style = "height:100px;width:550px" }) </td> </tr> <tr> <th> @Html.LabelFor(model => model.Source) </th> <td> @Html.EditorFor(model => model.Source) </td> </tr> <tr> <th> @Html.LabelFor(model => model.StackTrace) </th> <td> @Html.TextAreaFor(model => model.StackTrace, new { @style = "height:100px;width:550px" }) </td> </tr> <tr> <th> @Html.LabelFor(model => model.TargetSite) </th> <td> @Html.TextAreaFor(model => model.TargetSite, new { @style = "height:100px;width:550px" }) </td> </tr> <tr> <th> @Html.LabelFor(model => model.Data) </th> <td> @Html.EditorFor(model => model.Data) </td> </tr> <tr> <th> @Html.LabelFor(model => model.CreateTime) </th> <td> @Html.TextBoxFor(model => model.CreateTime) </td> </tr> </tbody> </table> }
被忘記注入到容器。預覽一下
因爲時間關係,把異常和日誌的應用放到一下講吧。
而後我認爲無目的的提供源碼對園友的幫助是不大的,只能說你擁有一套源碼,不管多漂亮都好,你本身不思考不動手,東西永遠仍是別人作出來的,真正遇到問題,是難解決,或者解決不了的,然而系統,我並無完徹底全把全部代碼放出來,可是複雜的邏輯或者重點我都放出來了,正如上面,日誌和異常的刪除功能我沒有放出源代碼,就但願你們一塊兒來完善這個強大的系統。
我但願你們若是有時間跟着來作,你確定會受益不淺