摘要:本文将带你了解WEBAPP开发ASP.NET MVC 5 SmartCode Scaffolding for Visual Studio.Net,希望本文对大家学WEBAPP有所帮助。
本文将带你了解WEBAPP开发ASP.NET MVC 5 SmartCode Scaffolding for Visual Studio.Net,希望本文对大家学WEBAPP有所帮助。
介绍
ASP.NET MVC 5 SmartCode Scaffolding是集成在Visual Studio.Net开发工具中一个ASP.NET MVC Web应用程序代码生成框架,使用SmartCode Scaffolding可以快速添加一整套View,Controller,Model,Service可以运行的交互式代码。减少程序员在系统开发过程中编写重复的代码行数(估计可以减少80%代码Coding),同时有助于团队成员遵循统一的架构和规范进行开发,就算没有接触过MVC的程序员也能快速的进行团队开发。大大减少对基础功能的debug的时间,提高软件项目的开发效率。
SmartCode Scaffolding是自定义扩展Visual Studio.Net ASP.NET Scaffolding并且实现了更多功能和生成更多的标准代码。非常适合快速原型法的开发过程。
该项目从2014年一直默默的在做版本更新和持续完善,从最早Visual Sutdio.Net 2013到最新2017。并且完全开源 GITHUB SmartCode Scaffolding
我的联系方式 QQ:28440117,email:new163@163.com,微信:neostwitter
我的主页:https://neozhu.github.io/WebSite/index.html
安装&使用
需要要配合Demo中WebApp 项目来生成代码,因为其中引用了大量的css和html模板
代码生成的过程
定义实体对象(Entity class)和属性
参考EntityFramewrok Code-First规范定义,定义的越规范,信息越多对后面的生成的代码就越完善。
下面代码定义一个Order,OrderDetail,一对多的关系,在创建Order类的Controller时会在controller,View,会根据关联的实体生成相应的代码,
比如EditView,会同时生成对表头Order form表单的操作和明细表OrderDetail的datagrid操作。
定义OrderDetail中引用了Product,多对一的关系。会在View部分生成Combox控件或DropdownList的控件和Controller层的查询方法。
//定义字段描述信息,字段长度,基本验证规则 public partial class Order:Entity { public Order() { OrderDetails = new HashSet(); } [Key] public int Id { get; set; } [Required] [Display(Name ="客户名称",Description ="订单所属的客户",Order =1)] [MaxLength(30)] public string Customer { get; set; } [Required] [Display(Name = "发货地址", Description = "发货地址", Order = 2)] [MaxLength(200)] public string ShippingAddress { get; set; } [Display(Name = "订单日期", Description = "订单日期默认当天", Order = 3)] public DateTime OrderDate { get; set; } //关联订单明细 1-* public virtual ICollection OrderDetails { get; set; } } public partial class OrderDetail:Entity { [Key] public int Id { get; set; } [Required(ErrorMessage = "必选")] [Display(Name ="商品", Description ="商品",Order =2)] public int ProductId { get; set; } [ForeignKey("ProductId")] [Display(Name = "商品", Description = "商品", Order = 3)] public Product Product { get; set; } [Required(ErrorMessage="必填")] [Range(1,9999)] [Display(Name = "数量", Description = "需求数量", Order = 4)] public int Qty { get; set; } [Required(ErrorMessage = "必填")] [Range(1, 9999)] [Display(Name = "单价", Description = "单价", Order = 5)] public decimal Price { get; set; } [Required(ErrorMessage = "必填")] [Range(1, 9999)] [Display(Name = "金额", Description = "金额(数量x单价)", Order = 6)] public decimal Amount { get; set; } [Display(Name = "订单号", Description = "订单号", Order = 1)] public int OrderId { get; set; } //关联订单表头 [ForeignKey("OrderId")] [Display(Name = "订单号", Description = "订单号", Order = 1)] public Order Order { get; set; } }
生成代码
添加controller
生成以下代码
Controllers\OrdersController.cs /* MVC控制类 */Repositories\Orders\OrderQuery.cs /* 定义与业务逻辑相关查询比如分页帅选,外键/主键查询 */Repositories\Orders\OrderRepository.cs /* Repository模式 */Services\Orders\IOrderService.cs /* 具体的业务逻辑接口 */Services\Orders\OrderService.cs /* 具体的业务逻辑实现 */Views\Orders\Index.cshtml /* 订单信息DataGrid包括查询/新增/删除/修改/导入/导出等功能 */Views\Orders\_PopupDetailFormView.cshtml /* 订单信息弹出编辑框 */Views\Orders\Create.cshtml /* 订单信息新增操作页面 */Views\Orders\Edit.cshtml /* 订单信息编辑操作页面 */Views\Orders\EditForm.cshtml /* 订单信息编辑表单 */
index.html javascript代码片段
var entityname = "Order"; //下载Excel导入模板 function downloadtemplate() { //TODO: 修改下载模板的路径 var url = "/ExcelTemplate/Order.xlsx"; $.fileDownload(url) .fail(function() { $.messager.alert("错误", "没有找到模板文件! {" + url + "}"); }); } //打开Excel上传导入 function importexcel() { $("#importwindow").window("open"); } //执行Excel到处下载 function exportexcel() { var filterRules = JSON.stringify($dg.datagrid("options").filterRules); //console.log(filterRules); $.messager.progress({ title: "正在执行导出!" }); var formData = new FormData(); formData.append("filterRules", filterRules); formData.append("sort", "Id"); formData.append("order", "asc"); $.postDownload("/Orders/ExportExcel", formData, function(fileName) { $.messager.progress("close"); console.log(fileName); }) } //显示帮助信息 function dohelp() { } //easyui datagrid 增删改查操作 var $dg = $("#orders_datagrid").datagrid({ rownumbers: true, checkOnSelect: true, selectOnCheck: true, idField: ‘Id‘, sortName: ‘Id‘, sortOrder: ‘desc‘, remoteFilter: true, singleSelect: true, toolbar: ‘#orders_toolbar‘, url: ‘/Orders/GetData‘, method: ‘get‘, onClickCell: onClickCell, pagination: true, striped: true, columns: [ [ /*{ field: ‘ck‘, checkbox: true },*/ { field: ‘_operate1‘, title: ‘操作‘, width: 120, sortable: false, resizable: true, formatter: showdetailsformatter }, /*{field:‘Id‘,width:80 ,sortable:true,resizable:true }*/ { field: ‘Customer‘, title: ‘@Html.DisplayNameFor(model => model.Customer)‘, width: 140, editor: { type: ‘textbox‘, options: { prompt: ‘客户名称‘, required: true, validType: ‘length[0,30]‘ } }, sortable: true, resizable: true }, { field: ‘ShippingAddress‘, title: ‘@Html.DisplayNameFor(model => model.ShippingAddress)‘, width: 140, editor: { type: ‘textbox‘, options: { prompt: ‘发货地址‘, required: true, validType: ‘length[0,200]‘ } }, sortable: true, resizable: true }, { field: ‘OrderDate‘, title: ‘@Html.DisplayNameFor(model => model.OrderDate)‘, width: 160, align: ‘right‘, editor: { type: ‘datebox‘, options: { prompt: ‘订单日期‘, required: true } }, sortable: true, resizable: true, formatter: dateformatter }, ] ] }); var editIndex = undefined; function reload() { if (endEditing()) { $dg.datagrid("reload"); } } function endEditing() { if (editIndex == undefined) { return true } if ($dg.datagrid("validateRow", editIndex)) { $dg.datagrid("endEdit", editIndex); editIndex = undefined; return true; } else { return false; } } function onClickCell(index, field) { var _operates = ["_operate1", "_operate2", "_operate3", "ck"] if ($.inArray(field, _operates) >= 0) { return; } if (editIndex != index) { if (endEditing()) { $dg.datagrid("selectRow", index) .datagrid("beginEdit", index); editIndex = index; var ed = $dg.datagrid("getEditor", { index: index, field: field }); if (ed) { ($(ed.target).data("textbox") ? $(ed.target).textbox("textbox") : $(ed.target)).focus(); } } else { $dg.datagrid("selectRow", editIndex); } } } function append() { if (endEditing()) { //$dg.datagrid("appendRow", { Status: 0 }); //editIndex = $dg.datagrid("getRows").length - 1; $dg.datagrid("insertRow", { index: 0, row: {} }); editIndex = 0; $dg.datagrid("selectRow", editIndex) .datagrid("beginEdit", editIndex); } } function removeit() { if (editIndex == undefined) { return } $dg.datagrid("cancelEdit", editIndex) .datagrid("deleteRow", editIndex); editIndex = undefined; } function accept() { if (endEditing()) { if ($dg.datagrid("getChanges").length) { var inserted = $dg.datagrid("getChanges", "inserted"); var deleted = $dg.datagrid("getChanges", "deleted"); var updated = $dg.datagrid("getChanges", "updated"); var effectRow = new Object(); if (inserted.length) { effectRow.inserted = inserted; } if (deleted.length) { effectRow.deleted = deleted; } if (updated.length) { effectRow.updated = updated; } //console.log(JSON.stringify(effectRow)); $.post("/Orders/SaveData", effectRow, function(response) { //console.log(response); if (response.Success) { $.messager.alert("提示", "提交成功!"); $dg.datagrid("acceptChanges"); $dg.datagrid("reload"); } }, "json").fail(function(response) { //console.log(response); $.messager.alert("错误", "提交错误了!", "error"); //$dg.datagrid("reload"); }); } //$dg.datagrid("acceptChanges"); } } function reject() { $dg.datagrid("rejectChanges"); editIndex = undefined; } function getChanges() { var rows = $dg.datagrid("getChanges"); alert(rows.length + " rows are changed!"); } //datagrid 开启筛选功能 $(function() { $dg.datagrid("enableFilter", [ { field: "Id", type: "numberbox", op: [‘equal‘, ‘notequal‘, ‘less‘, ‘lessorequal‘, ‘greater‘, ‘greaterorequal‘] }, { field: "OrderDate", type: "dateRange", options: { onChange: function(value) { $dg.datagrid("addFilterRule", { field: "OrderDate", op: "between", value: value }); $dg.datagrid("doFilter"); } } }, ]); }) //----------------------------------------------------- //datagrid onSelect //----------------------------------------------------- function showdetailsformatter(value, row, index) { return ‘查看明细‘; } //弹出明细信息 function showDetailsWindow(id) { //console.log(index, row); $.getJSON(‘/Orders/PopupEdit/‘ + id, function(data, status, xhr) { //console.log(data); $(‘#detailswindow‘).window(‘open‘); loadData(id, data); }); }
OrderController.cs 代码片段
public class OrdersController : Controller { //private StoreContext db = new StoreContext(); private readonly IOrderService _orderService; private readonly IUnitOfWorkAsync _unitOfWork; public OrdersController(IOrderService orderService, IUnitOfWorkAsync unitOfWork) { _orderService = orderService; _unitOfWork = unitOfWork; } // GET: Orders/Index [OutputCache(Duration = 360, VaryByParam = "none")] public ActionResult Index() { return View(); } // Get :Orders/PageList // For Index View Boostrap-Table load data [HttpGet] public async TaskGetData(int page = 1, int rows = 10, string sort = "Id", string order = "asc", string filterRules = "") { var filters = JsonConvert.DeserializeObject<IEnumerable>(filterRules); var totalCount = 0; //int pagenum = offset / limit +1; var orders = await _orderService .Query(new OrderQuery().Withfilter(filters)) .OrderBy(n => n.OrderBy(sort, order)) .SelectPageAsync(page, rows, out totalCount); var datarows = orders.Select(n => new { Id = n.Id, Customer = n.Customer, ShippingAddress = n.ShippingAddress, OrderDate = n.OrderDate }).ToList(); var pagelist = new { total = totalCount, rows = datarows }; return Json(pagelist, JsonRequestBehavior.AllowGet); } [HttpPost] public async TaskSaveData(OrderChangeViewModel orders) { if (orders.updated != null) { foreach (var item in orders.updated) { _orderService.Update(item); } } if (orders.deleted != null) { foreach (var item in orders.deleted) { _orderService.Delete(item); } } if (orders.inserted != null) { foreach (var item in orders.inserted) { _orderService.Insert(item); } } await _unitOfWork.SaveChangesAsync(); return Json(new { Success = true }, JsonRequestBehavior.AllowGet); } //[OutputCache(Duration = 360, VaryByParam = "none")] public async TaskGetOrders(string q = "") { var orderRepository = _unitOfWork.RepositoryAsync(); var data = await orderRepository.Queryable().Where(n => n.Customer.Contains(q)).ToListAsync(); var rows = data.Select(n => new { Id = n.Id, Customer = n.Customer }); return Json(rows, JsonRequestBehavior.AllowGet); } //[OutputCache(Duration = 360, VaryByParam = "none")] public async TaskGetProducts(string q = "") { var productRepository = _unitOfWork.RepositoryAsync(); var data = await productRepository.Queryable().Where(n => n.Name.Contains(q)).ToListAsync(); var rows = data.Select(n => new { Id = n.Id, Name = n.Name }); return Json(rows, JsonRequestBehavior.AllowGet); } // GET: Orders/Details/5 public async TaskDetails(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } var order = await _orderService.FindAsync(id); if (order == null) { return HttpNotFound(); } return View(order); } // GET: Orders/Create public ActionResult Create() { var order = new Order(); //set default value return View(order); } // POST: Orders/Create // To protect from overposting attacks, please enable the specific properties you want to bind to, for more details see //go.microsoft.com/fwlink/?LinkId=317598. [HttpPost] [ValidateAntiForgeryToken] public async TaskCreate([Bind(Include = "OrderDetails,Id,Customer,ShippingAddress,OrderDate,CreatedDate,CreatedBy,LastModifiedDate,LastModifiedBy")] Order order) { if (ModelState.IsValid) { order.ObjectState = ObjectState.Added; foreach (var item in order.OrderDetails) { item.OrderId = order.Id; item.ObjectState = ObjectState.Added; } _orderService.InsertOrUpdateGraph(order); await _unitOfWork.SaveChangesAsync(); if (Request.IsAjaxRequest()) { return Json(new { success = true }, JsonRequestBehavior.AllowGet); } DisplaySuccessMessage("Has append a Order record"); return RedirectToAction("Index"); } else { var modelStateErrors = String.Join("", this.ModelState.Keys.SelectMany(key => this.ModelState[key].Errors.Select(n => n.ErrorMessage))); if (Request.IsAjaxRequest()) { return Json(new { success = false, err = modelStateErrors }, JsonRequestBehavior.AllowGet); } DisplayErrorMessage(modelStateErrors); } return View(order); } // GET: Orders/PopupEdit/5 [OutputCache(Duration = 360, VaryByParam = "id")] public async TaskPopupEdit(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } var order = await _orderService.FindAsync(id); return Json(order, JsonRequestBehavior.AllowGet); } // GET: Orders/Edit/5 public async TaskEdit(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } var order = await _orderService.FindAsync(id); if (order == null) { return HttpNotFound(); } return View(order); } // POST: Orders/Edit/5 // To protect from overposting attacks, please enable the specific properties you want to bind to, for more details see //go.microsoft.com/fwlink/?LinkId=317598. [HttpPost] [ValidateAntiForgeryToken] public async TaskEdit([Bind(Include = "OrderDetails,Id,Customer,ShippingAddress,OrderDate,CreatedDate,CreatedBy,LastModifiedDate,LastModifiedBy")] Order order) { if (ModelState.IsValid) { order.ObjectState = ObjectState.Modified; foreach (var item in order.OrderDetails) { item.OrderId = order.Id; //set ObjectState with conditions if (item.Id <= 0) item.ObjectState = ObjectState.Added; else item.ObjectState = ObjectState.Modified; } _orderService.InsertOrUpdateGraph(order); await _unitOfWork.SaveChangesAsync(); if (Request.IsAjaxRequest()) { return Json(new { success = true }, JsonRequestBehavior.AllowGet); } DisplaySuccessMessage("Has update a Order record"); return RedirectToAction("Index"); } else { var modelStateErrors = String.Join("", this.ModelState.Keys.SelectMany(key =
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之WebApp频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号