目录
- ASP.NET MVC搭建项目后台UI框架—1、后台主框架
- ASP.NET MVC搭建项目后台UI框架—2、菜单特效
- ASP.NET MVC搭建项目后台UI框架—3、面板折叠和展开
- ASP.NET MVC搭建项目后台UI框架—4、tab多页签支持
- ASP.NET MVC搭建项目后台UI框架—5、Demo演示Controller和View的交互
- ASP.NET MVC搭建项目后台UI框架—6、客户管理(添加、修改、查询、分页)
- ASP.NET MVC搭建项目后台UI框架—7、统计报表
- ASP.NET MVC搭建项目后台UI框架—8、将View中选择的数据行中的部分数据传入到Controller中
- ASP.NET MVC搭建项目后台UI框架—9、服务器端排序
接着之前未写完的继续,本篇,我将讲解在此UI框架中和ASP.NET MVC4进行结合开发。效果如下:
这里,我将添加和修改用了两个不同的视图,当然也可以把添加和修改放到同一个视图中,但是要写一些业务逻辑代码来区分当前调用的是修改还是添加,根据添加和修改的不同,而对界面进行不同的操作。
添加控制器Customer,关于更新操作,我就不得不想吐槽一下NHibernate,他妹的,每次都要先load一次,然后再Update()一次,如果你直接save,它就把你表中有,但是界面上没有传过来的值全部更新为null了,相比之下EF就好多了。
public class CustomerController : Controller { private string message = ""; //消息,是否关闭弹出窗,是否停留在当前分页(0,1) #region 客户管理主页 public ActionResult Index() { return View(); } ////// 客户列表 /// /// /// [HttpPost] public JsonResult List(CustomerFilter filter) { filter.PageSize = int.MaxValue; var dataSource = CustomerInfo.GetByFilter(filter); List queryData = dataSource.ToList(); var data = queryData.Select(u => new { ID = u.ID, CusCode = u.CusCode, CusName = u.CusName, BusssinessType = u.BusssinessType.GetDescription(false), Balance = u.Balance, CreditAmount = u.CreditAmount, Status = u.Status.GetDescription(false), Country = u.Country, CompanyName = u.CompanyName, Delivery = GetDeliveryList(u.ExpressCurInfoBy) }); //构造成Json的格式传递 var result = new { iTotalRecords = queryData.Count, iTotalDisplayRecords = 10, data = data }; return Json(result, JsonRequestBehavior.AllowGet); } #region 添加客户 /// /// 添加客户 /// /// /// public ActionResult AddCustomer() { ViewBag.Title = "添加客户"; return View(); } /// /// 添加客户 /// /// /// [HttpPost] public ActionResult AddCustomer(CustomerInfo info) { string msg = string.Empty; if (ModelState.IsValid) { try { info.Save(); msg = "添加客户成功。"; } catch (Exception ex) { msg = "添加客户失败!" + ex.Message; ViewBag.Msg = string.Format(message, msg, false,"0"); } ViewBag.Msg = string.Format(message, msg, true,"0"); } return View(); } #endregion #region 修改客户 /// /// 修改客户 /// /// /// public ActionResult UpdateCustomer(int id) { ViewBag.Title = "修改客户"; var result = CustomerInfo.Load(id); return View(result); } /// /// 修改客户 /// /// /// [HttpPost] public ActionResult UpdateCustomer(CustomerInfo info) { string msg = string.Empty; if (ModelState.IsValid) { try { info.Update(); msg = "修改客户成功。"; } catch (Exception ex) { msg = "修改客户失败!" + ex.Message; ViewBag.Msg = string.Format(message, msg, false,"1"); } ViewBag.Msg = string.Format(message, msg, true,"1"); } return View(); } #endregion }
添加视图Index
@{ ViewBag.Title = "客户信息"; } <link href="~/libs/DataTables-1.10.6/media/css/jquery.dataTablesNew.css" rel="stylesheet" /> <script src="~/libs/DataTables-1.10.6/media/js/jquery.dataTables.min.js">script> <script src="~/Scripts/DataTablesExt.js">script> <script type="text/javascript"> //弹出框 var addDG, updateDG, matchDG; var w = 424, h = 520; //宽,高 //添加记录 function showPublishWin() { addDG = new $.dialog({ id: "AddChannel", title: "添加客户", content: "url:/Customer/AddCustomer", width: w, height: h, max: false, min: false, lock: true, close: true, btnBar: false }); addDG.show(); } //修改记录 function modifyRecord(id) { updateDG = new $.dialog({ id: "UpdateCustomer", title: "修改客户", content: "url:/Customer/UpdateCustomer/" + id, width: w, height: h, max: false, min: false, lock: true, close: true, btnBar: false }); updateDG.show(); } //隐藏弹出框 function hidePublishWin(msg, result, isStay) { var icon = "success.gif"; if (result == "False") { icon = "error.gif"; } $.dialog({ title: "提示", icon: icon, titleIcon: 'lhgcore.gif', content: msg, lock: true, ok: true }); if (result != "False") { if (addDG) { addDG.close(); } if (updateDG) { updateDG.close(); } if (matchDG) { matchDG.close(); } if (isStay == 0) { reloadList(); } else { reloadListNew(); } } } function matchDelivery(id) { matchDG = new $.dialog({ id: "UpdateCustomer", title: "客户匹配", content: "url:/Customer/DeliveryMatching/" + id, width: 800, height: h, max: false, min: false, lock: true, close: true, btnBar: false }); matchDG.show(); } //刷新,但是停留在当前分页 function reloadListNew() { var tables = $('#table_local').dataTable().api();//获取DataTables的Api,详见 http://www.datatables.net/reference/api/ tables.ajax.reload(null,false); } script> <script type="text/javascript"> $(function () { var h = $(document).height() - 258; var table = $("#table_local").dataTable({ bProcessing: true, "scrollY": h, "scrollCollapse": "true", "dom": 'ftr<"bottom"lip><"clear">', "bServerSide": false, //指定从服务器端获取数据 sServerMethod: "POST", sAjaxSource: "@Url.Action("List", "Customer")", "fnServerParams": function (aoData) { //查询条件 aoData.push( { "name": "CusCode", "value": $("#CusCode").val() }, { "name": "CusName", "value": $("#CusName").val() } ); }, columns: [{ title: "1", "visible": false, "data": "ID" }, { "data": "CusCode", title: "客户代码" }, { "data": "CusName", title: "客户名称" }, { "data": "BusssinessType", title: "业务类型", width: "100" }, { "data": "Country", title: "国家", width: "200" }, { "data": "CompanyName", title: "公司名称", width: "200" }, { "data": "Delivery", title: "收货商", width: "150" }, { "data": "Balance", title: "账户余额", width: "150" }, { "data": "CreditAmount", title: "信用额度", width: "150" }, { "data": "Status", title: "是否启用", width: "100" }, { "data": "ID", orderable: false, title: "操作", width: "140", "render": function (data, type, row, meta) { //自定义列 var re = ""; return re; } } ], paging: true,//分页 ordering: true,//是否启用排序 searching: true,//搜索 language: { "sProcessing": "处理中...", lengthMenu: '每页显示:' + '' + '' + '' + '' + '' + '' + '' + '',//左上角的分页大小显示。 search: '搜索:',//右上角的搜索文本,可以写html标签 paginate: {//分页的样式内容。 previous: "上一页", next: "下一页", first: "", last: "" }, zeroRecords: "暂无记录",//table tbody内容为空时,tbody的内容。 //下面三者构成了总体的左下角的内容。 info: "总共 (_PAGES_) 页,显示 _START_ -- _END_ ,共 (_TOTAL_) 条",//左下角的信息显示,大写的词为关键字。初始_MAX_ 条 infoEmpty: "0条记录",//筛选为空时左下角的显示。 infoFiltered: ""//筛选之后的左下角筛选提示, }, pagingType: "full_numbers"//分页样式的类型 }); //设置选中行样式 $('#table_local tbody').on('click', 'tr', function () { if ($(this).hasClass('selected')) { $(this).removeClass('selected'); } else { table.$('tr.selected').removeClass('selected'); $(this).addClass('selected'); } }); }); //查询 刷新 function reloadList() { var tables = $('#table_local').dataTable().api();//获取DataTables的Api,详见 http://www.datatables.net/reference/api/ tables.ajax.reload(); } script> <div class="areabx clear"> @using (Html.BeginForm("List", null, FormMethod.Get, new { @clase = "form-inline", @role = "form" })) { <div class="areabx_header">客户信息div> <ul class="formod mgt10"> <li><span>客户代码:span>@Html.TextBox("CusCode", "", new { @class = "trade-time wid153" })li> <li><span>客户名称:span>@Html.TextBox("CusName", "", new { @class = "trade-time" })li> <li>li> ul> <div class="botbtbx pdb0" style="margin-bottom: -30px;"> <input type="button" value="添加客户" class="btn btn-primary" onclick="showPublishWin()" /> <input type="button" value="查询" onclick="reloadList();" class="btn btn-primary"> div> } <div class="tob_box mgt15"> <table id="table_local" class="display" cellspacing="0" cellpadding="0" border="0" style="width: 100%"> table> div> div>
添加AddCustomer视图,之前公司ASP.NET MVC的项目没有启用模型验证,界面验证代码都是自己js写的,我晕,那用ASP.NET MVC干嘛呢?使用框架就是要充分发挥框架优良的功能,尽可能高效快速的开发,并减少开发人员的代码量。
@model Core.Customer.CustomerInfo @using ProjectBase.Utils @Html.Raw(ViewBag.Msg) <div class="areabx clear"> @* <div class="areabx_header">@ViewBag.Titlediv>*@ <div class="tian_xi"> @using (Html.BeginForm("AddCustomer", "Customer", FormMethod.Post, new { @clase = "form-inline", @role = "form", name = "from1" })) { <table width="100%" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr style="height: 40px;"> <td style="width: 120px; text-align: right;">客户代码:td> <td> @Html.TextBoxFor(x => x.CusCode, new { @class = "trade-timen", @id = "cusCode" })<span class="wtps">* @Html.ValidationMessageFor(m => m.CusCode)span>td> tr> <tr style="height: 40px;"> <td align="right">客户名称:td> <td> @Html.TextBoxFor(x => x.CusName, new { @class = "trade-timen", @id = "cusName" })<span class="wtps">* @Html.ValidationMessageFor(m => m.CusName)span>td> tr> <tr style="height: 40px;"> <td align="right">手机:td> <td> @Html.TextBoxFor(x => x.Phone, new { @class = "trade-timen" })td> tr> <tr style="height: 40px;"> <td align="right">电话:td> <td> @Html.TextBoxFor(x => x.Tel, new { @class = "trade-timen" })td> tr> <tr style="height: 40px;"> <td align="right">邮箱:td> <td> @Html.TextBoxFor(x => x.Email, new { @class = "trade-timen", @id = "email" })<span class="wtps">@Html.ValidationMessageFor(m => m.Email)span>td> tr> <tr style="height: 40px;"> <td align="right">传真:td> <td> @Html.TextBoxFor(x => x.Fax, new { @class = "trade-timen" })td> tr> <tr style="height: 40px;"> <td align="right">国家:td> <td> @Html.TextBoxFor(x => x.Country, new { @class = "trade-timen" })td> tr> <tr style="height: 40px;"> <td align="right">地址:td> <td> @Html.TextBoxFor(x => x.Address, new { @class = "trade-timen" })td> tr> <tr style="height: 40px;"> <td align="right">公司名称:td> <td> @Html.TextBoxFor(x => x.CompanyName, new { @class = "trade-timen" })td> tr> <tr style="height: 40px;"> <td align="right">业务类型:td> <td> @Html.DropDownListFor(x => x.BusssinessType, @Html.EnumToList(typeof(Core.Customer.Busssiness), false), new { @class = "trade-timen", style = "width:180px" }) tr> <tr style="height: 40px;"> <td align="right">是否启用:td> <td>是 @Html.RadioButtonFor(x => x.Status, "0", new { Checked = "checked", @name = "status" }) <span class="radioMagin">否 @Html.RadioButtonFor(x => x.Status, "1", new { @name = "status" })span>td> tr> tbody> table> <input type="submit" value="确定" class="popbtn1 mg"> <input type="button" value="关闭" class="popbtn3 mg2" onclick="frameElement.api.opener.addDG.close();" /> } div> div>
添加UpdateCustomer视图
@model Core.Customer.CustomerInfo @using ProjectBase.Utils @Html.Raw(ViewBag.Msg) <div class="areabx clear"> @* <div class="areabx_header">@ViewBag.Titlediv>*@ <div class="tian_xi"> @using (Html.BeginForm("UpdateCustomer", "Customer", FormMethod.Post, new { @clase = "form-inline", @role = "form", name = "from1" })) { <table width="100%" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr style="height: 40px;"> <td style="width: 120px; text-align: right;">客户代码:td> <td> @Html.TextBoxFor(x => x.CusCode, new { @class = "trade-timen", @id = "cusCode", @readOnly = "readOnly" })<span class="wtps">* @Html.ValidationMessageFor(m => m.CusCode)span>td> @Html.HiddenFor(x => x.ID) tr> <tr style="height: 40px;"> <td align="right">客户名称:td> <td> @Html.TextBoxFor(x => x.CusName, new { @class = "trade-timen", @id = "cusName" })<span class="wtps">* @Html.ValidationMessageFor(m => m.CusName)span>td> tr> <tr style="height: 40px;"> <td align="right">手机:td> <td> @Html.TextBoxFor(x => x.Phone, new { @class = "trade-timen" })td> tr> <tr style="height: 40px;"> <td align="right">电话:td> <td> @Html.TextBoxFor(x => x.Tel, new { @class = "trade-timen" })td> tr> <tr style="height: 40px;"> <td align="right">邮箱:td> <td> @Html.TextBoxFor(x => x.Email, new { @class = "trade-timen", @id = "email" }) <span class="wtps">@Html.ValidationMessageFor(m => m.Email)span>td> tr> <tr style="height: 40px;"> <td align="right">传真:td> <td> @Html.TextBoxFor(x => x.Fax, new { @class = "trade-timen" })td> tr> <tr style="height: 40px;"> <td align="right">国家:td> <td> @Html.TextBoxFor(x => x.Country, new { @class = "trade-timen" })td> tr> <tr style="height: 40px;"> <td align="right">地址:td> <td> @Html.TextBoxFor(x => x.Address, new { @class = "trade-timen" })td> tr> <tr style="height: 40px;"> <td align="right">公司名称:td> <td> @Html.TextBoxFor(x => x.CompanyName, new { @class = "trade-timen" })td> tr> <tr style="height: 40px;"> <td align="right">业务类型:td> <td> @Html.DropDownListFor(x => x.BusssinessType, @Html.EnumToList(typeof(Core.Customer.Busssiness), false), new { @class = "trade-timen", style = "width:180px" }) tr> <tr style="height: 40px;"> <td align="right">是否启用:td> <td>是 @Html.RadioButtonFor(x => x.Status, "0", new { Checked = "checked", @name = "status" }) <span class="radioMagin">否 @Html.RadioButtonFor(x => x.Status, "1", new { @name = "status" })span>td> tr> tbody> table> <input type="submit" value="确定" class="popbtn1 mg"> <input type="button" value="关闭" class="popbtn3 mg2" onclick="frameElement.api.opener.updateDG.close();" /> } div> div>
客户实体CustomerInfo
////// 客户信息 /// public class CustomerInfo //: DomainObject { #region property /// /// 客户代码 /// [Required(ErrorMessage = "客户代码不能为空!")] [StringLength(30, MinimumLength = 0, ErrorMessage = "客户代码最大长度为30个字符")] public virtual string CusCode { get; set; } /// /// 客户名称 /// [Required(ErrorMessage = "客户名称不能为空!")] [StringLength(30, MinimumLength = 0, ErrorMessage = "客户名称最大长度为30个字符")] public virtual string CusName { get; set; } /// /// 客户业务类型 /// public virtual Busssiness BusssinessType { get; set; } /// /// 手机 /// public virtual string Phone { get; set; } /// /// 电话 /// public virtual string Tel { get; set; } /// /// 邮箱 /// [RegularExpression(@"^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$", ErrorMessage="邮箱格式不正确!")] public virtual string Email { get; set; } /// /// 传真 /// public virtual string Fax { get; set; } /// /// 国家 /// public virtual string Country { get; set; } /// /// 地址 /// public virtual string Address { get; set; } /// /// 公司名称 /// public virtual string CompanyName { get; set; } /// /// 金额 /// public virtual decimal Balance { get; set; } /// /// 信用额度 /// public virtual decimal CreditAmount { get; set; } /// /// 状态 /// public virtual CustomerStatus Status { get; set; } /// /// 快件收货商信息 /// public virtual IList ExpressCurInfoBy { get; set; } #endregion #region common method /// /// 分页获取数据 /// /// /// public static IPageOfList GetByFilter(CustomerFilter filter) { return Dao.GetByFilter(filter); } #endregion }
查询类CustomerFilter
public class CustomerFilter : ParameterFilter { ////// 客户代码 /// public virtual string CusCode { get; set; } /// /// 客户名称 /// public virtual string CusName { get; set; } /// /// 生产NHQL查询语句 /// /// public override string ToHql() { string hql = ""; if (!string.IsNullOrEmpty(CusCode)) { hql += " and Cus_Code =:CusCode "; } if (!string.IsNullOrEmpty(CusName)) { hql += " and Cus_Name =:CusName "; } return hql; } /// /// 构造查询参数 /// /// public override Dictionary<string, object> GetParameters() { var result = new Dictionary<string, object>(); if (!string.IsNullOrEmpty(CusCode)) { result["CusCode"] = CusCode.Trim(); } if (!string.IsNullOrEmpty(CusName)) { result["CusName"] = CusName.Trim(); } return result; } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using ProjectBase.Utils.Entities; namespace ProjectBase.Data { public abstract class ParameterFilter { public ParameterFilter() { HasQueryString = false; PageSize = 10; } public string OrderBy { get;set; } public abstract string ToHql(); public override string ToString() { return ToHql(); } public abstract Dictionary<string, object> GetParameters(); public string GetOrderString() { if (OrderBy.HasValue()) return " Order By " + OrderBy; return String.Empty; } protected string GetLike(string value) { return "%" + value + "%"; } public int PageIndex { get; set; } public int PageSize { get; set; } /// /// 标识此构造器是包含全部查询语句。 /// 若为 False,则ToHql() 只需要构造条件查询,系统会自动在前面加上 " from " + typeof(T).Name + " a where 1=1 " /// 若为 True, ToHql() 需要返回 连form在类的完整Hql语句 /// public bool HasQueryString { get; set; } protected static bool HasValue(string str) { return str.HasValue(); } public static bool HasValue
(System.Nullable value) where T:struct { return value.HasValue; } } }
在这里,我只演示了控制器和视图的交互,至于Hhibernate和Unity等数据的操作,这里暂时不讲,因为你也可以使用其它的ORM框架和IOC框架,诸如EF、AutoFac等等。这里主要讲解jquery datatables和ASP.NET MVC的结合使用,但是这里只演示了客户端分页排序,后面我会讲服务器分页排序。我发现,网上都没有ASP.NET MVC和Datatables结合的完整的服务器分页、排序的Demo,只看到PHP的。于是我不断的尝试,皇天不负有心人,终于试验成功了,后面我会为大家讲述实现方式。