ASP.NET Core 5 MVC 如何将导航栏关联视图实现文件按分类上传与查看
分类导航栏功能实现方案
1. 预定义分类与视图模型
首先定义合法的文件分类,同时新增视图模型承载页面数据,解决原有静态属性导致的多用户数据冲突问题:
// 允许上传的分类枚举,可根据业务需求自行修改值 public enum FileCategory { 公共文档, 内部资料, 产品手册, 技术文档 } // 首页视图模型 public class FileIndexViewModel { // 当前选中分类 public string CurrentCategory { get; set; } // 当前分类下的文件列表 public List<FileInfo> FileList { get; set; } = new List<FileInfo>(); // 所有可展示的分类列表 public List<string> AllCategories { get; set; } = new List<string>(); }
2. 修改Home控制器逻辑
2.1 新增公共工具方法
在HomeController中新增分类校验和目录初始化方法,避免代码重复:
// 校验分类合法性,不合法返回默认分类 private string ValidateCategory(string category) { var validCategories = Enum.GetNames<FileCategory>().ToList(); if (string.IsNullOrEmpty(category) || !validCategories.Contains(category)) { return validCategories.First(); } return category; } // 确保分类存储目录存在 private void EnsureCategoryDirectoryExists(string category) { var dirPath = Path.Combine(_iweb.WebRootPath, "Uploads", category); if (!Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); } }
2.2 修改Index的Get方法
支持按分类读取文件:
public IActionResult Index(string category) { category = ValidateCategory(category); EnsureCategoryDirectoryExists(category); var displayPath = Path.Combine(_iweb.WebRootPath, "Uploads", category); DirectoryInfo di = new DirectoryInfo(displayPath); var fileList = di.GetFiles().ToList(); var viewModel = new FileIndexViewModel { CurrentCategory = category, FileList = fileList, AllCategories = Enum.GetNames<FileCategory>().ToList() }; return View(viewModel); }
2.3 修改上传Post方法
限制只能上传到指定分类:
[HttpPost] public async Task<IActionResult> Index(IFormFile fifile, string category) { if (fifile == null || fifile.Length == 0) { return RedirectToAction("Index"); } category = ValidateCategory(category); EnsureCategoryDirectoryExists(category); var savePath = Path.Combine(_iweb.WebRootPath, "Uploads", category, fifile.FileName); using var stream = new FileStream(savePath, FileMode.Create); await fifile.CopyToAsync(stream); return RedirectToAction("Index", new { category = category }); }
2.4 修改其他操作方法,新增分类参数
public IActionResult Delete(string filedel, string category) { category = ValidateCategory(category); var filePath = Path.Combine(_iweb.WebRootPath, "Uploads", category, filedel); if (System.IO.File.Exists(filePath)) { System.IO.File.Delete(filePath); } return RedirectToAction("Index", new { category = category }); } public async Task<IActionResult> Download(string filename, string category) { if (filename == null) return Content("filename is not avaiable"); category = ValidateCategory(category); var path = Path.Combine(_iweb.WebRootPath, "Uploads", category, filename); var memory = new MemoryStream(); using (var stream = new FileStream(path, FileMode.Open)) { await stream.CopyToAsync(memory); } memory.Position = 0; return File(memory, GetContentType(path), Path.GetFileName(path)); } public IActionResult DocumentViewer(string fileview, string category) { // 补充按分类读取文件的逻辑即可 return View(fc); }
3. 修改Razor视图代码
替换原有视图代码,新增分类导航栏,所有操作链接携带分类参数:
@model FileIndexViewModel <center> <hr /> <!-- 分类导航栏 --> <nav class="navbar navbar-expand-lg navbar-light bg-light mb-3"> <a class="navbar-brand">文档分类</a> <div class="collapse navbar-collapse"> <ul class="navbar-nav mr-auto"> @foreach (var cate in Model.AllCategories) { <li class="nav-item @(cate == Model.CurrentCategory ? "active" : "")"> <a class="nav-link" href="@Url.Action("Index", "Home", new { category = cate })">@cate</a> </li> } </ul> </div> </nav> @if (User.IsInRole("Admin")) { <form method="post" enctype="multipart/form-data" asp-controller="Home" asp-action="Index"> <input type="hidden" name="category" value="@Model.CurrentCategory" /> <div class="mb-2"> <input type="file" name="fifile" required /> <span class="ml-2">当前上传分类:@Model.CurrentCategory</span> </div> <input type="submit" value="上传文件" class="btn btn-primary" /> <hr /> </form> } <table class="table"> <tr> <th>文件名称</th> <th>操作</th> </tr> @foreach (var item in Model.FileList) { <tr> <td>@item.Name</td> <td><a href="@Url.Action("Download","Home",new { filename=item.Name, category = Model.CurrentCategory })">下载</a></td> @if (User.IsInRole("Admin")) { <td><a href="@Url.Action("Delete", "Home", new { filedel = item.Name, category = Model.CurrentCategory })">删除</a></td> } <td><a href="@Url.Action("DocumentViewer", "Home", new { fileview = item.Name, category = Model.CurrentCategory })">预览</a></td> </tr> } </table> </center>
功能说明
- 用户访问站点默认展示第一个分类的文档,点击导航栏对应分类即可切换查看对应分类下的文件
- 上传者(管理员)仅能在当前选中的分类下上传文件,无法自定义上传路径,符合指定分类上传的要求
- 文件按分类存放在
Uploads对应的子目录下,结构清晰,后续维护方便
内容的提问来源于stack exchange,提问作者Panait Rares Horia
相关产品推荐
相关产品推荐

