protected void btnUpload_Click(object sender, EventArgs e)
{
if (!fuFile.HasFile) { lblMsg.Text = "請選擇檔案"; return; }
FileInfo fi = new FileInfo(fuFile.FileName);
string destPath = Path.Combine(CurrentPath, fi.Name);
// 同名檔案處理:覆蓋/重命名/版本
if (File.Exists(destPath)) { /* 處理邏輯 */ }
try
{
fuFile.SaveAs(destPath); // 內部使用 PostedFile.SaveAs
LoadDirectory(CurrentPath);
lblMsg.Text = "上傳成功";
}
catch (Exception ex)
{
lblMsg.Text = "上傳失敗: " + ex.Message;
}
}
兩者必須同時設定,取較小值為實際限制。
// 核心邏輯:File.slice(start, end) → FormData append → POST /UploadChunk.ashx
// 參數: fileId (GUID), chunkIndex, totalChunks, fileName, totalSize
// 伺服器回傳: { success: true, receivedChunks: [0,1,2] }
// 所有分塊完成 → POST /MergeChunks.ashx?fileId=...&fileName=...&targetPath=...
public class UploadChunkHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string fileId = context.Request.QueryString["fileId"];
int chunkIndex = int.Parse(context.Request.QueryString["chunkIndex"]);
string tempDir = Path.Combine(Server.MapPath("~/App_Data/UploadTemp"), fileId);
Directory.CreateDirectory(tempDir);
string chunkPath = Path.Combine(tempDir, chunkIndex.ToString("D5"));
using (FileStream fs = new FileStream(chunkPath, FileMode.Create, FileAccess.Write))
{
context.Request.InputStream.CopyTo(fs);
}
// 回傳已收到分塊清單
var received = Directory.GetFiles(tempDir).Select(f => int.Parse(Path.GetFileNameWithoutExtension(f))).OrderBy(x => x).ToList();
context.Response.ContentType = "application/json";
context.Response.Write($"{{\"success\":true,\"receivedChunks\":[{string.Join(",", received)}]}}");
}
public bool IsReusable => false;
}
public class MergeChunksHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string fileId = context.Request.QueryString["fileId"];
string fileName = context.Request.QueryString["fileName"];
string targetPath = context.Request.QueryString["targetPath"]; // 伺服器端絕對路徑
string tempDir = Path.Combine(Server.MapPath("~/App_Data/UploadTemp"), fileId);
string[] chunks = Directory.GetFiles(tempDir).OrderBy(f => f).ToArray();
using (FileStream output = new FileStream(targetPath, FileMode.Create, FileAccess.Write))
{
foreach (string chunk in chunks)
{
using (FileStream fs = new FileStream(chunk, FileMode.Open, FileAccess.Read))
fs.CopyTo(output);
}
}
// 清理暫存
Directory.Delete(tempDir, true);
context.Response.ContentType = "application/json";
context.Response.Write("{\"success\":true,\"message\":\"合併完成\"}");
}
public bool IsReusable => false;
}