解決 必須使用適當的屬性和方法修改 User-Agent 錯誤
問題描述:近在項目中有一個需求為需要在 Http
的Header里面添加一個User-Agent參數,當請求時。項目本身的目標框架是 .NET Standard 2.0
。於是,在項目源碼中發現了,最終調用的請求是使用 HttpWebRequest
來進行最后的封裝和發送的。
首先是用 HttpRequest
包裝的,代碼如下:
request.Headers["User-Agent"] = "Windows 10.0.2.4";
然后到最后發請求時,foreach
這個Headers 的 Dictionary<string,string> 類型的,然后copy to HttpWebRequest
的這個Header中
foreach (var header in request.Headers)
{
httpWebRequest.Headers.Add(header.Key, header.Value);
}
本地也進行了相關的 UT 和 FT,一切都很完美。然后發布了新版本。
版本發布后的第三天,接到了用戶的一個反饋說:
在調用最新Nuget版本的包后,請求調用一直報錯:必須使用適當的屬性和方法修改 User-Agent
首先先讓用戶回退到上一個版本的包,然后詢問了用戶的目標框架,用戶說是.Net framework 4.6.1
,剛開始我以為是不是我項目中引用的某個包不支持該版本啊,沿着這個思路,果然有所發現。我發現在獲取用戶當前系統版本的時候使用了這個類System.Runtime.InteropServices.RuntimeInformation.OSDescription,然后我發現這個屬性可能為空,是不是屬性空導致這個錯誤的呢?抱着試一試的態度,繼續往下。
去官方文檔看了看,這個包最低支持的.net framework 框架為 4.7.1 。我想,那如果我在目標框架中也包含了.net framework 4.7.1 會不會就不報錯了呢。
繼續沿着這個思路,我去尋找了: 如何在csproj 文件中指定多個 targetframework ,於是也便有了這個提問,如何發布多個 TargetFramework 的nuget 包 。當我設置完了這個目標框架,測試時發現,怎么還是不行呢。我發現我可能走錯路了,可能根本就不是這個地方出現問題了,是不是我問題定位的有問題。而且奇怪的是,
為什么如果我本地目標框架是 .netcoreapp2.0 或者 .net standard2.0 時就不會報錯呢?好奇怪。
於是,我繼續開始設置斷點進行調試,最終發現了,每次走到下面這段代碼時就會曝出上面那條錯誤:
httpWebRequest.Headers.Add(header.Key, header.Value);
這到底是為什么呢,為什么添加其他屬性時就不會有這個錯,終於還是在微軟的官方文檔上找到了答案:
HttpWebRequest exposes common HTTP header values sent to the Internet resource as properties, set by methods, or set by the system; the following table contains a complete list. You can set other headers in the Headers property as name/value pairs. Note that servers and caches may change or add headers during the request.
The following table lists the HTTP headers that are set either by properties or methods or the system.
Header Set by Accept Set by the Accept property. Connection Set by the Connection property, KeepAlive property. Content-Length Set by the ContentLength property. Content-Type Set by the ContentType property. Expect Set by the Expect property. Date Set by the system to current date. Host Set by the system to current host information. If-Modified-Since Set by the IfModifiedSince property. Range Set by the AddRange method. Referer Set by the Referer property. Transfer-Encoding Set by the TransferEncoding property (the SendChunked property must be true
).User-Agent Set by the UserAgent property.
也就是說呢,如果你的Headers中沒有包含上述的12個屬性,我就當成它為保留屬性把,你都可以用以下命令設置
httpWebRequest.Headers.Add(header.Key, header.Value);
然而當涉及到上述的屬性的話,你就需要像下面這樣
if(header.key.contains("User-Agent"))
{
httpWebRequest.UserAgent = "Set as you like";
}
總結起來還是經驗不夠,小問題定位錯誤導致排查錯了方向,一旦找對方向,就很容易解決啦。
PS:下一篇寫一下 httpWebrequest 中的timeout,這個也坑死我了。