ASP.NET Core前后端对接及分类上传展示文件实现方案咨询
实现方案
核心逻辑是按分类创建独立子目录存储文件,上传时绑定分类参数存储到对应目录,查看时根据传入的分类参数读取对应目录文件即可,具体修改如下:
1. 前端Razor页面修改
管理员上传部分调整
把分类选择逻辑整合到上传表单中,新增隐藏字段传递选中的分类值:
@if (User.IsInRole("Admin")) { <form method="post" enctype="multipart/form-data" id="catform"> <!-- 新增隐藏字段存储选中的分类 --> <input type="hidden" name="category" id="selectedCategory" value="" required> <input asp-for="Files" type="file" name="files" multiple /> <p>当前选中分类:<span id="catTip">未选择</span></p> <button type="submit">Upload</button> </form> <p>Alegeti categoria de personal pentru care doriti sa uploadati</p> <nav class="navbar navbar-expand-lg navbar-light bg-light"> <!-- 原有导航代码不变,仅修改下拉项 --> <div class="dropdown-menu" aria-labelledby="navbarDropdown"> <!-- 给每个下拉项加data-category属性存储分类值 --> <a class="dropdown-item" href="#" data-category="Incepatori">Incepatori</a> <a class="dropdown-item" href="#" data-category="Avansati">Avansati</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="#" data-category="Admini">Admini</a> </div> </nav> } @if (User.IsInRole("User")) { <nav class="navbar navbar-expand-lg navbar-light bg-light"> <!-- 原有导航代码不变,修改分类链接为带参数的跳转地址,替换为你实际的控制器名 --> <li class="nav-item"> <a class="nav-link" href="/Home/Index1?category=Incepatori">Incepatori</a> </li> <li class="nav-item"> <a class="nav-link" href="/Home/Index1?category=Avansati">Avansati</a> </li> <li class="nav-item"> <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Admini</a> </li> </nav> } <!-- 新增js处理分类选择逻辑 --> @section Scripts{ <script> document.querySelectorAll('.dropdown-item').forEach(item=>{ item.addEventListener('click',e=>{ e.preventDefault(); const cat = item.dataset.category; document.getElementById('selectedCategory').value = cat; document.getElementById('catTip').innerText = cat; }) }) </script> }
2. 后端接口修改
首先定义合法分类列表防止非法参数传入,调整上传和查询逻辑按分类读写:
// 先定义合法分类白名单,放在控制器类里即可 private readonly List<string> ValidCategories = new List<string> { "Incepatori", "Avansati", "Admini" }; [HttpGet] public IActionResult Index1(string category = "") { // 普通用户禁止访问Admini分类 if (User.IsInRole("User") && category == "Admini") { return Forbid(); } var model = new FilesViewModel(); var basePath = Path.Combine(Directory.GetCurrentDirectory(), "upload"); // 有分类参数就读对应分类目录,否则读根目录(可根据需求调整默认展示逻辑) var readPath = string.IsNullOrEmpty(category) ? basePath : Path.Combine(basePath, category); // 目录不存在则返回空列表 if (Directory.Exists(readPath)) { foreach (var item in Directory.GetFiles(readPath)) { model.Files.Add(new FileDetails { Name = Path.GetFileName(item), Path = item }); } } // 可选:给model加CurrentCategory字段回传给前端做分类高亮 // model.CurrentCategory = category; return View(model); } [HttpPost] public IActionResult Index1(IFormFile[] files, string category) { // 校验分类合法性 if (!ValidCategories.Contains(category)) { ViewBag.Message = "请选择合法的分类"; return RedirectToAction(nameof(Index1)); } var basePath = Path.Combine(Directory.GetCurrentDirectory(), "upload"); var savePath = Path.Combine(basePath, category); // 分类目录不存在则自动创建 if (!Directory.Exists(savePath)) { Directory.CreateDirectory(savePath); } foreach (var file in files) { var fileName = Path.GetFileName(file.FileName); var filePath = Path.Combine(savePath, fileName); if (System.IO.File.Exists(filePath)) { System.IO.File.Delete(filePath); } using (var localFile = System.IO.File.OpenWrite(filePath)) using (var uploadedFile = file.OpenReadStream()) { uploadedFile.CopyTo(localFile); } } ViewBag.Message = "文件上传成功"; // 上传完成跳转到对应分类的文件列表页 return RedirectToAction(nameof(Index1), new { category = category }); }
3. 可选优化
- 可以给
FilesViewModel新增CurrentCategory属性,前端根据该值高亮当前选中的分类导航 - 分类名称可以做成配置项,避免硬编码
- 新增文件重名处理逻辑,避免覆盖同名文件
内容的提问来源于stack exchange,提问作者Panait Rares Horia
相关产品推荐
相关产品推荐

