EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(六)

前言

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

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 != 0)
                {
                    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 - 1) * 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 = 1)
        {
            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)  //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 != 0)
            {
                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="2">
        <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="50">
                主键ID
            </th>
            <th field="RoleName" width="50">
                角色名称
            </th>
            <th field="Remark" width="150">
                备注
            </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="50" rows="4"> </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: [10, 20, 50], //可以设置每页记录条数的列表
            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(2);  //操作:点击查询按钮筛选条件
    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视图查看系统运行效果:

  

时间: 2024-08-22 11:48:45

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

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

前言 本系列源自对EF6 CodeFirst的探索,但后来发现在自己项目中构建的时候遇到了一些问题以及一些解决方法,因此想作为一个系列写下来. 本系列并不是教你怎么做架构设计,但可以参照一下里面的方法,EF系列大都采用DDD的构建方式,这也是目前最流行的.如果你想对DDD有所了解,可以在园子当中寻找那些DDD方面的文章或者是在CodePlex上下载相关的DDD设计模型源码进行研究. 如果你是一个新人或者是没有用过EF6 CodeFirst的人,那么本系列将带你一步一步构建自己的解决方案平台.如果

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

前言 这一篇,我们终于到了讲解Entity Framework CodeFirst 的时刻了,首先创建实体对象模型,然后会通过配置Fluent API的方式来对实体对象模型进行完整的数据库映射操作. 此篇幅中会涉及到一些Entity Frame的相关概念,会给出初步的解释.如果需要详细了解,可以查阅相关的帮助文档. EF实体对象模型的创建 EF的实体对象模型大都采用POCO类的方式创建.POCO的全称为Plain_Old_CLR_Object(简单传统CLR对象),是指那些没有从任何类继承,也没

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

前言 在上一篇中,我们依靠着EasyUI强大的前端布局特性把前端登录界面和主界面给搭建完成了.这一篇我们就要尝试着把整个解决方案部署到云端呢,也就是Visual Studio Online(TFVC)中. 在我们进行团队项目开发的过程中,或多或少的都会接触到一些源代码管理工具,比如vss.svn.tfs.git,这些工具都有着自己的特点.但最终目的都是方便团队的协作开发,提高工作效率.Visual studio从2013版本开始就为我们提供了云端管理源代码的能力.Visual Studio On

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

前言 这一篇是本系列的最后一篇,虽然示例讲到这里就停止呢,但对于这些技术的学习远不能停止.虽然本示例讲的比较基础,但是正如我第一篇说到的,这个系列的目的不是说一些高端的架构设计,而是作为一个入门级,对学习EntityFramework6构建一个简单的示例以及对其进行设计,管理,编码的过程. 应部分园友要求,博客换了一个清爽的模板.之前的模板也是为了学习一下,所以按照其他模板的样式,把自己的博客园模板修该了一下.虽然这不是写博客的主要目的,但还是从中学习到了很多,比如小插件的应用.运行js和css

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

前言 上一篇文章我们完成了系统角色管理的基本功能实现,也对系统层次结构进行了了解.这一篇我们将继续对系统的用户管理模块进行代码编写.代码没有做封装,所以大部分的逻辑代码都是相通的,只是在一些前端的细节上处理有些不同.源码将在文章的末尾给出,有兴趣的园友可以对代码做一些封装或重构,毕竟这可以减少很多的代码量. Abstract层 在这一层添加对用户管理操作的业务接口IS_UserRepository,里面定义增删改查的业务接口.代码如下: using Entities; using System.

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

前言 今天早上,看到第一篇上首页呢,多谢支持! 写完第一篇后,我一直在想接下来应该从哪一方面开始讲.后来我觉得不用那么死板的把每一个课程和大纲都列出来吧,毕竟我又不是教书的,呵呵...我觉得就像做实验一样,我们一部分一部分的完成,最后总个结果应该就出来呢.那么这一篇就来把前端的样子弄出来,至少得知道长成什么样吧.接下来就应该开始捯饬了... 下载前端框架EasyUI 到EasyUI的官网下载压缩包.一个是基于GPL的开源版,一个是商业版.我们自己做研究就下个开源版呢.目前是1.4.3的版本,解压

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

前言 本篇幅将对系统的菜单管理模块进行说明,系统的菜单采用树形结构,这样可以更好地方便层级设计和查看.本示例将说明如何通过EntityFramework读取递归的菜单树形结构,以及结合EasyUI的treegrid在Asp.net MVC上显示树形菜单和管理操作. Easyui-treegrid的使用方法 首先我们来看一下treegrid的基本使用方法.很简单,和easyui-datagrid差不多. <table title="Folder Browser" class=&qu

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

前言 这一篇我们将完成系统的权限设置功能以及不同角色用户登录系统后动态加载菜单.注意:此示例权限只针对菜单级,如果园友需要更复杂的系统权限设置,可以拓展到按钮级或属性级. 用户的登录采用Form认证来实现,这样可以有效地防止非授权用户或页面链接对系统造成不安全的操作. 权限设置模块 页面采用角色列表和菜单列表勾选的方式,即选择角色后勾选可以操作的菜单,这样具有才角色的用户就具有操作这些菜单的权限.界面设置如下: 界面选择的roleID和menuID我们采用字符串的方式进行拼接.在controll

基于MVC4+EasyUI的Web开发框架形成之旅--MVC控制器的设计

自从上篇<基于MVC4+EasyUI的Web开发框架形成之旅--总体介绍>总体性的概括,得到很多同行的关注和支持,不过上一篇主要是介绍一个总体的界面效果和思路,本系列的文章将逐步介绍其中的细节,本文主要介绍整个Web开发框架中的MVC控制器的设计.在设计之初,我就希望尽可能的减少代码,提高编程模型的统一性.因此希望能够以基类继承的方式,和我Winform开发框架一样,尽可能通过基类,而不是子类的重复代码来实现各种通用的操作. 1.登录控制的控制器基类设计 我们知道,一般我们创建一个MVC的控制