在 C# 中驗證一個下載鏈接是否有效,核心思路是發送 HTTP 請求並檢查回應的 StatusCode(狀態碼)。常見有效狀態碼為 200 OK,重定向為 301/302,錯誤為 404/500 等。需注意異常處理、超時設置、重定向策略與資源釋放。
public bool IsDownloadUrlValid(string url, out int statusCode) {
statusCode = 0;
if (string.IsNullOrWhiteSpace(url)) return false;
try {
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "HEAD"; // 僅獲取頭部,不下載內容,更快
request.Timeout = 5000; // 5 秒超時
request.AllowAutoRedirect = true; // 允許自動重定向
request.UserAgent = "Mozilla/5.0 (compatible; LinkChecker/1.0)"; // 模擬瀏覽器
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
statusCode = (int)response.StatusCode;
// 2xx 成功,3xx 重定向通常也視為有效
return statusCode >= 200 && statusCode < 400;
}
} catch (WebException ex) {
// 捕獲 404、500 等 HTTP 錯誤回應
if (ex.Response is HttpWebResponse errorResponse) {
statusCode = (int)errorResponse.StatusCode;
}
return false;
} catch (Exception) {
// DNS 失敗、超時、網絡不可達等
return false;
}
}
public async Task<(bool IsValid, int StatusCode, string ErrorMessage)> CheckUrlAsync(string url) {
if (string.IsNullOrWhiteSpace(url))
return (false, 0, "URL 為空");
try {
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "HEAD";
request.Timeout = 10000;
request.AllowAutoRedirect = true;
// 支援 TLS 1.2/1.3
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;
using (var response = (HttpWebResponse)await request.GetResponseAsync()) {
int code = (int)response.StatusCode;
return (code >= 200 && code < 400, code, null);
}
} catch (WebException ex) when (ex.Response is HttpWebResponse resp) {
return (false, (int)resp.StatusCode, ex.Message);
} catch (Exception ex) {
return (false, 0, ex.Message);
}
}
| 屬性/方法 | 作用 | 建議值 |
|---|---|---|
| Method = "HEAD" | 僅請求頭部,不下載 Body,極大提升速度與節省流量 | 必須 |
| AllowAutoRedirect | 是否自動跟隨 301/302 重定向 | true(視業務而定) |
| Timeout | 請求超時時間 | 5-10 秒 |
| UserAgent | 偽裝瀏覽器,防止被反爬蟲攔截 | 自定義字符串 |
| SecurityProtocol | 啟用現代 TLS 協議 | Tls12 | Tls13 |
Response.ResponseUri 中。.NET Core / .NET 5+ 推薦使用 HttpClient(單例模式),支援更豐富的功能與更好效能:
private static readonly HttpClient _client = new HttpClient { Timeout = TimeSpan.FromSeconds(10) };
public async Task<bool> IsValidAsync(string url) {
try {
var request = new HttpRequestMessage(HttpMethod.Head, url);
request.Headers.UserAgent.ParseAdd("LinkChecker/1.0");
var response = await _client.SendAsync(request);
return response.IsSuccessStatusCode ||
(int)response.StatusCode >= 300 && (int)response.StatusCode < 400;
} catch { return false; }
}
總結:用 HEAD 請求 + 狀態碼判斷是標準做法;生產環境建議封裝為可重試、可取消、支援代理的通用服務。