`Convert.ToInt32` 拋出 `FormatException` 通常是字串包含 **不可見字元 (空白、換行、製表符、BOM)** 或 **非數字字元**。
string raw = ds.Tables[0].Rows[0][0].ToString(); // 從 DataSet 取得
string cleaned = raw.Trim(); // 移除首尾空白字元 (含 \r\n\t )
int value = Convert.ToInt32(cleaned);
if (int.TryParse(raw.Trim(), out int value)) {
// 轉換成功,使用 value
} else {
// 轉換失敗,記錄日誌/預設值/拋出自訂異常
Log.Warn($"無法解析整數: '{raw}'");
value = 0; // 或 throw new BusinessException(...)
}
| 來源 | 可能字元 | 處理 |
|---|---|---|
| 資料庫 CHAR/NCHAR 固定長度欄位 | 尾部補空格 | .Trim() |
| CSV/Excel 匯入 | BOM (U+FEFF)、全形數字、千分位逗號 | .Trim().Replace(",", "").Normalize() |
| XML 解析 | 實體編碼 ` `、CDATA 換行 | HttpUtility.HtmlDecode + Trim |
| Web API 回應 | JSON 字串含引號 `"123"` | JsonConvert.DeserializeObject |
public static class StringExtensions {
public static int ToInt32Safe(this string s, int defaultValue = 0) {
return int.TryParse(s?.Trim(), out int v) ? v : defaultValue;
}
}
// 使用
int value = raw.ToInt32Safe(-1); // 失敗回傳 -1
// 強型別 DataTable (推薦)
var row = ds.Tables[0].Rows[0];
int value = row.Field("ColumnName"); // 自動處理 DBNull、型別轉換
// 或 LINQ
int value = ds.Tables[0].AsEnumerable()
.Select(r => r.Field("ColumnName"))
.FirstOrDefault();
習慣用 `TryParse` + `Trim` + 明確失敗處理,比 `Convert.ToInt32` 配合 `try-catch` 更清晰、效能更好 (避免異常開銷)。