# 修復 SignUpImport 檔案上傳問題 & 支援新欄位順序 ## 問題描述 1. `System.InvalidOperationException: 要求格式無效: multipart/form-data; boundary=...` 2. 匯入檔案欄位順序更改為:序號、學員姓名、手機號、報名方式 ## 解決方案 ### 核心思路 **改用 HTTP Handler (ashx) 替代 ASMX Web Service**,並更新欄位對應順序 ## 實現步驟 ### 1. 建立 FileUploadHandler.ashx (HTTP Handler) - 路徑:`Services/FileUploadHandler.ashx` - 作用:直接接收並處理 multipart/form-data 檔案上傳 - 核心特性: - 使用 NPOI 解析 Excel 檔案(與後端保持一致) - 自動偵測表頭行 - 驗證資料格式 - 返回 JSON 格式的預覽資料和驗證錯誤 ### 2. 更新欄位對應順序 #### 後端 (FileUploadHandler.ashx.cs) ```csharp // 欄位順序: 序號(0), 學員姓名(1), 手機號(2), 報名方式(3) string indexValue = GetCellValue(row.GetCell(0)); // 序號 string nameValue = GetCellValue(row.GetCell(1)); // 學員姓名 string mobileValue = GetCellValue(row.GetCell(2)); // 手機號 string signupTypeValue = GetCellValue(row.GetCell(3)); // 報名方式 ``` #### 前端 (SignUpImport.js) - `convertBackendDataToPreviewFormat()` - 增加 `SignUpType` 欄位 - `executeImport()` - 傳送 `SignUpType` 給後端 ### 3. 表頭偵測邏輯更新 新的表頭偵測方式支援新欄位: ```csharp string[] col1Keywords = { "序號", "編號", "index", "Index", "#" }; string[] col2Keywords = { "姓名", "名字", "name", "Name", "學員" }; ``` ### 4. 保持後端兼容性 - 移除了 ASMX 中的 `ProcessImportFile` WebMethod(或保留但不使用) - 保留 `ConfirmImport` WebMethod 用於最終的資料匯入 - 匯入流程:「檔案上傳驗證」→ 「確認匯入」(兩個不同的端點) ## 請求流程 ``` 前端 (Vue.js) ↓ 上傳檔案 (multipart/form-data) ↓ FileUploadHandler.ashx (HTTP Handler) ├─ 讀取檔案 (NPOI) ├─ 解析欄位: 序號、姓名、手機號、報名方式 ├─ 偵測表頭 ├─ 驗證資料 ├─ 生成預覽 + 驗證錯誤 └─ 返回 JSON 響應 (包含 SignUpType) ↓ 前端顯示預覽 & 驗證錯誤 ↓ 使用者確認 ↓ 呼叫 ConfirmImport (ASMX WebMethod) ├─ 接收 SignUpType └─ 入庫 ``` ## 技術細節 ### FileUploadHandler.ashx 的優勢 1. **原生 multipart/form-data 支援** - `HttpContext.Request.Files` 可直接存取上傳的檔案 2. **輕量級** - 不依賴 ASMX SOAP 協議的複雜包裝 3. **靈活** - 可自由處理任何 HTTP 請求格式 4. **適合檔案上傳** - ASP.NET 的標準檔案上傳機制 ### 為什麼 ASMX 有問題 - ASMX 期望 JSON 格式的參數 (application/json) - 對 multipart/form-data 的支援不完整 - 試圖將 multipart 請求轉換為 SOAP/JSON 參數時失敗 ## 資料模型對應 ### Excel 檔案格式 | 序號 | 學員姓名 | 手機號 | 報名方式 | |-----|--------|------|--------| | (忽略) | 王小明 | 0912345678 | 現場報名 | | (忽略) | 李美麗 | 0923456789 | 線上報名 | ### 前端預覽資料結構 ```javascript { Name: '王小明', Mobile: '0912345678', SignUpType: '現場報名', errors: [] // 驗證錯誤陣列 } ``` ### 後端匯入結構 ```csharp { ID: 0, CourseID: 123, Name: '王小明', Mobile: '0912345678', SignUpType: '現場報名', QRCode: null, CheckInTime: null, CheckOutTime: null, DB_APPNO: 0 } ``` ## 測試清單 - [ ] 上傳包含新欄位的 Excel 檔案 - [ ] 表頭自動偵測(包含「序號」) - [ ] 驗證錯誤正確顯示 - [ ] 預覽資料正確展示(包含報名方式) - [ ] 確認匯入時正確傳送 SignUpType - [ ] 資料成功入庫且欄位完整 - [ ] 錯誤處理 (檔案格式、空檔案等) ## 相關檔案 - `Scripts/SignUpImport.js` - 前端 Vue 應用,使用新的 Handler 端點 - `Services/FileUploadHandler.ashx` - HTTP Handler 標記檔案 - `Services/FileUploadHandler.ashx.cs` - 處理邏輯實現(支援新欄位順序) - `Services/SignUpService.asmx.cs` - 保留 ConfirmImport 方法 ## 變更摘要 ### FileUploadHandler.ashx.cs 變更 - ✅ 新增 4 欄欄位的支援(序號、姓名、手機號、報名方式) - ✅ 更新表頭偵測邏輯 - ✅ 預覽資料包含 SignUpType ### SignUpImport.js 變更 - ✅ 更新 `convertBackendDataToPreviewFormat()` 處理 SignUpType - ✅ 更新 `executeImport()` 傳送 SignUpType