diff --git "a/\351\273\204\351\222\260/20260112-\350\247\206\345\233\276\345\244\215\344\271\240.md" "b/\351\273\204\351\222\260/20260112-\350\247\206\345\233\276\345\244\215\344\271\240.md" new file mode 100644 index 0000000000000000000000000000000000000000..06c0db3bdcaed18265166095623f092e4de9f6e2 --- /dev/null +++ "b/\351\273\204\351\222\260/20260112-\350\247\206\345\233\276\345\244\215\344\271\240.md" @@ -0,0 +1,122 @@ +# 笔记 +## 一、核心架构分层 +本次实现采用 ASP.NET Core MVC 经典三层(Model-Controller-View)结构,核心是**模型数据传递与视图渲染**。 + +## 二、Model 层:数据模型定义(核心代码) +### 作用 +封装VIP数据结构,包含原始数据字段和格式化计算属性,提供视图所需的数据模型。 +```csharp +// 引用必要命名空间(默认可省略,如需特殊特性需引入) +namespace AuraCRM.Models; + +// 定义VIP数据模型类 +public class Vip +{ + // 1. 基础数据字段(与业务数据对应) + public int Id { get; set; } // 序号(主键) + public string VipName { get; set; } = null!; // VIP姓名(null! 抑制空引用警告) + public string Birthday { get; set; } = null!; // 生日 + public int Score { get; set; } // 积分 + public int Gender { get; set; } // 性别(0=女,1=男,存储用数字) + + // 2. 计算属性(只读,格式化展示数据,无需存储) + public string GenderText + { + get + { + // 将数字性别转换为中文文本,方便视图直接展示 + return Gender == 1 ? "男" : "女"; + } + } +} +``` +### 关键知识点 +1. 自动属性 `{ get; set; }`:简化字段封装,无需手动编写私有字段。 +2. `null!`:C# 可空引用类型特性,声明该属性不会为 `null`,抑制编译器警告。 +3. 只读计算属性(仅 `get` 访问器):用于数据格式化,逻辑封装在模型中,符合“胖模型,瘦控制器”思想。 + +## 三、Controller 层:控制器与数据传递(核心代码) +### 作用 +处理请求,构造数据模型,将数据传递给视图进行渲染。 +```csharp +// 1. 引入必要命名空间 +using Microsoft.AspNetCore.Mvc; // 包含Controller、IActionResult等核心类 +using AuraCRM.Models; // 引入自定义VIP模型 + +// 2. 定义控制器,继承自Controller基类 +namespace AuraCRM.Controllers; +public class VipController : Controller +{ + // 3. 定义Action方法,处理默认请求(对应视图Index) + public IActionResult Index() + { + // 4. 构造VIP列表数据(模拟数据,实际可从数据库获取) + List vipList = [ + new Vip{Id=1,VipName="郭富城",Birthday="1999-12-13",Score=18,Gender=1}, + new Vip{Id=2,VipName="金晨",Birthday="1999-12-13",Score=18,Gender=0} + // 其他数据可简化,核心是List集合的构造 + ]; + + // 5. 将数据模型传递给视图(关键:View()方法接收模型参数) + return View(vipList); + } +} +``` +### 关键知识点 +1. 控制器命名规范:`XXXController`,继承 `Microsoft.AspNetCore.Mvc.Controller`。 +2. Action 方法:返回 `IActionResult`,用于响应HTTP请求,`Index()` 是默认Action方法。 +3. 数据传递核心:`return View(模型对象)`,将 `List` 集合传递给对应的视图,视图可通过 `Model` 关键字获取该数据。 +4. 集合初始化:使用 C# 简化语法 `[]` 构造 `List`,等价于 `new List { ... }`。 + +## 四、View 层:视图渲染与数据展示(核心代码) +### 作用 +接收控制器传递的模型数据,通过Razor语法渲染为HTML页面,展示给用户。 +```razor +@{ + // 1. 关闭布局页(仅展示当前视图内容,可选) + Layout = null; +} + +// 2. 声明视图接收的模型类型(关键:指定模型为List) +@model List + + + + + +
+ + + +
+ + + + + + + + + + @foreach (var item in Model) + { + + + + + + + + } +
序号名称性别
@item.Id@item.VipName@item.GenderText + + +
+``` +### 关键知识点 +1. Razor 语法标识:`@` 用于区分C#代码与HTML,常用语法有 `@model`、`@foreach`、`@item.XXX`。 +2. 模型声明:`@model List` 必须指定,视图才能正确识别 `Model` 关键字的类型,提供智能提示。 +3. 数据遍历:`@foreach (var item in Model)` 遍历控制器传递的集合数据,逐个渲染表格行。 +4. 属性绑定:`@item.属性名` 读取模型对象的属性值,渲染到HTML元素中,支持直接调用计算属性(如 `GenderText`)。 \ No newline at end of file diff --git "a/\351\273\204\351\222\260/20260114-MVC\344\270\255\346\226\260\345\242\236\343\200\201\345\210\240\351\231\244\345\212\237\350\203\275.md" "b/\351\273\204\351\222\260/20260114-MVC\344\270\255\346\226\260\345\242\236\343\200\201\345\210\240\351\231\244\345\212\237\350\203\275.md" new file mode 100644 index 0000000000000000000000000000000000000000..7ca966fa63fc19912e8709aa58a210eb7101d851 --- /dev/null +++ "b/\351\273\204\351\222\260/20260114-MVC\344\270\255\346\226\260\345\242\236\343\200\201\345\210\240\351\231\244\345\212\237\350\203\275.md" @@ -0,0 +1,68 @@ +# 笔记 +## 一、 新增功能 +1. 视图层(View):新增按钮(a 标签实现,两种方式) + - 推荐:使用 ASP.NET Core 内置标签助手(自动解析路由,无需硬编码URL,更灵活) + ```html + 新增 + ``` + - 备选:直接硬编码 URL 路径(路径格式:`/控制器名/Action方法名`) + ```html + 新增 + ``` +2. 控制器层(Controller):新增功能分两个核心 Action 方法(遵循 MVC 最佳实践) + - 展示新增页面(GET 请求,默认触发,无参数):仅返回新增视图,不处理数据 + ```csharp + // 用于展示VIP新增表单页面 + public IActionResult Create() + { + return View(); + } + ``` + - 保存新增数据(POST 请求,需标注 [HttpPost] 特性,接收实体类参数):处理表单提交的新数据,保存到“数据库”(模拟/真实) + ```csharp + // 用于接收表单提交的新VIP数据,完成保存操作 + [HttpPost] + public IActionResult Create(Vip vip) // 接收Vip实体类参数,绑定表单提交的数据 + { + // 此处编写数据保存逻辑(如添加到模拟集合/真实数据库) + if (ModelState.IsValid) // 可选:校验实体数据合法性 + { + // 保存逻辑... + return RedirectToAction("Index"); // 保存成功后跳转回列表页 + } + return View(vip); // 数据校验失败,返回新增页面回显数据 + } + ``` + +## 二、 删除功能 +1. 控制器层(Controller):核心 Action 方法(处理删除请求,接收待删除数据ID) + - 关键参数:接收 `int? id`(使用可空int `int?`,避免空值传递报错) + - 前置操作:先校验 ID 非空且有效,再执行删除逻辑 + - 核心代码示例: + ```csharp + // 处理VIP删除请求(可根据需求标注 [HttpGet] 或 [HttpPost],推荐Post提高安全性) + public IActionResult Delete(int? id) + { + // 第一步:校验ID合法性(非空校验) + if (id == null) + { + return NotFound(); // ID为空,返回404未找到 + } + + // 第二步:编写真正的删除逻辑(根据id从模拟数据库/真实数据库中删除对应数据) + // 示例:从vipList集合中移除对应ID的数据 + // var targetVip = vipList.FirstOrDefault(v => v.Id == id); + // if (targetVip != null) { vipList.Remove(targetVip); } + + // 第三步:删除完成后,跳转回列表页 + return RedirectToAction("Index"); + } + ``` +2. 补充说明 + - 视图层跳转:可通过 a 标签或按钮跳转至删除 Action,传递 id 参数(如 `删除`) + - 安全性:真实项目中,删除操作推荐使用 `[HttpPost]` 或 `[HttpDelete]` 特性,避免通过 GET 请求直接触发删除,防止误操作和恶意请求。 + +## 三、 核心总结 +1. 新增功能:分“展示表单(GET)”和“保存数据(POST+实体参数)”两步,保存后建议跳转列表页。 +2. 删除功能:核心是“接收可空id → 校验id合法性 → 执行删除逻辑 → 跳转列表页”。 +3. 路由优化:优先使用标签助手 `asp-controller`/`asp-action`/`asp-route-id`,减少硬编码URL,提高项目可维护性。 \ No newline at end of file diff --git "a/\351\273\204\351\222\260/20260115-MVC\344\270\255\347\274\226\350\276\221\343\200\201\346\237\245\346\211\276\345\212\237\350\203\275.md" "b/\351\273\204\351\222\260/20260115-MVC\344\270\255\347\274\226\350\276\221\343\200\201\346\237\245\346\211\276\345\212\237\350\203\275.md" new file mode 100644 index 0000000000000000000000000000000000000000..bbe31583ba358547d22ee7ba364d9ec06c6d26cf --- /dev/null +++ "b/\351\273\204\351\222\260/20260115-MVC\344\270\255\347\274\226\350\276\221\343\200\201\346\237\245\346\211\276\345\212\237\350\203\275.md" @@ -0,0 +1,84 @@ +# 笔记 +## 一、 编辑功能 +### 1. 控制器核心代码(两步走:查询回显 + 保存更新) +#### (1) 第一步:根据ID查询数据,返回编辑视图(GET请求,用于回显原有数据) +```csharp +// 接收待编辑数据的ID(精准定位待编辑记录) +public IActionResult Edit(int id) +{ + // 1. 根据ID从模拟集合(或数据库)中查询对应的实体对象 + var targetModel = 命名List.Find(v => v.Id == id); // Find方法:根据主键ID查找匹配项 + + // 2. 合法性校验:判断查询结果是否为空(避免ID无效导致报错) + // 若为空返回404 NotFound,若不为空将实体数据传递给编辑视图(用于表单回显) + return targetModel == null ? NotFound() : View(targetModel); +} +``` + +#### (2) 第二步:接收表单数据,保存更新(POST请求,用于处理编辑提交) +```csharp +// 标注[HttpPost],明确处理POST提交请求,命名建议与GET方法区分(如EditSave/直接重载Edit) +[HttpPost] +public IActionResult EditSave(Vip updatedModel) +{ + // 1. 核心步骤:ID校验 + 字段更新 + if (updatedModel == null || updatedModel.Id <= 0) // 校验实体和ID合法性 + { + return NotFound(); + } + + // 2. 查找原数据(从模拟集合/数据库中获取待更新的旧记录) + var originalModel = 命名List.Find(v => v.Id == updatedModel.Id); + if (originalModel == null) + { + return NotFound(); + } + + // 3. 更新字段(将提交的新数据覆盖旧数据的对应字段) + originalModel.VipName = updatedModel.VipName; + originalModel.Birthday = updatedModel.Birthday; + originalModel.Score = updatedModel.Score; + originalModel.Gender = updatedModel.Gender; + + // 4. 更新完成后,跳转回列表页(查看更新结果) + return RedirectToAction("Index"); +} +``` + +### 2. 核心要点总结 +- 编辑功能遵循**“两步走”原则**:① GET-Edit(查数据、返视图、做回显);② POST-EditSave(验数据、更字段、完成更新)。 +- 核心逻辑:`ID精准定位` + `合法性校验` + `字段覆盖更新`,ID是编辑功能的核心标识,确保更新的是目标记录。 +- 视图配合:编辑视图需绑定实体模型,表单控件回显原有数据,提交时将完整实体(含ID)传递给后台保存方法。 + +## 二、 查找(搜索)功能 +### 1. 控制器核心代码(GET请求,支持条件筛选 + 参数回显) +```csharp +// 接收搜索框传递的查询参数(string类型,允许为null/空,对应VIP姓名搜索) +public IActionResult Index(string 命名Name) +{ + // 1. 初始化查询源:将模拟集合转为可查询的IEnumerable(方便后续LINQ筛选) + var queryList = 命名List.AsEnumerable(); + + // 2. 条件筛选:判断查询参数是否有效,有效则执行LINQ模糊查询 + if (!string.IsNullOrEmpty(命名Name)) + { + // Where + Contains:实现模糊搜索,筛选出姓名包含查询关键字的记录 + queryList = queryList.Where(v => v.VipName.Contains(命名Name)); + } + + // 3. 参数回显:将查询参数存入ViewBag,传递回视图(保持搜索框输入内容不丢失) + ViewBag.SearchVipName = 命名Name; + + // 4. 转换结果并返回视图:将筛选后的结果转为List,传递给视图展示 + return View(queryList.ToList()); +} +``` + +### 2. 核心要点总结 +- 请求方式:优先使用**GET请求**,方便浏览器缓存、支持书签收藏,查询参数会拼接在URL中,直观且易调试。 +- 核心逻辑:`接收查询参数` → `LINQ条件筛选` → `ViewBag参数回显` → `视图渲染结果`,四步完成搜索功能。 +- 关键技术点: + ① LINQ筛选:使用 `AsEnumerable()` 初始化查询源,`Where()` 构建筛选条件,`Contains()` 实现模糊匹配(类似SQL的LIKE)。 + ② 参数回显:通过 `ViewBag`(动态对象)传递查询参数回视图,解决搜索后输入框内容丢失的问题,提升用户体验。 + ③ 空值处理:使用 `!string.IsNullOrEmpty()` 校验查询参数,避免无效筛选和空指针异常。 +- 视图配合:搜索框的 `value` 属性绑定 `ViewBag.SearchVipName`,表单提交方式为GET,确保查询参数能传递到后台控制器。 \ No newline at end of file diff --git "a/\351\273\204\351\222\260/20260116MVC\351\242\230\347\233\256\350\256\262\350\247\243\344\270\216\345\244\215\344\271\240.md" "b/\351\273\204\351\222\260/20260116MVC\351\242\230\347\233\256\350\256\262\350\247\243\344\270\216\345\244\215\344\271\240.md" new file mode 100644 index 0000000000000000000000000000000000000000..d1a0affe6d0c968a45a38fd206788806b9ff82a2 --- /dev/null +++ "b/\351\273\204\351\222\260/20260116MVC\351\242\230\347\233\256\350\256\262\350\247\243\344\270\216\345\244\215\344\271\240.md" @@ -0,0 +1,59 @@ +# 笔记 +## (一)新增功能 +1. 触发跳转:点击页面中的「新增」按钮,将跳转至数据录入页面A;其中「新增」按钮采用 `` 标签实现,有两种常用写法: + - 基于 ASP.NET Core 标签助手(推荐,支持路由自动解析,无需硬编码URL): + ```html + 新增 + ``` + - 基于硬编码 URL(简单直接,路由变更时需手动修改): + ```html + 新增 + ``` +2. 页面A核心内容:包含一个数据录入表单,表单内有若干表单项、「提交」按钮和「取消」按钮。 + - 表单配置(指定提交目标与请求方式): + ```html +
+ ``` + - 表单项绑定:使用 `asp-for` 标签助手实现表单与后台模型的自动绑定,简化数据接收与验证。 +3. 按钮功能逻辑: + - 提交按钮:点击后将表单数据通过 `POST` 请求提交至后台,后台将数据保存到数据库表(通过集合 `List` 的 `list.Add()` 方法添加数据),保存成功后跳转回数据列表页。 + - 取消按钮:点击后直接跳转回数据列表页,不执行任何数据保存操作。 + +## (二)删除功能 +1. 触发跳转:点击页面中的「删除」按钮,跳转至确认删除页面B。 +2. 页面B核心内容:展示删除确认提示,询问用户是否确认删除目标数据。 +3. 操作逻辑分支: + - 确认删除:用户选择「是」,后台执行数据库数据删除操作,删除完成后跳转回数据列表页。 + - 取消删除:用户选择「否」,不执行任何数据操作,直接跳转回数据列表页。 + +## (三)编辑功能 +1. 触发跳转:点击页面中的「编辑」按钮,跳转至数据编辑页面C。 +2. 页面C核心内容:包含一个数据编辑表单,表单已回显待编辑数据的原始信息,同时提供「保存」按钮和「取消」按钮。 +3. 按钮功能逻辑: + - 保存按钮:点击后将表单中的最新数据提交至后台,后台更新数据库对应记录,更新成功后跳转回数据列表页。 + - 取消按钮:点击后直接跳转回数据列表页,不执行任何数据更新操作。 + +# 二、.NET 项目创建笔记 +## (一)创建控制台项目 +1. 创建纯净控制台项目(项目名与自动生成的文件夹名一致): + ```bash + dotnet new console -n 项目命名 + ``` +2. 示例:创建一个名为 `Blog` 的控制台项目: + ```bash + dotnet new console -n Blog + ``` +3. 指定项目输出目录(创建后项目文件存放于指定 `Blog` 目录下): + ```bash + dotnet new console -o Blog + ``` + +## (二)创建 MVC 项目 +1. 指定项目名称创建 MVC 项目(项目名与自动生成的文件夹名一致): + ```bash + dotnet new mvc -n 项目命名 + ``` +2. 指定项目输出目录创建 MVC 项目(项目文件存放于指定目录下): + ```bash + dotnet new mvc -o ./目标文件名/ + ``` \ No newline at end of file