基于MVC4+EasyUI的Web开发框架形成之旅MVC控制器的设计.docx
《基于MVC4+EasyUI的Web开发框架形成之旅MVC控制器的设计.docx》由会员分享,可在线阅读,更多相关《基于MVC4+EasyUI的Web开发框架形成之旅MVC控制器的设计.docx(14页珍藏版)》请在冰点文库上搜索。
基于MVC4+EasyUI的Web开发框架形成之旅MVC控制器的设计
自从上篇《基于MVC4+EasyUI的Web开发框架形成之旅--总体介绍》总体性的概括,得到很多同行的关注和支持,不过上一篇主要是介绍一个总体的界面效果和思路,本系列的文章将逐步介绍其中的细节,本文主要介绍整个Web开发框架中的MVC控制器的设计。
在设计之初,我就希望尽可能的减少代码,提高编程模型的统一性。
因此希望能够以基类继承的方式,和我Winform开发框架一样,尽可能通过基类,而不是子类的重复代码来实现各种通用的操作。
1、登录控制的控制器基类设计
我们知道,一般我们创建一个MVC的控制器,都是基于Controller这样的基类来实现。
如下代码所示。
publicclassTestController:
Controller
{
//
//GET:
/Test/
publicActionResultIndex()
{
returnView();
}
}
在我的Winform开发框架里面,用到了泛型的类型,非常方便实现业务逻辑和数据访问基类的设计,控制器是否也可以这样做的呢?
我们知道,一般的MVC控制器需要验证用户是否已经登陆了,这也是很多常见Web操作前的验证,还有对异常的处理,在MVC的基类,可以一并进行记录(这个非常不错),于是我们先来设计一个验证用户身份是否登陆的基类BaseController
///
///所有需要进行登录控制的控制器基类
///
publicclassBaseController:
Controller
{
///
///当前登录的用户属性
///
publicUserInfoCurrentUserInfo{get;set;}
///
///重新基类在Action执行之前的事情
///
///重写方法的参数
protectedoverridevoidOnActionExecuting(ActionExecutingContextfilterContext)
{
base.OnActionExecuting(filterContext);
//得到用户登录的信息
CurrentUserInfo=Session["UserInfo"]asUserInfo;
//判断用户是否为空
if(CurrentUserInfo==null)
{
Response.Redirect("/Login/Index");
}
}
protectedoverridevoidOnException(ExceptionContextfilterContext)
{
base.OnException(filterContext);
//错误记录
WHC.Framework.Commons.LogTextHelper.Error(filterContext.Exception);
//当自定义显示错误mode=On,显示友好错误页面
if(filterContext.HttpContext.IsCustomErrorEnabled)
{
filterContext.ExceptionHandled=true;
this.View("Error").ExecuteResult(this.ControllerContext);
}
}
........................
}
有了这个基类,我们在主页的Home控制类,就可以使用用户信息对象了进行操作了,而且必须要求客户登陆了。
publicclassHomeController:
BaseController
{
publicActionResultIndex()
{
if(CurrentUserInfo!
=null)
{
ViewBag.FullName=CurrentUserInfo.FullName;
ViewBag.Name=CurrentUserInfo.Name;
}
returnView();
}
................
}
2、数据访问业务基类控制器的设计
我在我的Winform开发框架里面,对很多基类都使用泛型进行设计,这样可以传递相应的数据类型到基类里面进行处理,如下面的BLL层的业务对象定义代码如下所示。
namespaceWHC.Security.BLL
{
///
///角色信息业务管理类
///
publicclassRole:
BaseBLL
{
....................
///
///业务基类对象
///
///业务对象类型
publicclassBaseBLLwhereT:
BaseEntity,new()
{
///
///插入指定对象到数据库中
///
///指定的对象
///执行操作是否成功。
publicvirtualboolInsert(Tobj)
{
returnbaseDal.Insert(obj);
}
............
业务对象Role,要求传入RoleInfo给基类处理,这样基类就能定义到都对应的T为具体的RoleInfo类型了。
在MVC的控制器是否也可以这样做呢?
当然可以,下面是我定义的一个控制器继承关系图。
上面的介绍也已经比较明白了,其实就是在BusinessController里面传入了两个参数,定义代码如下所示。
///
///本控制器基类专门为访问数据业务对象而设的基类
///
///业务对象类型
///实体类类型
publicclassBusinessController:
BaseController
whereB:
class
whereT:
WHC.Framework.ControlUtil.BaseEntity,new()
{
///
///插入指定对象到数据库中
///
///指定的对象
///执行操作是否成功。
publicvirtualActionResultInsert(Tinfo)
{
boolresult=false;
if(info!
=null)
{
result=baseBLL.Insert(info);
}
returnContent(result);
}
................
我根据传入的BLL业务对象类型B,对象实体类类型T,那么我们就可以构造对应的baseBLL对象,然后调用其基类接口实现基本的操作,如插入,删除,更新,查找等等,这样的模式就和我的Winform开发框架的理念非常吻合了。
我们以角色控制器来说明,它的定义如下所示,如果不需要实现额外的接口(除了常见的操作),基本上不需要写任何代码了,因为所有很多常见的操作,都已经封装在了基类控制器BusinessController里面了。
///
///角色业务操作控制器
///
publicclassRoleController:
BusinessController
{
publicRoleController():
base()
{
}
...............
对于一些需要特殊数据处理的操作,可以增加一些自定义的接口函数,也可以重写基类的一些接口,实现数据的相应处理。
如我的菜单界面显示中,需要根据缩进的层级对菜单名称进行缩进,以便更好的展示它们的层级结构,那么我就需要对分页函数进行重写了,如下代码所示是整个菜单Menu类的控制器类代码。
publicclassMenuController:
BusinessController