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

ASP.NET MVC如何反转年份目录与月度PDF文件的排序顺序?

问题描述

我定义了如下C#实体类:

public class NewsLetter
{
   public string FileName { get; set; }
}
public class Folder
{
   public Folder()
   {
      this.NewsLetter = new HashSet<NewsLetter>(); 
   }
   public string FolderName {  get; set; }
   public virtual ICollection<NewsLetter> NewsLetter { get; set;}
}

在ASP.NET MVC控制器中,我获取了/Newsletters/目录下的所有年份子目录(从2006年至今)及其中的月度PDF文件(文件名以两位月份开头),并封装为List<Folder>返回视图,控制器代码如下:

public ActionResult Index()
{
    try
    {
        string path = Server.MapPath("/Newsletters/");             
        string[] folderPaths = Directory.GetDirectories(path);
        List<Folder> fldrs = new List<Folder>();
        foreach(string folder in folderPaths)
        {
            Folder fldr = new Folder();
            List<Newsletter> newsletters = new List<Newsletter>();
            string thisFolder = Path.GetFileName(folder);
            string[] filePaths = Directory.GetFiles(folder);                 
            foreach(string newsletter in filePaths)
            {
                Newsletter nl = new Newsletter();
                nl.FileName = Path.GetFileName(newsletter);
                newsletters.Add(nl);
            }
            fldr.FolderName = thisFolder;
            fldr.Newsletter = newsletters;
            fldrs.Add(fldr);
            //fldrs.Reverse();
        }
        return View(fldrs);
    }           
    catch (Exception ex)
    {
        Errors.ErrorOccured(ex);
    }
    return RedirectToAction("Index", "Error", new { Area = "" });
}

当前内容按时间正序显示,示例如下:

2021
01-Jan.pdf
02-Feb.pdf
03-Mar.pdf
04-Apr.pdf
05-May.pdf
06-Jun.pdf
07-Jul.pdf
08-Aug.pdf
09-Sep.pdf
10-Oct.pdf
11-Nov.pdf
12-Dec.pdf

2022
01-Jan.pdf
...snipped for brevity

我需要反转目录与文件的排序,让最新的年份和月份内容排在最上方,期望输出如下:

2022
11-Nov.pdf
10-Oct.pdf
...snipped for brevity
01-Jan.pdf

2021
12-Dec.pdf
...snipped for brevity
01-Jan.pdf

但尝试取消注释fldrs.Reverse()后,仅偶数年目录反转,文件仍为正序,请问该如何正确实现需求?


解决方案

问题出在你把fldrs.Reverse()放在了foreach循环内部,每次添加一个文件夹就反转一次列表,导致排序逻辑混乱。要实现年份倒序+每个年份下文件倒序,需要做两处关键调整:

1. 调整年份目录的排序时机与逻辑

将目录反转/排序操作移到foreach循环外部,确保所有年份文件夹都添加完成后,再统一按年份降序排列。

2. 对每个年份下的文件进行倒序处理

在收集完单个年份的所有文件后,立即对文件列表进行降序排序(或反转),因为文件名以两位月份开头,降序排列会自动实现从12月到1月的顺序。

修改后的控制器代码如下:

public ActionResult Index()
{
    try
    {
        string path = Server.MapPath("/Newsletters/");             
        string[] folderPaths = Directory.GetDirectories(path);
        List<Folder> fldrs = new List<Folder>();
        
        foreach(string folder in folderPaths)
        {
            Folder fldr = new Folder();
            List<Newsletter> newsletters = new List<Newsletter>();
            string thisFolder = Path.GetFileName(folder);
            string[] filePaths = Directory.GetFiles(folder);                 
            
            foreach(string newsletter in filePaths)
            {
                Newsletter nl = new Newsletter();
                nl.FileName = Path.GetFileName(newsletter);
                newsletters.Add(nl);
            }
            
            // 对当前年份下的文件按文件名降序排序(从12月到1月)
            newsletters = newsletters.OrderByDescending(n => n.FileName).ToList();
            // 若确认文件默认是正序,也可直接用:newsletters.Reverse();
            
            fldr.FolderName = thisFolder;
            fldr.Newsletter = newsletters;
            fldrs.Add(fldr);
        }
        
        // 对年份文件夹按名称降序排序,最新年份排在最前面
        fldrs = fldrs.OrderByDescending(f => f.FolderName).ToList();
        // 若确认目录默认是正序,也可直接用:fldrs.Reverse(); 但排序逻辑更稳妥
        
        return View(fldrs);
    }           
    catch (Exception ex)
    {
        Errors.ErrorOccured(ex);
    }
    return RedirectToAction("Index", "Error", new { Area = "" });
}

关键说明

  • 使用OrderByDescending比直接Reverse()更可靠:如果目录中存在命名不规范的文件夹/文件,排序逻辑能保证按年份、月份的正确顺序排列,而反转仅依赖默认的目录遍历顺序。
  • 确保排序操作的时机正确:年份排序在所有文件夹添加完成后执行,文件排序在单个文件夹的文件收集完成后执行。

内容的提问来源于stack exchange,提问作者Miranda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 09:10:32