首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

ASP.NET 網絡硬盤實作 (一):目錄瀏覽與檔案夾管理

     編輯:關於ASP.NET

功能需求

  • 每位使用者擁有獨立根目錄 (如 `C:\UserDir\{UserId}`)。
  • 列出目前目錄檔案/子目錄,支援進入子目錄、返回上層。
  • 新建資料夾、刪除檔案/資料夾、上傳下載 (後續文章)。

頁面版面



核心程式碼

public partial class NetDisk : System.Web.UI.Page
{
 private string RootPath => Server.MapPath($"~/UserFiles/{User.Identity.Name}");
 private string CurrentPath
 {
 get => ViewState["CurrentPath"] as string ?? RootPath;
 set => ViewState["CurrentPath"] = value;
 }

 protected void Page_Load(object sender, EventArgs e)
 {
 if (!IsPostBack)
 {
 EnsureRootDirectory();
 LoadDirectory(CurrentPath);
 }
 }

 void EnsureRootDirectory()
 {
 if (!Directory.Exists(RootPath)) Directory.CreateDirectory(RootPath);
 }

 void LoadDirectory(string path)
 {
 CurrentPath = path;
 lbFiles.Items.Clear();

 // 返回上層 (非根目錄)
 if (path != RootPath)
 lbFiles.Items.Add(new ListItem("⬆ 返回上層", ".."));

 // 目錄優先
 foreach (string dir in Directory.GetDirectories(path))
 {
 DirectoryInfo di = new DirectoryInfo(dir);
 lbFiles.Items.Add(new ListItem($"📁 {di.Name}", di.FullName));
 }

 // 檔案
 foreach (string file in Directory.GetFiles(path))
 {
 FileInfo fi = new FileInfo(file);
 lbFiles.Items.Add(new ListItem($"📄 {fi.Name} ({FormatSize(fi.Length)})", fi.FullName));
 }
 }

 string FormatSize(long bytes)
 {
 if (bytes < 1024) return $"{bytes} B";
 if (bytes < 1024 * 1024) return $"{bytes / 1024.0:F1} KB";
 return $"{bytes / (1024.0 * 1024):F1} MB";
 }

 protected void btnOpen_Click(object sender, EventArgs e)
 {
 if (lbFiles.SelectedIndex < 0) return;
 string selected = lbFiles.SelectedValue;

 if (selected == "..")
 {
 CurrentPath = Directory.GetParent(CurrentPath).FullName;
 }
 else if (Directory.Exists(selected))
 {
 CurrentPath = selected;
 }
 else if (File.Exists(selected))
 {
 // 檔案:導向下載頁或直接下載
 Response.Redirect($"Download.aspx?file={Server.UrlEncode(selected)}");
 return;
 }
 LoadDirectory(CurrentPath);
 }

 protected void btnNewFolder_Click(object sender, EventArgs e)
 {
 // 簡易實作:彈出 prompt (JS) 取得名稱 → 後端建立
 // 此處略,實際建議用 ModalPopup + TextBox
 string folderName = Request.Form["newFolderName"]; // 假設前端已處理
 if (!string.IsNullOrWhiteSpace(folderName))
 {
 string newPath = Path.Combine(CurrentPath, folderName);
 if (!Directory.Exists(newPath)) Directory.CreateDirectory(newPath);
 LoadDirectory(CurrentPath);
 }
 }

 protected void btnDelete_Click(object sender, EventArgs e)
 {
 if (lbFiles.SelectedIndex < 0) return;
 string selected = lbFiles.SelectedValue;
 if (selected == "..") return;

 try
 {
 if (Directory.Exists(selected))
 Directory.Delete(selected, true); // 遞迴刪除
 else if (File.Exists(selected))
 File.Delete(selected);
 LoadDirectory(CurrentPath);
 }
 catch (Exception ex)
 {
 lblMsg.Text = "刪除失敗: " + ex.Message;
 }
 }
}

安全性關鍵:路徑遍歷防護

private bool IsPathSafe(string requestedPath, string rootPath)
{
 string fullRequested = Path.GetFullPath(requestedPath).TrimEnd('\\');
 string fullRoot = Path.GetFullPath(rootPath).TrimEnd('\\');
 return fullRequested.StartsWith(fullRoot, StringComparison.OrdinalIgnoreCase);
}

// 在所有檔案操作前呼叫
if (!IsPathSafe(selected, RootPath)) throw new SecurityException("存取路徑超出授權範圍");

擴充建議

  • 分頁/虛擬滾動:大量檔案時 `ListBox` 效能不佳,改用 `Repeater` + JS 虛擬清單。
  • 圖片縮圖預覽:`ImageHandler.ashx` 產生縮圖,ListBox 模板顯示。
  • 右鍵選單:ContextMenu JS 元件提供重新命名、複製、移動、屬性。
  • 搜尋/過濾:文字框即時過濾 ListBox 項目。
  • 資料庫中繼資料:檔案描述、標籤、版本、共享連結存資料庫,檔案系統只存實體。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved