.Net MVC&&datatables.js&&bootstrap做一个界面的CRUD有多简单

Posted life is not only coding......

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.Net MVC&&datatables.js&&bootstrap做一个界面的CRUD有多简单相关的知识,希望对你有一定的参考价值。

    我们在项目开发中,做得最多的可能就是CRUD,那么我们如何在ASP.NET MVC中来做CRUD呢?如果说只是单纯实现功能,那自然是再简单不过了,可是我们要考虑如何来做得比较好维护比较好扩展,如何做得比较漂亮。做开发要有工匠精神,不要只求完成开发任务,那样的话,永远停留在只是简单的写业务逻辑代码水平,我们要做有追求的程序员。本来这么简单的东西,我真是懒得写,但是看到即便是一些工作了好些年的人,做东西也是只管实现功能,啥都不管,还有些界面css样式要么就硬编要么就毫无规则的在页面中进行穿插,遇到要设置间距甚至直接写多个 ,我觉得还是要写出来给那些人看下。硬编的前提是只有你这一个界面使用。

    我们先来看下我们要实现的效果,功能需要:新增、修改、删除、查询、分页、排序、导出excel、打印、上传图片、支持表单验证,优雅的实现有多简单?非常简单。

需要用到哪些UI组件?我都是基于bootstrap这种扁平化响应式风格的,jquery.dataTables.js、toastr.js、bootstrapValidator.js、bootstrap-confirmation.js、printThis.js

由于是演示用,所以控制器中直接调用了EF上下文操作,重点是看前端部分的渲染和交互,不要重复你的代码!不要重复你的代码!不要重复你的代码!重要的事情说三遍!为什么没有用mvc自带的模型验证?答:太傻逼!1、样式改起来操蛋;2、每次要点击提交表单才促发验证。

这里表数据量少,是直接一次性加载,然后内存中分页的,如果表数据量多,那么就要用服务器分页,同样很简单。修改下配置项,如下所示:然后控制器中对应的方法稍微修改下即可。

options.bServerSide = true;,
options.fnServerParams = function (aoData) { //查询条件 aoData.push( { "name": "LogName", "value": $("#LogName").val() } ); };

 BaseController控制器基类

    [PublicAuthorize]
    public class BaseController : Controller
    {
        HomeService _HomeService = new HomeService();
        #region 字段

        /// <summary>
        /// 新增
        /// </summary>
        protected string CText = "新增";
        /// <summary>
        /// 读取
        /// </summary>
        protected string RText = "读取";
        /// <summary>
        /// 更新
        /// </summary>
        protected string UText = "更新";
        /// <summary>
        /// 删除
        /// </summary>
        protected string DText = "删除";
        /// <summary>
        /// 数据有误!
        /// </summary>
        protected string VoidText = "数据有误!";

        #endregion

        #region 属性
        /// <summary>
        /// 获取点击的菜单ID
        /// </summary>
        public string MenuId { get { return Request.QueryString["MenuId"]; } }
        /// <summary>
        /// 自动构建页面标题导航
        /// </summary>
        public MvchtmlString HeadString
        {
            get { return new MvcHtmlString(_HomeService.GetHead(int.Parse(MenuId))); }
        } 
        /// <summary>
        /// 构造非菜单页的界面导航标题
        /// </summary>
        /// <param name="title">页面标题</param>
        public void CreateSubPageHead(string title)
        {
            ViewBag.HeadString = HeadString;
            ViewBag.MenuId = MenuId;
            ViewBag.SubHeadString = title; 
        }
        #endregion
        [HttpGet]
        public virtual ActionResult Index()
        {
            if (!string.IsNullOrEmpty(MenuId))
            {
                ViewBag.MenuId = MenuId;
                ViewBag.HeadString = HeadString;
            }
            return View();
        }
        /// <summary>
        /// 操作成功
        /// </summary>
        /// <param name="message">提示文本</param>
        /// <returns></returns>
        protected virtual AjaxResult SuccessTip(string message)
        {
            return new AjaxResult { state = ResultType.success.ToString(), message = message };
        }
        /// <summary>
        /// 操作失败
        /// </summary>
        /// <param name="message">提示文本</param>
        /// <returns></returns>
        protected virtual AjaxResult ErrorTip(string message)
        {
            return new AjaxResult { state = ResultType.error.ToString(), message = message };
        }
    }
View Code

控制器DefaultController

    public class DefaultController : BaseController
    {
        private MyContext db = new MyContext();
        /// <summary>
        /// 客户列表
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult List(Customer filter)
        {
            //filter.PageSize = int.MaxValue;
            IQueryable<Customer> dataSource = db.Customers;

            if (!string.IsNullOrEmpty(filter.Name))
            {
                dataSource = dataSource.Where(x => x.Name == filter.Name).OrderBy(x => x.CreateTime);
            }

            List<Customer> queryData = dataSource.ToList();

            var data = queryData.Select(u => new
            {
                ID = u.Id,
                Name = u.Name,
                CreateTime = u.CreateTime.ToDateStr(),
                Address = u.Address
            });

            //构造成Json的格式传递
            var result = new { iTotalRecords = queryData.Count, iTotalDisplayRecords = 10, data = data };
            return Json(result, JsonRequestBehavior.AllowGet);
        }
        #region CRUD
        [HttpGet]
        public ActionResult Create()
        {
            return View();
        }
        [HttpPost]
        public JsonResult Create([Bind(Include = "Name,Address,CreateTime,Msg,HeadsUrl")] Customer _Customer)
        {
            AjaxResult _AjaxResult = null;
            if (ModelState.IsValid)
            {
                db.Customers.Add(_Customer);
                _AjaxResult = db.SaveChanges() > 0 ? SuccessTip(string.Format("{0}成功!", CText)) : ErrorTip(string.Format("{0}失败!", CText)); ;
            }
            else
            {
                _AjaxResult = ErrorTip(VoidText);
            }
            return Json(_AjaxResult, JsonRequestBehavior.AllowGet);
        }

        [HttpGet]
        public ActionResult Update(int Id)
        {
            var model = db.Customers.Where(x => x.Id == Id).FirstOrDefault();
            return View(model);
        }
        [HttpPost]
        public JsonResult Update([Bind(Include = "Id,Name,Address,CreateTime,Msg,HeadsUrl")] Customer _Customer)
        {
            AjaxResult _AjaxResult = null;
            if (ModelState.IsValid)
            {
                db.Entry(_Customer).State = EntityState.Modified;
                _AjaxResult = db.SaveChanges() > 0 ? SuccessTip(string.Format("{0}成功!", UText)) : ErrorTip(string.Format("{0}失败!", UText));
            }
            else
            {
                _AjaxResult = ErrorTip(VoidText);
            }
            return Json(_AjaxResult, JsonRequestBehavior.AllowGet);
        }
        [HttpPost]
        public JsonResult Delete(int Id)
        {
            var model = db.Customers.Where(x => x.Id == Id).FirstOrDefault();
            db.Customers.Remove(model);
            AjaxResult _AjaxResult = db.SaveChanges() > 0 ? SuccessTip(string.Format("{0}成功!", DText)) : ErrorTip(string.Format("{0}失败!", DText));

            return Json(_AjaxResult, JsonRequestBehavior.AllowGet);
        }
        [HttpPost]
        public JsonResult DeleteList(List<int> ids)
        {
            var list = db.Customers.Where(x => ids.Contains(x.Id)).ToList();
            db.Customers.RemoveRange(list);
            AjaxResult _AjaxResult = db.SaveChanges() > 0 ? SuccessTip(string.Format("{0}成功!", DText)) : ErrorTip(string.Format("{0}失败!", DText));

            return Json(_AjaxResult, JsonRequestBehavior.AllowGet);
        }

        #endregion

        #region File handle
        /// <summary>
        /// 导出Excel
        /// </summary>
        /// <returns></returns>
        public FileResult ExportExcel()
        {
            string excelPath = Server.MapPath("~/Excel/用户列表.xls");
            GenerateExcel genExcel = new GenerateExcel();
            genExcel.SheetList.Add(new UserListSheet(db.Customers.ToList(), "用户列表"));
            genExcel.ExportExcel(excelPath);
            return File(excelPath, "application/ms-excel", "用户列表.xls");
        }
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <returns></returns>
        public JsonResult ExportFile()
        {
            HttpPostedFileBase file = Request.Files["txt_file"];
            uploadFile _uploadFile = new uploadFile();

            if (file != null)
            {
                string str = DateTime.Now.ToString("yyyyMMddhhMMss");
                var fileFullName =string.Format("{0}{1}_{2}",Request.MapPath("~/Upload/"),str ,file.FileName);
                try
                {
                    file.SaveAs(fileFullName);
                    _uploadFile.state = 1;
                }
                catch
                {
                    _uploadFile.state = 0;
                }
                finally
                {
                    _uploadFile.name = str+"_"+file.FileName;
                    _uploadFile.fullName = fileFullName;
                }
            }
            else
            {
                _uploadFile.state = 0;
            }
            return Json(_uploadFile, JsonRequestBehavior.AllowGet);
        }
        /// <summary>
        /// 删除文件
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public JsonResult DeleteFile(string key)
        {
            var fileFullName = Path.Combine(Request.MapPath("~/Upload"), key);
            int state = 0;
            try
            {
                state = FileHelper.DeleteFile(fileFullName) ? 1 : 0;
                //var model = db.Customers.Where(x => x.HeadsUrl == key).FirstOrDefault();
                //if(model!=null)
                //{
                //    db.Customers.Remove(model);
                //}
            }
            catch
            {
                state = 0;
            }
            return Json(state, JsonRequestBehavior.AllowGet);
        } 

        #endregion
    }
View Code

视图页面,razor、css、js都分离,不要放到一个文件中。

Index视图:

@model List<Secom.Smp.Data.Models.Customer>
@{
    ViewBag.Title = "用户列表";
    ViewBag.ParentTitle = "系统管理";
    Layout = "~/Views/Shared/_Page.cshtml";
}
<style type="text/css">
    .divModal {
        width: 700px;
    }
</style>
<div class="page-content-body">
    <div class="row">
        <div class="col-md-12">
            <!-- BEGIN EXAMPLE TABLE PORTLET-->
                <div class="portlet-title">
                    <div class="caption font-dark">
                        <i class="icon-settings font-dark"></i>
                        <span class="caption-subject bold uppercase">用户列表</span>
                    </div>
                    <div class="actions">
                       
                    </div>
                </div>
                <div class="portlet-body">
                    <div class="table-toolbar">
                        <div class="row">
                            <div class="col-md-6">
                                <div class="btn-group">
                                    <button id="btnAdd" class="btn sbold green" onclick="DataTablesObj.doCreateModal(\'/Admin/Default/Create\')" data-toggle="modal">添加用户<i class="fa fa-plus"></i></button>
                                    <button id="btnDeleteList" title="确定要删除吗?" class="btn sbold btn-danger deleteBtn" data-toggle="confirmation" data-placement="right" data-btn-ok-label="继续" data-btn-ok-icon="icon-like" data-btn-ok-class="btn-success" data-btn-cancel-label="取消"
                                            data-btn-cancel-icon="icon-close" data-btn-cancel-class="btn-danger">
                                        批量删除
                                        <i class="fa fa-minus"></i>
                                    </button>
                                </div>
                            </div>
                            <div class="col-md-6">
                                <div class="btn-group pull-right">
                                    <button class="btn green  btn-outline dropdown-toggle" data-toggle="dropdown">
                                        操作
                                        <i class="fa fa-angle-down"></i>
                                    </button>
                                    <ul class="dropdown-menu pull-right">
                                        <li>
                                            <a href="/Admin/Default/ExportExcel" target=\'_blank\' class="fa fa-file-excel-o"><span style="margin-left:10px;"> 导出Excel </span></a>
                                        </li>
                                        <li>
                                            <a href="#" class="fa fa-file-excel-o" id="printView"><span style="margin-left:10px;"> 打印预览</span></a>
                                        </li>
                                    </ul>
                                </div>

                            </div>
                        </div>
                    </div>
                    <table class="table table-striped table-bordered table-hover table-checkable order-column" id="table_local"></table>
                </div>
            <!--模态弹窗-->
            <div class="modal fade" id="defaultModal" tabindex="-1" role="dialog" aria-labelledby="defaultModalLabel" aria-hidden="true">
                <div class="modal-dialog divModal" role="document">
                    <div class="modal-content">
                    </div>
                </div>
            </div>
            <!-- END EXAMPLE TABLE PORTLET-->
        </div>       
        </div>
</div>
@section scripts
{
<script src="@Html.ScriptsPath("lib/printThis.js")"></script>
}
View Code

Create视图:

@model Secom.Smp.Data.Models.Customer
@{
    ViewBag.Title = "Create";
    Layout = "~/Views/Shared/_Form.cshtml";
}
<div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
    <h4 class="modal-title" id="defaultModalLabel">添加用户</h4>
</div>
@using (Html.BeginForm("Create", "Default", new { area = "Admin" }, FormMethod.Post, new { @id = "defaultForm" }))
            {
    <div class="modal-body">
        <div class="row">
            <div class="col-md-5">
                    <div class="form-group">
                        @Html.LabelFor(x => x.HeadsUrl,new { @class = "control-label" }):
                        <input type="file" id="txt_file" name="txt_file" class="file-loading" accept="image/*" />
                        @Html.HiddenFor(x=>x.HeadsUrl,new { @id = "hidFileUrl" })
                    </div>
                </div>
            <div class="col-md-7">
                <div class="form-group">
                    @Html.LabelFor(x => x.Name, new { @class = "control-label" }):
                    @Html.TextBoxFor(x => x.Name, new { @id = "Name", @placeholder = "请输入用户名", @class = "form-control" })
                </div>
                <div class="form-group">
                    @Html.LabelFor(x => x.Address, new { @class = "control-label" }):
                    @Html.TextBoxFor(x => x.Address, new { @id = "Address", @placeholder = "请输入地址", @class = "form-control" })
                </div>
                <div class="form-group">
                    @Html.LabelFor(x => x.CreateTime):
                    <div class="input-group input-medium date date-picker">
                        @Html.TextBoxFor(x => x.CreateTime, new { @class = "form-control", @readonly = true })
                        <span class="input-group-btn">
                            <button class="btn default" type="button">
                                <i class="fa fa-calendar"></i>
                            </button>
                        </span>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">关闭[MVC&Core]ASP.NET Core MVC 视图传值入门

构建ASP.NET MVC4&JQuery&AJax&JSon示例

如何构建ASP.NET MVC4&JQuery&AJax&JSon示例

ASP.NET MVC & JQuery 动态表单内容

解读ASP.NET 5 & MVC6系列:核心技术与环境配置

Microsoft 'Identity Platform' 是不是(轻松)与'(ASP.NET) Identity Framework' - MVC5 & .NET 4.7.2 集成?