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

ASP.NET MVC 無元件上傳圖片完整實作 (HttpPostedFileBase)

     編輯:ASP.NET 基礎

前端表單 (Razor / .cshtml)

@using (Html.BeginForm("FileUpload", "Book", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <input type="file" id="imageUpload" name="imageUpload" accept="image/*" />
    <input type="submit" value="上傳圖片" />
    @* 或使用 AJAX 上傳 (見下方) *@
}

Controller 端處理

[HttpPost]
public ActionResult FileUpload(HttpPostedFileBase imageUpload)
{
    // 1. 基本驗證
    if (imageUpload == null || imageUpload.ContentLength == 0)
    {
        ModelState.AddModelError("", "請選擇檔案");
        return View();
    }

    // 2. 檔案類型驗證 (雙重保險)
    string[] allowedTypes = { "image/jpeg", "image/png", "image/gif", "image/bmp" };
    if (!allowedTypes.Contains(imageUpload.ContentType))
    {
        ModelState.AddModelError("", "僅支援 JPG/PNG/GIF/BMP 格式");
        return View();
    }

    // 3. 檔案大小限制 (例:4MB)
    if (imageUpload.ContentLength > 4 * 1024 * 1024)
    {
        ModelState.AddModelError("", "檔案大小不可超過 4MB");
        return View();
    }

    // 4. 取得原始檔名並處理路徑字元
    string fileName = Path.GetFileName(imageUpload.FileName); // 自動移除路徑資訊
    
    // 5. 產生唯一檔名避免衝突 (GUID + 原始副檔名)
    string ext = Path.GetExtension(fileName);
    string uniqueName = $"{Guid.NewGuid()}{ext}";
    
    // 6. 確保儲存目錄存在
    string saveDir = Server.MapPath("~/Content/Uploads/Images/");
    if (!Directory.Exists(saveDir)) Directory.CreateDirectory(saveDir);
    
    string savePath = Path.Combine(saveDir, uniqueName);
    
    // 7. 儲存檔案
    imageUpload.SaveAs(savePath);
    
    // 8. 存入資料庫 (相對路徑)
    string relativePath = $"/Content/Uploads/Images/{uniqueName}";
    // db.BookPhotos.Add(new BookPhoto { Path = relativePath });
    // db.SaveChanges();
    
    TempData["Success"] = "上傳成功!";
    return RedirectToAction("Index");
}

AJAX 非同步上傳 (jQuery + FormData)

// 前端 JS
$('#imageUpload').on('change', function() {
    var file = this.files[0];
    if (!file) return;
    
    var formData = new FormData();
    formData.append('imageUpload', file);
    
    $.ajax({
        url: '@Url.Action("FileUpload", "Book")',
        type: 'POST',
        data: formData,
        processData: false,  // 必須 false
        contentType: false,  // 必須 false,讓瀏覽器自動設定 multipart boundary
        success: function(result) {
            if (result.success) {
                alert('上傳成功:' + result.path);
            } else {
                alert('失敗:' + result.message);
            }
        },
        error: function() { alert('網路錯誤'); }
    });
});

// Controller 回傳 JSON
[HttpPost]
public JsonResult FileUpload(HttpPostedFileBase imageUpload)
{
    // ... 驗證與儲存邏輯同前 ...
    return Json(new { success = true, path = relativePath });
}

安全性關鍵點總結

風險防護措施
惡意腳本上傳驗證 ContentType、副檔名、檔案標頭 (Magic Bytes)
路徑遍歷攻擊使用 Path.GetFileName、不信任用戶檔名、重新命名
大檔案 DoS設定 maxRequestLength (web.config) 與 requestLimits (IIS)
直接存取上傳檔儲存於非公開目錄,透過 Controller 串流輸出或簽名 URL

web.config 請求大小限制

<system.web>
  <!-- 最大 10MB,預設 4MB -->
  <httpRuntime maxRequestLength="10240" />
</system.web>

<system.webServer>
  <security>
    <requestFiltering>
      <requestLimits maxAllowedContentLength="10485760" /> <!-- 10MB in bytes -->
    </requestFiltering>
  </security>
</system.webServer>
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved