前言

  • 在接下来的篇幅里将对系统的模块功能进行编写。主要以代码实现为主。这一篇我们需要完成系统模块“角色管理”的相关功能。完成后可以对系统框架结构有进一步了解。

Abstract

  • 之前说过,Abstract层是对业务接口的定义,所以我们新建接口文件IS_UserRepository,定义增删改查业务的接口。这一层需要添加对Entities层的引用。代码如下:
using Entities;
using System.Collections.Generic; namespace Abstract
{
public interface IS_RoleRepository
{
bool Add(S_Role model);
bool Update(S_Role model);
bool Delete(long id);
List<S_Role> GetInfo(string strWhere, int rows, int page, out int total);
}
}

Concrete

  • 这一层是对Abstract业务的接口进行实现层,也是利用EntityFramework与数据库进行交互的层。我们定义类文件S_ RoleRepository,实现增删改查业务。查询时,我们将禁用延迟加载。这一层需要添加对Entities、Abstract层的引用。代码如下:
using System.Collections.Generic;
using System.Linq;
using Abstract;
using Entities; namespace Concrete
{
public class S_RoleRepository : IS_RoleRepository
{
private EFDbContext context = new EFDbContext();
public bool Add(S_Role model)
{
try
{
if (null != model)
{
context.S_Roles.Add(model);
context.SaveChanges();
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
} public bool Update(S_Role model)
{
try
{
if (null != model)
{
S_Role oldModel = context.S_Roles.FirstOrDefault(x => x.ID == model.ID);
oldModel.RoleName = model.RoleName;
oldModel.Remark = model.Remark; context.SaveChanges();
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
} public bool Delete(long id)
{
try
{
if (id != )
{
S_Role model = context.S_Roles.FirstOrDefault(x => x.ID == id);
if (null != model)
{
context.S_Roles.Remove(model);
context.SaveChanges();
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
catch
{
return false;
}
} public List<S_Role> GetInfo(string strWhere, int rows, int page, out int total)
{
context.Configuration.ProxyCreationEnabled = false;
context.Configuration.LazyLoadingEnabled = false; List<S_Role> listData = new List<S_Role>(); if (!string.IsNullOrEmpty(strWhere))
{
listData = context.S_Roles.Where(x => x.RoleName.Contains(strWhere)).ToList();
}
else
{
listData = context.S_Roles.ToList();
} var results = listData.OrderByDescending(p => p.ID).Skip((page - ) * rows).Take(rows);
total = listData.Count();
return results.ToList(); }
}
}

利用Ninject实现依赖注入

  • Ninject是.net平台下的一个IOC/DI框架。在此我们可以利用它解除Concrete对Abstract的强依赖关系。我们通过Ninject可以在web层构建一个依赖注入列表,这样可以在运行时进行依赖呢,而不是在编译时就产生依赖关系。
  • 接下来,我们为Web层添加Ninject,可以在Nuget上通过“程序包管理器控制台”进行下载安装。如下图:

   

  • 在Web层建立Infrastructure文件夹,添加NinjectControllerFactory类,实现Concrete和Abstract的动态绑定,在这里我们采用的是Ninject的构造注入的方式。这一层需要添加对Abstract、Concrete的引用。代码如下: 
using Abstract;
using Concrete;
using Ninject;
using System;
using System.Web.Mvc;
using System.Web.Routing; namespace Web.Controllers
{
public class NinjectControllerFactory : DefaultControllerFactory
{
private IKernel ninjectKernel;
public NinjectControllerFactory()
{
ninjectKernel = new StandardKernel();
AddBindings();
} protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
return controllerType == null
? null
: (IController)ninjectKernel.Get(controllerType);
} private void AddBindings()
{
// put additional bindings here
ninjectKernel.Bind<IS_RoleRepository >().To<S_ RoleRepository >();
}
}
}
  • 打开Web层的Global.asax文件,添加对动态生成控制器工厂类NinjectControllerFactory的注册。代码如下: 
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles); DatabaseInitializer.Initialize();
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
}
}

实现Web层角色管理界面功能

  • 注意:本示例都将采用Jquery的Ajax的异步方式,视图和控制器都将采用Json字符串作为传输对象。如果对这两块不清楚,可以先查阅相关资料了解一下。
  • 我们先定义MVC的Models层,新增mod_S_Role类,用于EasyUI的datagrid绑定role对象和分页操作。代码如下:
using Entities;
using System.Collections.Generic; namespace Web.Models
{
  public class mod_S_RolePage
  {
public string total { get; set; }
public List<S_Role> rows { get; set; }
  }
}
  • 再完成MVC的Controllers,新增SystemController控制器,添加角色操作界面视图RoleList,完成SystemController的角色操作代码。代码如下:
using System.Collections.Generic;
using System.Web.Mvc;
using Abstract;
using Common;
using Entities;
using Web.Models; namespace Web.Controllers
{
public class SystemController : Controller
{
private IS_RoleRepository IS_Role; public SystemController(IS_RoleRepository _S_Role)
{
this.IS_Role = _S_Role;
} #region log20150703 Create By Jack: 系统角色操作
public ActionResult RoleList()
{
return View();
} public ActionResult GetRoles(string strWhere, int rows, int page = )
{
mod_S_RolePage DataModel = new mod_S_RolePage(); int total; //必须定义参数变量接收out参数
List<S_Role> listData = IS_Role.GetInfo(strWhere, rows, page, out total); DataModel.total = total.ToString();
DataModel.rows = listData; return Json(DataModel, JsonRequestBehavior.AllowGet);
} public ActionResult CreateRole(S_Role dataModel)
{
bool rtnFalg = false;
if (Request.IsAjaxRequest())
{
if (dataModel.ID == ) //0为ID的默认值
{
dataModel.ID = NewID.NewComb();
rtnFalg = IS_Role.Add(dataModel);
}
else
{
rtnFalg = IS_Role.Update(dataModel);
}
if (rtnFalg == true)
{
return Json(new { flag = true });
}
else
{
return Json(new { flag = false });
}
}
else
{
return Json(new { flag = false });
}
} [HttpPost]
public ActionResult DeleteRole(long id)
{
if (id != )
{
bool rtnFlag = IS_Role.Delete(id);
if (rtnFlag == true)
{
return Json(new { flag = true });
}
else
{
return Json(new { flag = false });
}
}
else
{
return Json(new { flag = false });
}
} #endregion }
}
  • 完成MVC的Views,修改RoleList的代码如下:
@{
ViewBag.Title = "RoleList";
} <script src="~/JSFunction/System_RoleList.js"></script> <div id="toolbar">
<table cellpadding="">
<tr>
<td>角色ID:<input type="hidden" id="hid_optype" name="hid_optype" value="" /></td>
<td><input class="easyui-validatebox textbox" type="text" name="ID" disabled="disabled"></input></td>
<td>角色名称:</td>
<td><input class="easyui-validatebox textbox" type="text" name="RoleName" id="txt_RoleName"></input></td>
</tr> </table> <div class="panelExten">
<a href="javascript:void(0)" class="easyui-linkbutton" iconcls="icon-search" plain="true" onclick="ConditionSearch();">查询</a> |
<a href="javascript:void(0)" class="easyui-linkbutton" iconcls="icon-add" plain="true" onclick="NewData();">新增</a> |
<a href="javascript:void(0)" class="easyui-linkbutton" iconcls="icon-edit" plain="true" onclick="EditData();">编辑</a> |
<a href="javascript:void(0)" class="easyui-linkbutton" iconcls="icon-remove" plain="true" onclick="DestroyData();">删除</a> |
<a href="javascript:void(0)" class="easyui-linkbutton" iconcls="icon-undo" plain="true" onclick="ClearQuery();">清除</a>
</div>
</div> <table id="dg" class="easyui-datagrid" pagination="true"
rownumbers="true" fit="true"
fitcolumns="true" singleselect="true" toolbar="#toolbar" fit="false" style=" height:500px;">
<thead>
<tr>
<th data-options="field:'ck',checkbox:true"></th> <th field="ID" width="">
主键ID
</th>
<th field="RoleName" width="">
角色名称
</th>
<th field="Remark" width="">
备注
</th>
</tr>
</thead>
</table> <div id="dlg" class="easyui-dialog" style="width: 550px; height: 480px; padding: 10px 20px"
closed="true" buttons="#dlg-buttons" modal="true">
<form id="fm" method="post" novalidate>
<div class="fitem" style=" display:none;">
<label> 主键ID:</label>
<input id="ID" name="ID" class="easyui-validatebox" required="true">
</div>
<div class="fitem">
<label>角色名称:</label>
<input id="RoleName" name="RoleName" class="easyui-validatebox" required="true">
</div>
<div class="fitem">
<label>备注:</label>
<textarea id="Remark" name="Remark" cols="" rows=""> </textarea>
</div>
</form>
</div>
<div id="dlg-buttons">
<a href="javascript:void(0)" class="easyui-linkbutton" iconcls="icon-ok" id="send" onclick="SaveData()"> 保存</a>
<a href="javascript:void(0)" class="easyui-linkbutton" iconcls="icon-cancel" onclick="javascript:$('#dlg').dialog('close')">取消</a>
</div>
  • 注意,由于页面都是由大量的JS代码操作,所以我们在WEB的目录下建立一个JSFunction文件夹来存放页面的处理函数,名字由控制器和视图组合而成,如本例中为System_RoleList.js。代码如下:
//页面加载时读取数据
$(function () {
Search(); var dg = $('#dg');
var opts = dg.datagrid('options');
var pager = dg.datagrid('getPager');
pager.pagination({
onSelectPage: function (pageNum, pageSize) {
opts.pageNumber = pageNum;
opts.pageSize = pageSize;
pager.pagination('refresh', {
pageNumber: pageNum,
pageSize: pageSize
});
Search(); //从数据库中获取数据,并加载
},
pageList: [, , ], //可以设置每页记录条数的列表
beforePageText: '第', //页数文本框前显示的汉字
afterPageText: '页 共 {pages} 页',
displayMsg: '当前显示 {from} - {to} 条记录 共 {total} 条记录'
});
}); //从数据库中获取数据,并加载
function Search() { var page_Number = $('#dg').datagrid('options').pageNumber; //pageNumber为datagrid的当前页码
var page_Size = $('#dg').datagrid('options').pageSize; //pageSize为datagrid的每页记录条数 var optype = $('#hid_optype').val();
$('#dg').datagrid("loading"); //根据操作类型判断筛选条件
var strRoleName = $('#txt_RoleName').val();
var strWhere = strRoleName; $.post('/System/GetRoles', { strWhere: strWhere, page: page_Number, rows: page_Size },
function (data) {
$('#dg').datagrid('loadData', data);
$('#dg').datagrid("loaded");
})
} function ConditionSearch() {
$('#hid_optype').val(); //操作:点击查询按钮筛选条件
Search();
} function NewData() {
$('#dlg').dialog('open').dialog('setTitle', '新增角色信息');
$('#fm').form('clear');
} function EditData() {
var row = $('#dg').datagrid('getSelected');
if (row) {
$('#dlg').dialog('open').dialog('setTitle', '编辑角色信息');
$('#fm').form('load', row);
}
} function DestroyData() {
var row = $('#dg').datagrid('getSelected');
if (row) {
$.messager.confirm('提醒', '确定删除这条数据吗?', function (r) {
if (r) {
var strWhere = row.ID;
alert(strWhere); $.ajax({
url: '/System/DeleteRole',
type: 'POST',
data: { id: strWhere },
success: function (data) {
var t = data.flag;
if (t) {
$.messager.show({
title: '提示信息',
msg: '【系统提示】:操作成功!',
style: {
right: '',
top: document.body.scrollTop + document.documentElement.scrollTop,
bottom: ''
}
});
//$('#dg_CommGreen').datagrid('reload'); // reload the user data
Search();
}
}
})
}
});
}
else {
$.messager.show({
title: '提示信息',
msg: '【系统提示】:请选择须要操作的数据!',
style: {
right: '',
top: document.body.scrollTop + document.documentElement.scrollTop,
bottom: ''
}
});
}
} function ClearQuery()
{
$('#txt_RoleName').val("");
} function SaveData() {
var prod = {
ID: $('#ID').val(),
RoleName: $('#RoleName').val(),
Remark: $('#Remark').val()
}; $.ajax({
url: '/System/CreateRole',
type: 'POST',
data: JSON.stringify(prod),
dataType: 'json',
processData: false,
contentType: 'application/json;charset=utf-8',
complete: function (data) {
$('#dlg').dialog('close'); // close the dialog
$('#dg').datagrid('reload'); // reload the user data },
success: function (data) {
var t = data.flag;
if (t) {
$.messager.show({
title: '提示信息',
msg: '【系统提示】:操作成功!',
style: {
right: '',
top: document.body.scrollTop + document.documentElement.scrollTop,
bottom: ''
}
});
Search(); //添加成功后加载数据
}
else {
$.messager.show({
title: '提示信息',
msg: '【系统提示】:操作失败!',
style: {
right: '',
top: document.body.scrollTop + document.documentElement.scrollTop,
bottom: ''
}
});
}
},
error: function () {
$.messager.show({
title: '提示信息',
msg: '【系统提示】:操作失败!',
style: {
right: '',
top: document.body.scrollTop + document.documentElement.scrollTop,
bottom: ''
}
});
}
});
}
  • 到此,角色管理模块功能完成,运行结果如下:

  

备注

  • 本示例按照系统框架的层级结构对系统角色管理模块进行代码的编写。完成了基本功能,但没有对EasyUI做过多详细的解释,有关EasyUI的详细使用方法可以查看官方API 本示例源码下载。通过运行Account控制器下的Login视图查看系统运行效果:

  

EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(六)的更多相关文章

  1. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(一)

    前言 本系列源自对EF6 CodeFirst的探索,但后来发现在自己项目中构建的时候遇到了一些问题以及一些解决方法,因此想作为一个系列写下来. 本系列并不是教你怎么做架构设计,但可以参照一下里面的方法 ...

  2. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(完)

    前言 这一篇是本系列的最后一篇,虽然示例讲到这里就停止呢,但对于这些技术的学习远不能停止.虽然本示例讲的比较基础,但是正如我第一篇说到的,这个系列的目的不是说一些高端的架构设计,而是作为一个入门级,对 ...

  3. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(八)

    前言 本篇幅将对系统的菜单管理模块进行说明,系统的菜单采用树形结构,这样可以更好地方便层级设计和查看.本示例将说明如何通过EntityFramework读取递归的菜单树形结构,以及结合EasyUI的t ...

  4. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(七)

    前言 上一篇文章我们完成了系统角色管理的基本功能实现,也对系统层次结构进行了了解.这一篇我们将继续对系统的用户管理模块进行代码编写.代码没有做封装,所以大部分的逻辑代码都是相通的,只是在一些前端的细节 ...

  5. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(四)

    前言 这一篇,我们终于到了讲解Entity Framework CodeFirst 的时刻了,首先创建实体对象模型,然后会通过配置Fluent API的方式来对实体对象模型进行完整的数据库映射操作. ...

  6. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(三)

    前言 在上一篇中,我们依靠着EasyUI强大的前端布局特性把前端登录界面和主界面给搭建完成了.这一篇我们就要尝试着把整个解决方案部署到云端呢,也就是Visual Studio Online(TFVC) ...

  7. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(二)

    前言 写完第一篇后,我一直在想接下来应该从哪一方面开始讲.后来我觉得不用那么死板的把每一个课程和大纲都列出来吧,毕竟我又不是教书的,呵呵...我觉得就像做实验一样,我们一部分一部分的完成,最后总个结果 ...

  8. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(九)

    前言 这一篇我们将完成系统的权限设置功能以及不同角色用户登录系统后动态加载菜单.注意:此示例权限只针对菜单级,如果园友需要更复杂的系统权限设置,可以拓展到按钮级或属性级. 用户的登录采用Form认证来 ...

  9. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(五)

    前言 在编写代码的时候,我遇到了很多关于EntityFramework6的疑问,所以现在就提前把这些问题列出来做一下解答,以便在以后的代码编写过程中减少不必要的Bug. EntityFramework ...

随机推荐

  1. 第1章 Sass简介

    什么是 CSS 预处理器? 定义: CSS 预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为 CSS 增加了一些编程的特性,将 CSS 作为目标生成文件,然后开发者就只要使用这种语言 ...

  2. poj2485 kruskal与prim

    Kruskal: #include<iostream> #include<cstdio> #include<algorithm> using namespace s ...

  3. inline、block、inline-block的区别

    http://www.cnblogs.com/KeithWang/p/3139517.html

  4. 【RabbitMQ】RabbitMQ的一些基础概念

    工作中使用的是RabbitMQ,需要对其进行熟悉.使用之前,弄清楚它是什么东西,解决什么问题. 场景 一些不必实时执行的任务 开发中,有一些任务并无须实时执行,比如: 会员更新个人信息,更新会员信息之 ...

  5. 俄罗斯画师Mikhail Rakhmatullin作品

  6. Date Picker和UITool Bar的使用

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Verdana } span.s1 { } span.s2 { background-colo ...

  7. 《简明python教程》笔记一

    读<简明Python教程>笔记: 本书的官方网站是www.byteofpython.info  安装就不说了,网上很多,这里就记录下我在安装时的问题,首先到python官网下载,选好安装路 ...

  8. php : Warning: strftime(): It is not safe to rely on the system's timezone settings.

    使用 Smarty 的时候出现这种警告: Warning: strftime(): It is not safe to rely on the system's timezone settings. ...

  9. newInstance()和new()

    在Java开发特别是数据库开发中,经常会用到Class.forName( )这个方法.通过查询Java Documentation我们会发现使用Class.forName( )静态方法的目的是为了动态 ...

  10. 本周psp(观众页面)

    个人项目PSP(观众页面) 计划 30min 估计要用多长时间 3d 开发 5h 需求分析 1h 生成设计文档 1h 设计复审 50min 代码规范 20min 具体设计 40min 具体编码 3h ...