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
相关产品推荐
相关产品推荐

