You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 19:54:03