chore: 首次簽入 Thinkyu ASP.NET 專案
- 加入 Visual Studio / ASP.NET .gitignore - 排除建置輸出、IDE 設定、NuGet packages、大型 MSI 安裝檔
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
# 修復 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
|
||||
Reference in New Issue
Block a user