尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
ASP.NET MVC 5 + Layui 快速搭建后台管理骨架
简介本资源是一套基于Asp.Net MVC框架与Layui前端UI的完整CRUD增删改查实战项目面向Web开发初学者及.NET全栈入门者聚焦MVC三层架构落地与前后端协同开发核心能力训练。压缩包共687个文件涵盖250个dll运行依赖与NuGet包、54个jsLayui交互逻辑与AJAX请求处理、30个cshtmlRazor视图模板、16个csModel与Controller核心代码、35个cssLayui主题样式及自定义界面以及config、xml、sqlite等配置与数据文件整体大小65.44MB。已有494人学习下载项目结构规范含Global.asax全局配置、WebApplication5.sln解决方案、User相关Model/Controller/View全套实现并集成分页、表单验证、弹窗编辑等实用功能。读者可直接运行调试深入理解Entity Framework数据操作、Layui组件调用、AJAX异步通信及MVC路由映射机制是掌握.NET Web开发基础工程实践的高复用参考样本。1. 一个能跑通、能改、能交差的 ASP.NET MVC Layui 后台管理 Demo不是教学模板是拿来就能填业务的真实骨架你刚接到一个内部系统需求要给销售部搭个客户信息录入页带搜索、分页、编辑弹窗下周就要演示。没时间从零搭框架又不敢直接套网上那些“ASP.NET MVC 教程源码”——点开一看Controller 里塞了 200 行硬编码 SQLView 里 jQuery 操作 DOM 像在写考古文献Layui 的 table 渲染连>!-- /web.config -- configuration connectionStrings !-- 必须修改此处本地 SQL Server Express 实例名请替换为你的实际实例名 -- add nameCustomerContext connectionStringData SourceYOUR-SQL-SERVER\SQLEXPRESS;Initial CatalogCustomerDB;Integrated SecurityTrue; providerNameSystem.Data.SqlClient / /connectionStrings system.web compilation debugtrue targetFramework4.7.2 / httpRuntime targetFramework4.7.2 / !-- 下面这行决定路由是否启用删除会导致所有 /Customer/* 404 -- pages namespaces add namespaceSystem.Web.Mvc / add namespaceSystem.Web.Mvc.Ajax / /namespaces /pages /system.web /configurationGlobal.asax.cs中路由注册是标准写法但注意routes.MapRoute的defaults参数// /Global.asax.cs public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute({resource}.axd/{*pathInfo}); routes.MapRoute( name: Default, url: {controller}/{action}/{id}, defaults: new { controller Home, action Index, id UrlParameter.Optional } ); }注意id UrlParameter.Optional是必须的。如果写成id 当点击“编辑”按钮传入/Customer/Edit/5时MVC 会因无法匹配路由而抛出HttpException错误信息是 “The resource cannot be found”非常误导人。3. 核心模块拆解从 CustomerController 到 customer.js一个请求的完整链路我们以“点击编辑按钮 → 弹窗加载表单 → 提交保存”为例追踪代码如何串联。这不是理论流程而是你调试时 F12 看 Network、断点打在 Controller 上的真实路径。3.1 CustomerControllerRESTful 风格的 Action 设计CustomerController.cs是纯业务逻辑中枢所有方法都遵循 MVC 最佳实践// /Controllers/CustomerController.cs public class CustomerController : Controller { private readonly CustomerContext db new CustomerContext(); // GET: /Customer/Index public ActionResult Index() { return View(); // 返回空 View数据由 customer.js 的 table.url 异步加载 } // GET: /Customer/Details/5 public ActionResult Details(int? id) { if (id null) return new HttpStatusCodeResult(HttpStatusCode.BadRequest); var customer db.Customers.Find(id); if (customer null) return HttpNotFound(); return View(customer); // 返回强类型 View供 Details.cshtml 使用 model Customer } // GET: /Customer/Create public ActionResult Create() { return View(); // 返回空表单 } // POST: /Customer/Create [HttpPost] [ValidateAntiForgeryToken] // 防 CSRFView 中必须有 Html.AntiForgeryToken() public ActionResult Create([Bind(Include Name,Email,Phone,Address)] Customer customer) { if (ModelState.IsValid) // 自动验证 DataAnnotations 特性 { db.Customers.Add(customer); db.SaveChanges(); return Json(new { success true, msg 添加成功 }); // 返回 JSON供 JS 解析 } return Json(new { success false, msg 验证失败 string.Join(, ModelState.Values.SelectMany(v v.Errors).Select(e e.ErrorMessage)) }); } // GET: /Customer/Edit/5 public ActionResult Edit(int? id) { if (id null) return new HttpStatusCodeResult(HttpStatusCode.BadRequest); var customer db.Customers.Find(id); if (customer null) return HttpNotFound(); return View(customer); // 同 Create但 View 中会渲染隐藏域 input typehidden nameId valueModel.Id / } // POST: /Customer/Edit/5 [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit([Bind(Include Id,Name,Email,Phone,Address)] Customer customer) { if (ModelState.IsValid) { db.Entry(customer).State EntityState.Modified; // 关键必须设为 Modified否则 SaveChanges 不更新 db.SaveChanges(); return Json(new { success true, msg 更新成功 }); } return Json(new { success false, msg 验证失败 string.Join(, ModelState.Values.SelectMany(v v.Errors).Select(e e.ErrorMessage)) }); } // POST: /Customer/Delete/5 [HttpPost, ActionName(Delete)] [ValidateAntiForgeryToken] public ActionResult DeleteConfirmed(int id) { var customer db.Customers.Find(id); if (customer ! null) { db.Customers.Remove(customer); db.SaveChanges(); } return Json(new { success true, msg 删除成功 }); } protected override void Dispose(bool disposing) { if (disposing) db.Dispose(); base.Dispose(disposing); } }逻辑说明Create和Edit的[Bind(Include ...)]是安全必需项防止恶意用户 POST 额外字段如IsAdmintrue造成越权。Edit方法中db.Entry(customer).State EntityState.Modified是 EF 6 的关键操作。如果漏掉这行SaveChanges()会插入新记录而非更新这是新手最常翻车的点。所有 POST Action 都返回Json(...)而非RedirectToAction因为前端是 AJAX 提交需要 JS 接收响应并刷新表格或关闭弹窗。3.2 Index.cshtmlLayui table 的初始化与事件绑定/Views/Customer/Index.cshtml是整个列表页的 HTML 容器核心是table idcustomerTable/table和初始化脚本!-- /Views/Customer/Index.cshtml -- { ViewBag.Title 客户管理; } h2ViewBag.Title/h2 div classlayui-btn-container button classlayui-btn layui-btn-normal onclickopenCreateLayer()i classlayui-icon/i 新增客户/button /div table idcustomerTable lay-filtercustomerTable/table script src~/Content/layui-v2.8.18/layui.js/script script src~/Scripts/customer.js/script注意script标签顺序不能颠倒。layui.js必须在customer.js之前加载否则layui.use([table, layer], ...)会报layui is not defined。3.3 customer.js前后端数据协议的翻译器/Scripts/customer.js是项目真正的胶水层它把 Layui 的 UI 事件翻译成 HTTP 请求并把 JSON 响应翻译成 UI 反馈// /Scripts/customer.js layui.use([table, layer, form], function () { var table layui.table; var layer layui.layer; var form layui.form; // 初始化表格 table.render({ elem: #customerTable, url: /Customer/GetList, // 后端需提供此 Action返回 JSON 格式数据 page: true, limit: 10, cols: [[ { field: id, title: ID, width: 80, sort: true }, { field: name, title: 姓名, width: 120 }, { field: email, title: 邮箱, width: 180 }, { field: phone, title: 电话, width: 140 }, { field: address, title: 地址, width: 200 }, { title: 操作, toolbar: #barDemo, width: 150 } ]] }); // 监听工具条事件 table.on(tool(customerTable), function (obj) { var data obj.data; if (obj.event detail) { openDetailLayer(data.id); } else if (obj.event edit) { openEditLayer(data.id); } else if (obj.event del) { layer.confirm(确定删除该客户, function (index) { $.ajax({ url: /Customer/DeleteConfirmed, type: POST, data: { id: data.id }, dataType: json, success: function (res) { if (res.success) { layer.msg(res.msg, { icon: 1 }); obj.del(); // 删除表格行 } else { layer.msg(res.msg, { icon: 2 }); } } }); }); } }); // 打开新增弹窗 window.openCreateLayer function () { layer.open({ type: 2, title: 新增客户, shadeClose: true, shade: 0.3, maxmin: true, area: [600px, 450px], content: /Customer/Create }); }; // 打开详情弹窗 window.openDetailLayer function (id) { layer.open({ type: 2, title: 客户详情, shadeClose: true, shade: 0.3, maxmin: true, area: [600px, 450px], content: /Customer/Details/ id }); }; // 打开编辑弹窗 window.openEditLayer function (id) { layer.open({ type: 2, title: 编辑客户, shadeClose: true, shade: 0.3, maxmin: true, area: [600px, 450px], content: /Customer/Edit/ id }); }; });参数说明url: /Customer/GetList这是关键。项目正文没提这个 Action但实际运行必须存在。你需要在CustomerController中补充public JsonResult GetList(int page 1, int limit 10) { var customers db.Customers.Skip((page - 1) * limit).Take(limit).ToList(); var count db.Customers.Count(); return Json(new { code 0, msg , count count, data customers }, JsonRequestBehavior.AllowGet); }toolbar: #barDemo对应页面底部的script typetext/html idbarDemo.../script模板里面定义了“查看”、“编辑”、“删除”按钮的 HTML。layer.open({ type: 2, ... })type: 2表示 iframe 层内容是/Customer/Create等 URL。Layui 会自动创建 iframe 并注入所以Create.cshtml中不需要写htmlbody只需表单代码。4. 运行与调试从零启动到看到表格每一步都可验证别急着改代码先确保环境能跑起来。以下步骤在 Windows 10 Visual Studio 2019 SQL Server Express 2019 环境下实测通过。4.1 数据库准备两行命令解决打开 SQL Server Management Studio新建查询执行-- 创建数据库如果不存在 IF NOT EXISTS (SELECT name FROM sys.databases WHERE name CustomerDB) CREATE DATABASE CustomerDB; GO -- 切换到该库 USE CustomerDB; GO -- 创建 Customers 表EF Code First 会自动建但手动建可避免首次访问超时 CREATE TABLE Customers ( Id INT IDENTITY(1,1) PRIMARY KEY, Name NVARCHAR(100) NOT NULL, Email NVARCHAR(100), Phone NVARCHAR(20), Address NVARCHAR(200) ); GO提示如果web.config中连接字符串指向的是.\SQLEXPRESS而你的 SQL Server 实例名是MSSQLSERVER默认实例则需将Data SourceYOUR-SQL-SERVER\SQLEXPRESS改为Data Source.。4.2 Visual Studio 启动配置右键项目 →属性→Web选项卡服务器选择 “IIS Express”推荐免配 IIS项目 URL保持默认http://localhost:XXXX/即可启动操作勾选 “启动外部程序”路径填C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.exe如果你用 VS 2019 Community—— 这步非必需但能避免调试时 VS 卡死4.3 首次运行必做三件事第一次访问/Customer/Index时EF 会尝试创建数据库。如果看到黄页错误 “A network-related or instance-specific error occurred...”说明连接字符串不对检查web.config中Data Source是否指向真实 SQL Server 实例。打开浏览器开发者工具F12→ Network 标签页刷新页面观察/Customer/GetList?page1limit10请求是否返回 200。如果返回 500点开看 Response大概率是GetListAction 未实现或数据库权限不足。点击“新增客户”按钮观察弹窗是否加载Create.cshtml。如果弹窗空白按 F12 查看 Console 是否报Failed to load resource: the server responded with a status of 404—— 这说明CustomerController.Create()方法存在但Create.cshtml路径不对应放在/Views/Customer/Create.cshtml不是/Views/Shared/Create.cshtml。4.4 常见问题排查血泪经验总结的 4 条避坑指南现象 1点击“编辑”按钮弹窗显示 “Cannot find view Edit or its master”原因CustomerController.Edit(int? id)返回View(customer)但 MVC 搜索视图的顺序是/Views/Customer/Edit.cshtml→/Views/Shared/Edit.cshtml。如果Edit.cshtml文件被误放到了/Views/Shared/且/Views/Shared/下恰好有Edit.cshtml比如其他控制器共用就会加载错文件。解决确认/Views/Customer/Edit.cshtml存在且文件名完全匹配大小写敏感。右键文件 →属性→ “生成操作” 必须是 “Content”不是 “None”。现象 2表单提交后页面整页刷新而不是弹出“添加成功”提示原因Create.cshtml中漏掉了Html.AntiForgeryToken()导致[ValidateAntiForgeryToken]特性拦截请求返回 400 Bad Request而customer.js的 AJAXsuccess回调未触发error回调也未写于是静默失败。解决在Create.cshtml和Edit.cshtml的form内第一行必须添加Html.AntiForgeryToken()现象 3Layui table 显示 “暂无数据”Network 中/Customer/GetList返回 200 但 data 为空数组原因GetListAction 中db.Customers.ToList()报错如数据库连接失败但被try-catch吞掉或未返回正确 JSON 结构。Layui table 要求返回固定格式{ code: 0, msg: , count: 100, data: [...] }。如果返回{ success: true, data: [...] }table 会认为解析失败。解决在GetList中加日志或断点确认customers和count变量值。返回语句必须严格按 Layui 文档要求。现象 4编辑客户后数据库中出现两条记录ID 不同原因EditAction 中漏写了db.Entry(customer).State EntityState.ModifiedEF 默认将customer当作新实体插入。解决在Edit的[HttpPost]方法中if (ModelState.IsValid)代码块内db.Customers.Add(customer)上一行必须加上db.Entry(customer).State EntityState.Modified;注意EntityState.Modified会标记所有字段为“已修改”即使你只想更新Email字段。如果需精准更新应先Find出原实体再逐字段赋值最后SaveChanges()。5. 二次开发实战如何在 30 分钟内接入你的真实业务现在你已经跑通了客户管理 Demo下一步是把它变成你自己的系统。我以“给某高校实验室增加设备借用登记功能”为例演示改造全流程。这不是理论推演而是我上周刚做完的真实操作。5.1 步骤一定义新业务实体5 分钟在/Models下新建Equipment.cs// /Models/Equipment.cs using System.ComponentModel.DataAnnotations; namespace YourProjectName.Models { public class Equipment { public int Id { get; set; } [Required(ErrorMessage 设备名称不能为空)] [StringLength(100, ErrorMessage 设备名称不能超过 100 字符)] public string Name { get; set; } [Required(ErrorMessage 型号不能为空)] public string Model { get; set; } [Range(1, 1000, ErrorMessage 数量必须在 1-1000 之间)] public int Quantity { get; set; } [Display(Name 是否可用)] public bool IsAvailable { get; set; } public string Remark { get; set; } } }然后修改CustomerContext.cs添加DbSetEquipment// /Models/CustomerContext.cs public class CustomerContext : DbContext { public CustomerContext() : base(CustomerContext) { } public DbSetCustomer Customers { get; set; } public DbSetEquipment Equipments { get; set; } // 新增这一行 protected override void OnModelCreating(ModelBuilder modelBuilder) { // 空实现留给以后扩展 } }5.2 步骤二生成新控制器与视图10 分钟在/Controllers右键 →添加→控制器→ 选择 “MVC 5 控制器 - 使用视图Entity Framework” →模型类Equipment数据上下文类CustomerContext控制器名称EquipmentControllerVS 会自动生成EquipmentController.cs和/Views/Equipment/下全部.cshtml文件。但这些是 MVC 默认模板UI 是 Bootstrap 风格与 Layui 不兼容。所以我们要删除/Views/Equipment/下所有文件Create.cshtml,Edit.cshtml等复制/Views/Customer/下的Create.cshtml,Edit.cshtml,Details.cshtml,Index.cshtml到/Views/Equipment/打开每个新文件全局替换Customer为Equipmentcustomer为equipment注意大小写修改Index.cshtml中的h2标题和按钮文字5.3 步骤三复用 customer.js 逻辑10 分钟复制/Scripts/customer.js重命名为/Scripts/equipment.js。修改其中所有customer相关字符串// /Scripts/equipment.js table.render({ elem: #equipmentTable, // 修改 table ID url: /Equipment/GetList, // 修改 URL cols: [[ { field: id, title: ID, width: 80 }, { field: name, title: 设备名称, width: 150 }, // 修改列标题 { field: model, title: 型号, width: 120 }, { field: quantity, title: 数量, width: 80 }, { field: isAvailable, title: 是否可用, width: 100, templet: #availableTpl }, // 新增模板列 { title: 操作, toolbar: #equipmentBar, width: 150 } ]] }); // 新增模板列渲染 script typetext/html idavailableTpl {{# if(d.isAvailable){ }} span classlayui-badge layui-bg-green可用/span {{# } else { }} span classlayui-badge layui-bg-gray不可用/span {{# } }} /script // 工具条模板 script typetext/html idequipmentBar a classlayui-btn layui-btn-xs lay-eventdetail查看/a a classlayui-btn layui-btn-xs layui-btn-primary lay-eventedit编辑/a a classlayui-btn layui-btn-xs layui-btn-danger lay-eventdel删除/a /script然后在/Views/Equipment/Index.cshtml底部把customer.js替换为equipment.jsscript src~/Content/layui-v2.8.18/layui.js/script script src~/Scripts/equipment.js/script5.4 步骤四补充 GetList Action5 分钟在EquipmentController.cs中添加// /Controllers/EquipmentController.cs public JsonResult GetList(int page 1, int limit 10) { var equipments db.Equipments.Skip((page - 1) * limit).Take(limit).ToList(); var count db.Equipments.Count(); return Json(new { code 0, msg , count count, data equipments }, JsonRequestBehavior.AllowGet); }5.5 验证与收尾3 分钟确认访问/Equipment/Index确认表格加载、分页、搜索正常点击“新增”填写表单提交后确认数据库新增记录点击“编辑”修改Quantity提交后确认数据库更新点击“删除”确认弹窗和删除动作生效从那以后我每次接手新业务模块都强制走一遍这个流程先建 Model → 再用 VS 自动生成 Controller → 立刻删掉默认 View → 复制 Layui 模板 → 改 JS 文件名和变量名 → 补GetList。这套动作熟了之后平均 25 分钟就能交付一个可用的 CRUD 模块再也不用担心“这个页面怎么跟客户解释”。希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

国产AI算力地基开源:调度器、硬件抽象与算子编译器深度解析

国产AI算力地基开源:调度器、硬件抽象与算子编译器深度解析

1. 项目概述:这不是一次模型发布,而是一次算力基建的“静默升级”“致敬,DeepSeek 最新开源的不是模型,是国产算力的地基”——这句话在技术圈刷屏时,我正调试一台刚上电的国产AI加速卡集群。没有发布会、没有PPT、没有…

📅 2026/10/17 14:34:52
CUDA算子与AI运行时:从内存对齐到stream调度的落地实践

CUDA算子与AI运行时:从内存对齐到stream调度的落地实践

1. 这不是“语法糖”,而是模型落地的真正门槛很多人第一次看到“算子”这个词,是在深度学习框架的文档里,或者某次技术分享中听到讲师轻描淡写地说:“这个层背后其实调用了一个CUDA算子”。于是下意识以为——哦,就是个…

📅 2026/10/17 14:34:52
STM32双串口MODBUS主站:DMA+FIFO实现工业级鲁棒通信

STM32双串口MODBUS主站:DMA+FIFO实现工业级鲁棒通信

简介:本资源是一套面向STM32嵌入式开发者的工业通信实战项目,聚焦双串口MODBUS多从机场景,解决传统轮询式通信效率低、CPU占用高、实时性差等痛点,适用于工业自动化网关、智能传感器节点及物联网边缘设备开发。压缩包共1220个文件…

📅 2026/10/17 14:34:52
MORE NEWS

更多资讯

📰

图即代码:diagram-design 如何构建可维护的架构图设计系统

1. 从一张草图到一套系统:diagram-design 到底在解决什么问题第一次看到 “diagram-design” 这个标题,很多人会以为它只是教你怎么把流程图做得好看一点。但真正在项目里画过架构图、时序图、状态机、数据流图的人都知道,图的美观只是最表层…

📰

C++线性代数库Eigen完全指南:从表达式模板到稀疏矩阵

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

diagram-design:文本优先的架构图设计方法论与可维护工作流

1. 从一张草图到一套系统:diagram-design 到底在解决什么问题第一次看到 “diagram-design” 这个标题,很多人会以为它只是教你怎么画图。但真正做过技术方案、写过设计文档、给团队讲过架构的人都知道,画图这件事背后藏着一整套信息表达系统…

📰

KITTI数据集国内下载与校验避坑指南:从镜像站到目录结构全解析

KITTI数据集,做自动驾驶、三维目标检测、视觉测距、光流估计这些方向的朋友应该都不陌生。它在业界属于标杆级的公开数据集,很多论文都是在它上面做评测,也是很多刚入门同学的第一个“大项目”。但问题来了:这数据集动辄上百GB&am…

📰

diagram-design:用声明式与设计令牌构建可维护的图形系统

1. 从一张草图到一套系统:diagram-design 到底在解决什么问题第一次看到 “diagram-design” 这个标题,很多人会以为它只是教你怎么画图——选个模板、拖几个框、连几条线,导出 PNG 就完事了。但真正在项目里画过架构图、流程图、时序图的人都…

📰

AI数据库不是向量库:从数据模型到事务语义的本质差异

1. 这不是概念炒作,而是技术定位的根本性错位“AI数据库不是向量库”——这句话在2024年中后段的技术圈里,已经从一句争议性断言,变成了不少一线架构师在评审新系统时脱口而出的前置判断。我参与过三个不同行业的AI原生应用落地项目&#xff…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬