基于MVC4+EasyUI的Web开发框架造成之旅(6)--基类控制器CRUD的操做

在上一篇随笔中,我对Web开发框架的整体界面进行了介绍,其中并提到了个人《Web开发框架》的控制器的设计关系,Web开发框架沿用了个人《Winform开发框架》的不少架构设计思路和特色,对Controller进行了封装。使得控制器可以得到很好的继承关系,并能以更少的代码,更高效的开发效率,实现Web项目的开发工做,整个控制器的设计思路以下所示。javascript

从上图的设计里面能够看到,我把主要能经过抽象封装的CRUD方法都放到了BusinessController<B, T>类里面,本文继续详细介绍这个Web框架控制器类的CRUD具体实现,以便使得你们了解个人整个Web开发框架的基类控制器的工做原理。html

一、基类的插入操做

咱们知道,通常常规的插入操做是很广泛的操做,那么咱们在MVC的Web界面上是如何调用的,后台又是如何进行数据的处理的呢?java

在MVC的View视图代码里面,咱们添加数据的时候,javascript脚本代码是这样的:数据库

复制代码
                var postData = $("#ffAdd").serializeArray(); $.post("/Information/Insert", postData, function (data) { if (data = "true") { //添加成功 1.关闭弹出层,2.刷新DataGird $.messager.alert("提示", "添加成功"); $("#DivAdd").dialog("close"); $("#grid").datagrid("reload"); $("#ffAdd").form("clear"); //本页面的类型为【通知公告】,固定不变 $("#Category").val("通知公告"); } else { $.messager.alert("提示", "添加失败,请您检查"); } });
复制代码

其中的serializeArray就把该表单要提交的数据序列号到一个字符串里面了,里面的数据可能相似A=a&B=b&C=c 这样的字符串里面了,经过POST调用控制器Information的Insert方法,实现数据的插入。因为控制器Information是具体业务类,所以它继承自BusinessController<B, T>,也就是会调用BusinessController<B, T>控制器的Insert方法。架构

如字典数据添加的界面以下所示。框架

那么后台的接收方法如何呢?其实后台是把数据序列化到了一个FormCollection对象的集合里面了,可是,咱们还可使用对象T(实体类),让这些数据集合赋值给对应的实体对象属性,以下就是个人后台控制器的插入方法,它的参数是一个实体类T,这样咱们直接调用业务操做类就能够插入了,代码很简单易懂。dom

复制代码
        /// <summary> /// 插入指定对象到数据库中 /// </summary> /// <param name="info">指定的对象</param> /// <returns>执行操做是否成功。</returns> public virtual ActionResult Insert(T info) {bool result = false; if (info != null) { result = baseBLL.Insert(info); } return Content(result); }
复制代码

二、基类的更新操做

上面咱们看了插入数据的操做,可能你们对下面介绍的数据更新操做,可能也已经有了一些了解了,其实它和插入操做的方法很相似的。异步

更新操做的视图View中脚本代码以下所示, 它经过控制器Information的Update方法进行更新数据。ide

复制代码
                var ID = $("#ID1").val(); var postData = $("#ffEdit").serializeArray(); $.post("/Information/Update?ID=" + ID, postData, function (date) { if (date == "true") { //修改为功,关闭弹出层,刷新DataGird $.messager.alert("提示", "修改为功"); $("#DivEdit").dialog('close'); $("#grid").datagrid("reload"); } else { $.messager.alert("提示", "修改失败,请您检查"); } });
复制代码

因为控制器Information是具体业务类,所以它继承自BusinessController<B, T>,也就是会调用BusinessController<B, T>控制器的Update方法。post

和上面的插入操做同样,后台是把数据序列化到了一个FormCollection对象的集合里面了,咱们可使用相似和插入方法的操做,以下所示。

复制代码
        /// <summary> /// 更新对象属性到数据库中 /// </summary> /// <param name="info">指定的对象</param> /// <param name="id">主键ID的值</param> /// <returns>执行成功返回<c>true</c>,不然为<c>false</c></returns> public virtual ActionResult Update(T info, string id) { bool result = baseBLL.Update(info, id); return Content(result); }
复制代码

可是,若是使用以上的代码做为更新数据的代码,那么在编辑界面里,若是只是显示编辑部分表的数据,那么可能致使不少属性会被初始化为实体类的默认值,显然这样不符合咱们的要求,咱们可能只是进行部分更新,那么咱们进行部分更新的控制器方法应该如何设计呢?

前面咱们说到,数据会被序列号到一个FormCollection对象集合里面,更新方法也同样,那么咱们能够把更新操做的接口定义为以下代码所示,视图操做代码不变化:

复制代码
        /// <summary> /// 更新对象属性到数据库中 /// </summary> /// <param name="info">指定的对象</param> /// <param name="id">主键ID的值</param> /// <returns>执行成功返回<c>true</c>,不然为<c>false</c></returns> public virtual ActionResult Update(string id, FormCollection formValues)
复制代码

咱们能够经过调试的方法,查询到FormCollection里面的值就是咱们更新界面里面的数据(注意:多是实体类的部分数据)。但使用了这个方法后,咱们还须要把FormCollection对象里面的数据转换为实体类的信息,咱们才好调用BaseBLL里面的接口进行更新数据。可是不一样的实体类,有不一样的属性,咱们如何可以抽象把他们的属性都赋值了呢?

答案是经过反射属性方式,把FormCollection里面属性的值赋值给对应实体类属性的值。下面咱们来介绍下具体的代码实现了。

复制代码
        /// <summary> /// 更新对象属性到数据库中 /// </summary> /// <param name="info">指定的对象</param> /// <param name="id">主键ID的值</param> /// <returns>执行成功返回<c>true</c>,不然为<c>false</c></returns> public virtual ActionResult Update(string id, FormCollection formValues) { T obj = baseBLL.FindByID(id); if (obj != null) { //遍历提交过来的数据(多是实体类的部分属性更新) foreach (string key in formValues.Keys) { string value = formValues[key]; System.Reflection.PropertyInfo propertyInfo = obj.GetType().GetProperty(key); if (propertyInfo != null) { try { // obj对象有key的属性,把对应的属性值赋值给它(从字符串转换为合适的类型) //若是转换失败,会抛出InvalidCastException异常 propertyInfo.SetValue(obj, Convert.ChangeType(value, propertyInfo.PropertyType), null); } catch { } } } } bool result = baseBLL.Update(obj, id); return Content(result); }
复制代码

经过对象propertyInfo的SetValue方法,能够把字符串的值,转换为实体类对应属性类型的值,顺利进行赋值。

若是是业务类须要提交一些HTML的代码,那么咱们须要在具体的业务类里面,重写插入、更新方法并设置一下 [ValidateInput(false)] 标识才能够。

复制代码
        [ValidateInput(false)] public override ActionResult Insert(InformationInfo info) { info.Editor = CurrentUser.Name; info.EditTime = DateTime.Now; return base.Insert(info); } [ValidateInput(false)] public override ActionResult Update(string id, FormCollection formValues) { return base.Update(id, formValues); }
复制代码

如通知公告的内容编辑界面以下所示。

三、基类的获取对象数据方法

咱们在不少接口里面,都要求获取单一对象的数据信息,我在基类接口里面定义了一个FindByID方法,就是从业务对象里面,根据主键ID信息,获取一个对象的数据,把他转换为Json传递到View视图里面使用便可。

复制代码
        /// <summary> /// 查询数据库,检查是否存在指定ID的对象 /// </summary> /// <param name="id">对象的ID值</param> /// <returns>存在则返回指定的对象,不然返回Null</returns> public virtual ActionResult FindByID(string id) { ActionResult result = Content(""); T info = baseBLL.FindByID(id); if (info != null) { result = JsonDate(info); } return result; }
复制代码

其中的JsonDate方法是为了不日期类型的数值在序列化中出现错误格式,包装的一个方法,以下所示。

复制代码
        /// <summary> /// 返回处理过的时间的Json字符串 /// </summary> /// <param name="date"></param> /// <returns></returns> public ContentResult JsonDate(object date) { var timeConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" }; return Content(JsonConvert.SerializeObject(date, Formatting.Indented, timeConverter)); }
复制代码

在View视图里面使用控制器方法,绑定数据到查看界面里面的代码以下所示。

复制代码
        //绑定查看详细信息的方法  function BindViewInfo() { var ID = $("#grid").datagrid('getSelections')[0].ID; //发送请求 $.getJSON("/Information/FindByID?r=" + Math.random() + "&id=" + ID, function (info) { $("#ID2").val(info.ID); $("#Title2").text(info.Title); $("#Content2").html(info.Content); $("#Attachment_GUID2").text(info.Attachment_GUID); $("#Editor2").text(info.Editor); $("#EditTime2").text(info.EditTime); ShowUpFiles(info.Attachment_GUID, 'divViewAttach'); }); }
复制代码

具体效果以下所示:

四、基类删除操做方法

在GridView里面,咱们提供了删除数据的按钮,具体视图里面使用的代码以下所示。

复制代码
                //而后确认发送异步请求的信息到后台删除数据 $.messager.confirm("删除确认", "您确认删除选定的记录吗?", function (deleteAction) { if (deleteAction) { $.get("/Information/DeletebyIds", postData, function (data) { if (data == "true") { $.messager.alert("提示", "删除选定的记录成功"); $("#grid").datagrid("reload");  } else { $.messager.alert("提示", data); } }); } });
复制代码

后台控制器的基类删除方法以下所示。

复制代码
        /// <summary> /// 删除多个ID的记录 /// </summary> /// <param name="ids">多个id组合,逗号分开(1,2,3,4,5)</param> /// <returns></returns> public virtual ActionResult DeleteByIds(string ids) {bool result = false; if (!string.IsNullOrEmpty(ids)) { string[] idArray = ids.Split(new char[] { ',' }); foreach (string strId in idArray) { if (!string.IsNullOrEmpty(strId)) { baseBLL.Delete(strId); } } result = true; } return Content(result); } 
复制代码

以上就是基类控制器增删改查的一些通用方法的封装,业务对象控制器类,若是有特殊的须要,能够对方法进行重写便可,很是方便使用,从而减小了不少重复编写的代码,并可使得页面的操做统一化,提升生产效率。

相关文章
相关标签/搜索