不知不觉已经过了13讲,(本来还要讲多一讲是,数据验证之自定义验证,基于园友还是对权限这块比较敢兴趣,讲不讲验证还是看大家的反映),我们应该对系统有一个小结。
首先这是一个团队开发项目,基于接口编程,我们从EasyUI搭建系统的框架开始,开始了一个样例程序对EasyUI的DataGrid进行了操作,并实现Unity的注入到容器,使程序
的性能大大提升,代码质量上升,更佳利于单元测试,使用日志和异常坚固系统稳定性等等。。。。
当然你应该觉得系统还有存在很多不足,我们应该动手来优化一下。
下面我罗列了需要优化的项目,如果你觉得还有优化的,请提交,我将加入以后的文章中去
- UI方面,我们的easyui window弹出窗体,是不是没有居中,好丑啊;
- DataGrid虽然我在绑定时候写入了根据第一次窗体的变化去适应框架,这时你点击游览器的缩小或者扩大按钮,那么你的DataGrid变形了;
- JS我们在Details页面引入了JS,我们是否应该把他嵌入到_Layout_----里面去?并进行捆绑?
- 我们DataGrid返回的日期格式是/Date(20130450000365)你看得懂吗?
- 我们的BLL每次都要去实例化 DBContainer db = new DBContainer();重复操作,我们是不是应该写一个BaseBLL基类类继承
- 我们前端很多提示信息都一样,是不是应该封装起来,比如点击:Details时没有选择提示的“请选择要操作的记录”
- 工具栏的增、删、改按钮一样每次粘贴的代码也不少,我们应该扩展Mvc的HtmlHelper的封装,之后我们@html.就出来了多方便,以后还用于权限控制
优化后的系统将可能做为最后一个发布源码的版本,如无必要以后不再提供源码下载,但所讲的内容中,将全部包含完整源码,请你将完成的系统“珍藏”起来,因
为这是你的劳动成果
最后我们将接受一个更大的目标挑战,权限管理系统。我觉得这个是大家最关心的事情了,但是在此之前,我们将要补充一些知识。
- MVC自带的过滤器用法
- MVC路由Rotun概念
权限系统讲完了,我们讲T4模板,导出报表和图表,文件上传,系统设置等等补充..让我们的系统拿出来就能当项目来用。
由于接下来的东西逻辑性和编码都要比之前的复杂很多,所以更新可能会比以前慢。请大家耐心等待,谢谢园友的支持,无论多忙我都会不断的更新
现在我们先来解决以上7个问题吧!
1.UI方面,我们的easyui window弹出窗体,是不是没有居中,好丑啊;
easyui1.3.2版本,window的弹出不会居中了。而dialog是会居中的,我们必须为为window的open事件做扩展
代码如下:只要加入以下代码即可.如果你是看了MVC项目系列的,把他放到jquery.easyui.plus.js里面就可以了
//让window居中 var easyuiPanelOnOpen = function (left, top) { var iframeWidth = $(this).parent().parent().width(); var iframeHeight = $(this).parent().parent().height(); var windowWidth = $(this).parent().width(); var windowHeight = $(this).parent().height(); var setWidth = (iframeWidth - windowWidth) / 2; var setHeight = (iframeHeight - windowHeight) / 2; $(this).parent().css({/* 修正面板位置 */ left: setWidth, top: setHeight }); if (iframeHeight < windowHeight) { $(this).parent().css({/* 修正面板位置 */ left: setWidth, top: 0 }); } $(".window-shadow").hide(); }; $.fn.window.defaults.onOpen = easyuiPanelOnOpen;
jquery.easyui.plus.js
完美居中。
点击最大化后,再次最小化时也会出现不居中现象,我们必须,扩展resize事件。
var easyuiPanelOnResize = function (left, top) { var iframeWidth = $(this).parent().parent().width(); var iframeHeight = $(this).parent().parent().height(); var windowWidth = $(this).parent().width(); var windowHeight = $(this).parent().height(); var setWidth = (iframeWidth - windowWidth) / 2; var setHeight = (iframeHeight - windowHeight) / 2; $(this).parent().css({/* 修正面板位置 */ left: setWidth-6, top: setHeight-6 }); if (iframeHeight < windowHeight) { $(this).parent().css({/* 修正面板位置 */ left: setWidth, top: 0 }); } $(".window-shadow").hide(); //$(".window-mask").hide().width(1).height(3000).show(); }; $.fn.window.defaults.onResize = easyuiPanelOnResize;
window组件可以兼容了
2.DataGrid虽然我在绑定时候写入了根据第一次窗体的变化去适应框架,这时你点击游览器的缩小或者扩大按钮,那么你的DataGrid变形了;
DataGrid有100%宽度的设置,但是有时不是很让人满意,比如你你放大或者拉放你的浏览器,那么DataGrid只维持第一次加载的宽高,非常难看
$(‘#List‘).datagrid({ url: ‘/SysSample/GetList‘, width: $(window).width() - 10, methord: ‘post‘, height: $(window).height() - 35, fitColumns: true, .................................
你看到$(window).width() - 10和$(window).height() - 35
这是我设置的页面第一次载入,去后去窗体的宽度和高度进行计算,那么在第一次载入显示是正常的,但是放大或者拉伸浏览器,datagrid将不做改变了,我们这是要用到一个jquery的方法,叫resize()
参数
fnFunctionV1.0
在每一个匹配元素的resize事件中绑定的处理函数。
[data],fnString,FunctionV1.4.3
data:resize([Data], fn) 可传入data供函数fn处理。
fn:在每一个匹配元素的resize事件中绑定的处理函数。
看到浏览器变化时候激发的事件,所以我们要加入:
!--自动DataGrid 从第一次加载与重置窗体大小时候发生的事件:分部视图--> <script type="text/javascript"> $(function () { $(window).resize(function () { $(‘#List‘).datagrid(‘resize‘, { width: $(window).width() - 10, height: $(window).height() - 35 }).datagrid(‘resize‘, { width: $(window).width() - 10, height: $(window).height() - 35 }); }); }); </script>
好了,我们来做一个对比(第一载入的时候)
缩小浏览器的时候
完美显示
3.JS我们在Details页面引入了JS,我们是否应该把他嵌入到_Layout_----里面去?并进行捆绑?
我已经进行压缩了.源码带出.
4.我们DataGrid返回的日期格式是/Date(20130450000365)你看得懂吗?
MVC解决Json DataGrid返回的日期格式是/Date(20130450000365)
实际上是Json格式化问题,我们应该在返回json的时候进行格式化,我们需要重写系统的JsonResult类,新增引用system.web和system.web.extensions
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Mvc; using System.Text.RegularExpressions; using System.Web; using System.Web.Script.Serialization; namespace App.Common { public class ToJsonResult : JsonResult { const string error = "该请求已被封锁,因为敏感信息透露给第三方网站,这是一个GET请求时使用的。为了可以GET请求,请设置JsonRequestBehavior AllowGet。"; /// <summary> /// 格式化字符串 /// </summary> public string FormateStr { get; set; } public override void ExecuteResult(ControllerContext context) { if (context == null) { throw new ArgumentNullException("context"); } if (JsonRequestBehavior == JsonRequestBehavior.DenyGet && String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException(error); } HttpResponseBase response = context.HttpContext.Response; if (!String.IsNullOrEmpty(ContentType)) { response.ContentType = ContentType; } else { response.ContentType = "application/json"; } if (ContentEncoding != null) { response.ContentEncoding = ContentEncoding; } if (Data != null) { JavaScriptSerializer serializer = new JavaScriptSerializer(); string jsonstring = serializer.Serialize(Data); //string p = @"\\/Date\((\d+)\+\d+\)\\/"; string p = @"\\/Date\(\d+\)\\/"; MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertJsonDateToDateString); Regex reg = new Regex(p); jsonstring = reg.Replace(jsonstring, matchEvaluator); response.Write(jsonstring); } } /// <summary> /// 将Json序列化的时间由/Date(1294499956278+0800)转为字符串 /// </summary> private string ConvertJsonDateToDateString(Match m) { string result = string.Empty; string p = @"\d"; var cArray = m.Value.ToCharArray(); StringBuilder sb = new StringBuilder(); Regex reg = new Regex(p); for (int i = 0; i < cArray.Length; i++) { if (reg.IsMatch(cArray[i].ToString())) { sb.Append(cArray[i]); } } // reg.Replace(m.Value; DateTime dt = new DateTime(1970, 1, 1); dt = dt.AddMilliseconds(long.Parse(sb.ToString())); dt = dt.ToLocalTime(); result = dt.ToString("yyyy-MM-dd HH:mm:ss"); return result; } } }
创建Controller的基类,BaseController让Controller去继承Controller
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web; using System.Web.Mvc; using App.Common; using App.Models.Sys; namespace App.Admin { public class BaseController : Controller { /// <summary> /// 获取当前用户Id /// </summary> /// <returns></returns> public string GetUserId() { if (Session["Account"] != null) { AccountModel info = (AccountModel)Session["Account"]; return info.Id; } else { return ""; } } /// <summary> /// 获取当前用户Name /// </summary> /// <returns></returns> public string GetUserTrueName() { if (Session["Account"] != null) { AccountModel info = (AccountModel)Session["Account"]; return info.TrueName; } else { return ""; } } /// <summary> /// 获取当前用户信息 /// </summary> /// <returns>用户信息</returns> public AccountModel GetAccount() { if (Session["Account"] != null) { return (AccountModel)Session["Account"]; } return null; } protected override JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior) { return new ToJsonResult { Data = data, ContentEncoding = contentEncoding, ContentType = contentType, JsonRequestBehavior = behavior, FormateStr = "yyyy-MM-dd HH:mm:ss" }; } /// <summary> /// 返回JsonResult.24 /// </summary> /// <param name="data">数据</param> /// <param name="behavior">行为</param> /// <param name="format">json中dateTime类型的格式</param> /// <returns>Json</returns> protected JsonResult MyJson(object data, JsonRequestBehavior behavior, string format) { return new ToJsonResult { Data = data, JsonRequestBehavior = behavior, FormateStr = format }; } /// <summary> /// 返回JsonResult42 /// </summary> /// <param name="data">数据</param> /// <param name="format">数据格式</param> /// <returns>Json</returns> protected JsonResult MyJson(object data, string format) { return new ToJsonResult { Data = data, FormateStr = format }; } /// <summary> /// 检查SQL语句合法性 /// </summary> /// <param name="sql"></param> /// <returns></returns> public bool ValidateSQL(string sql, ref string msg) { if (sql.ToLower().IndexOf("delete") > 0) { msg = "查询参数中含有非法语句DELETE"; return false; } if (sql.ToLower().IndexOf("update") > 0) { msg = "查询参数中含有非法语句UPDATE"; return false; } if (sql.ToLower().IndexOf("insert") > 0) { msg = "查询参数中含有非法语句INSERT"; return false; } return true; } } }
好了,我们运行,其实就是这么一回事!
5.我们的BLL每次都要去实例化 DBContainer db = new DBContainer();重复操作,我们是不是应该写一个BaseBLL基类类继承
我已经进行分离,源码带出.
6.我们前端很多提示信息都一样,是不是应该封装起来,比如点击:Details时没有选择提示的“请选择要操作的记录”
在App.Common加入以下类Suggestion
在视图中的使用
$("#btnDelete").click(function () { var row = $(‘#List‘).datagrid(‘getSelected‘); if (row != null) { $.messager.confirm(‘提示‘, ‘@Suggestion.YouWantToDeleteTheSelectedRecords‘, function (r) { if (r) { $.post("/SysSample/Delete?id=" + row.Id, function (data) { if (data.type == 1) $("#List").datagrid(‘load‘); $.messageBox5s(‘提示‘, data.message); }, "json"); } }); } else { $.messageBox5s(‘提示‘, ‘@Suggestion.PlaseChooseToOperatingRecords‘); } });
@Suggestion.PlaseChooseToOperatingRecords‘
7.工具栏的增、删、改按钮一样每次粘贴的代码也不少,我们应该扩展Mvc的HtmlHelper的封装,之后我们@html.就出来了多方便,以后还用于权限控制
这个必须返回MvcHtmlString和在视图中引入命名空间。在App.Admin的Core文件夹中新建类ExtendMvcHtml
并加入以下代码
并在视图中使用它,使用例子!
@Html.ToolButton("btnQuery", "icon-search","查询",true) @Html.ToolButton("btnCreate", "icon-add", "新增",true) @Html.ToolButton("btnEdit", "icon-edit", "编辑", true) @Html.ToolButton("btnDetails", "icon-details", "详细", true) @Html.ToolButton("btnDelete", "icon-remove", "删除", true) @Html.ToolButton("btnExport", "icon-export","导出",true)