1. 程式人生 > >ASP.NET MVC 5 SmartCode Scaffolding for Visual Studio.Net

ASP.NET MVC 5 SmartCode Scaffolding for Visual Studio.Net

ef6 click params open protect block javascrip ctr chang

介紹

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:[email protected],微信: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<OrderDetail>(); } [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<OrderDetail> 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 ‘<a onclick="showDetailsWindow(‘ + row.Id + ‘)" class="easyui-linkbutton" href="javascript:void(0)">查看明細</a>‘;

 }
 //彈出明細信息
 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 Task<ActionResult> GetData(int page = 1, int rows = 10, string sort = "Id", string order = "asc", string filterRules = "")
        {
            var filters = JsonConvert.DeserializeObject<IEnumerable<filterRule>>(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 Task<ActionResult> SaveData(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 Task<ActionResult> GetOrders(string q = "")
        {
            var orderRepository = _unitOfWork.RepositoryAsync<Order>();
            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 Task<ActionResult> GetProducts(string q = "")
        {
            var productRepository = _unitOfWork.RepositoryAsync<Product>();
            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 Task<ActionResult> Details(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 http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Create([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 Task<ActionResult> PopupEdit(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 Task<ActionResult> Edit(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 http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Edit([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 => 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/Delete/5
        public async Task<ActionResult> Delete(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/Delete/5
        [HttpPost, ActionName("Delete")]
        //[ValidateAntiForgeryToken]
        public async Task<ActionResult> DeleteConfirmed(int id)
        {
            var order = await _orderService.FindAsync(id);
            _orderService.Delete(order);
            await _unitOfWork.SaveChangesAsync();
            if (Request.IsAjaxRequest())
            {
                return Json(new { success = true }, JsonRequestBehavior.AllowGet);
            }
            DisplaySuccessMessage("Has delete a Order record");
            return RedirectToAction("Index");
        }
        // Get Detail Row By Id For Edit
        // Get : Orders/EditOrderDetail/:id
        [HttpGet]
        public async Task<ActionResult> EditOrderDetail(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            var orderdetailRepository = _unitOfWork.RepositoryAsync<OrderDetail>();
            var orderdetail = await orderdetailRepository.FindAsync(id);
            var orderRepository = _unitOfWork.RepositoryAsync<Order>();
            var productRepository = _unitOfWork.RepositoryAsync<Product>();
            if (orderdetail == null)
            {
                ViewBag.OrderId = new SelectList(await orderRepository.Queryable().ToListAsync(), "Id", "Customer");
                ViewBag.ProductId = new SelectList(await productRepository.Queryable().ToListAsync(), "Id", "Name");
                //return HttpNotFound();
                return PartialView("_OrderDetailEditForm", new OrderDetail());
            }
            else
            {
                ViewBag.OrderId = new SelectList(await orderRepository.Queryable().ToListAsync(), "Id", "Customer", orderdetail.OrderId);
                ViewBag.ProductId = new SelectList(await productRepository.Queryable().ToListAsync(), "Id", "Name", orderdetail.ProductId);
            }
            return PartialView("_OrderDetailEditForm", orderdetail);
        }
        // Get Create Row By Id For Edit
        // Get : Orders/CreateOrderDetail
        [HttpGet]
        public async Task<ActionResult> CreateOrderDetail()
        {
            var orderRepository = _unitOfWork.RepositoryAsync<Order>();
            ViewBag.OrderId = new SelectList(await orderRepository.Queryable().ToListAsync(), "Id", "Customer");
            var productRepository = _unitOfWork.RepositoryAsync<Product>();
            ViewBag.ProductId = new SelectList(await productRepository.Queryable().ToListAsync(), "Id", "Name");
            return PartialView("_OrderDetailEditForm");
        }
        // Post Delete Detail Row By Id
        // Get : Orders/DeleteOrderDetail/:id
        [HttpPost, ActionName("DeleteOrderDetail")]
        public async Task<ActionResult> DeleteOrderDetailConfirmed(int id)
        {
            var orderdetailRepository = _unitOfWork.RepositoryAsync<OrderDetail>();
            orderdetailRepository.Delete(id);
            await _unitOfWork.SaveChangesAsync();
            if (Request.IsAjaxRequest())
            {
                return Json(new { success = true }, JsonRequestBehavior.AllowGet);
            }
            DisplaySuccessMessage("Has delete a Order record");
            return RedirectToAction("Index");
        }

        // Get : Orders/GetOrderDetailsByOrderId/:id
        [HttpGet]
        public async Task<ActionResult> GetOrderDetailsByOrderId(int id)
        {
            var orderdetails = _orderService.GetOrderDetailsByOrderId(id);
            if (Request.IsAjaxRequest())
            {
                var data = await orderdetails.AsQueryable().ToListAsync();
                var rows = data.Select(n => new { OrderCustomer = (n.Order == null ? "" : n.Order.Customer), ProductName = (n.Product == null ? "" : n.Product.Name), Id = n.Id, ProductId = n.ProductId, Qty = n.Qty, Price = n.Price, Amount = n.Amount, OrderId = n.OrderId });
                return Json(rows, JsonRequestBehavior.AllowGet);
            }
            return View(orderdetails);
        }

        //導出Excel
        [HttpPost]
        public ActionResult ExportExcel(string filterRules = "", string sort = "Id", string order = "asc")
        {
            var fileName = "orders_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx";
            var stream = _orderService.ExportExcel(filterRules, sort, order);
            return File(stream, "application/vnd.ms-excel", fileName);
        }
        private void DisplaySuccessMessage(string msgText)
        {
            TempData["SuccessMessage"] = msgText;
        }
        private void DisplayErrorMessage(string msgText)
        {
            TempData["ErrorMessage"] = msgText;
        }
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _unitOfWork.Dispose();
            }
            base.Dispose(disposing);
        }
    }

  

註冊UnityConfig.cs

        /// <summary>Registers the type mappings with the Unity container.</summary>
        /// <param name="container">The unity container to configure.</param>
        /// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to 
        /// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>
        public static void RegisterTypes(IUnityContainer container)
        {
              container.RegisterType<IRepositoryAsync<Order>, Repository<Order>>();
              container.RegisterType<IOrderService, OrderService>();

              container.RegisterType<IRepositoryAsync<OrderDetail>, Repository<OrderDetail>>();
              container.RegisterType<IOrderDetailService, OrderDetailService>();
        }

運行生成的代碼功能

技術分享圖片
Animation2-1.gif 技術分享圖片

以上功能一鍵生成帶帶主從表關聯的多表同時操作的頁面功能和後臺代碼,包括必填,長度等輸入校驗規則

基礎功能

即時聊天功能
系統賬號管理
菜單導航授權
Excel導入導出配置
枚舉值維護
系統日誌
消息通知

技術分享圖片
Animation8.gif

整個項目的系統架構和功能

主要組件

  • ”Microsoft.AspNet.Mvc” version="5.2.4"
  • “Microsoft.AspNet.Razor“ version="3.2.4"
  • "EasyUI" version="1.4.5"
  • "Hangfire" version="1.6.17"
  • "Unity.Mvc" version="5.0.13"
  • "Z.EntityFramework.Plus.EF6" version="1.7.15"
  • SmartAdmin - Responsive WebApp v1.9.1
  • "EntityFramework" version="6.2.0" 支持Oracle,MySql,Sql Server,PostgreSQL,SQLite,Sybase等


    技術分享圖片
    image.png

實戰項目

x-TMS

技術分享圖片
Animation4.gif


供應鏈協同平臺

技術分享圖片
Animation5.gif


MES系統

技術分享圖片
Animation6.gif

我們還能做

承接企業內部業務系統開發,組建企業私有雲,虛擬化集群服務器部署。
承接BizTalk B2B/EAI/EDI/AS/RosettaNet 開發工作

聯系方式

技術分享圖片
image.png

捐助

如果這個項目對您有用,我們歡迎各方任何形式的捐助,也包括參與到項目代碼更新或意見反饋中來。謝謝!

資金捐助:

技術分享圖片
image.png

License

ASP.NET MVC 5 SmartCode Scaffolding for Visual Studio.Net