今天在HttpWebRequest發送一個網頁請求的時候,HttpWebResponse返回了一個奇怪的錯誤信息:

這個Http協議請求類可是微軟封裝的,我使用的流程可是中規中矩,不可能是我寫錯代碼,然而看了下抓包工具抓的包,返回一切正常,所以只有一種可能就是對方服務器返回的標頭格式不符合微軟的解析規則。 因此腦袋里第一個想到的就是用Socket重寫HttpWebResponse,可是想了下,HttpWebResponse本身封裝的已經不錯了,如果再去重寫還不一定會比微軟寫的好,況且因為這一個小小的問題就重新去造一個非常復雜精細的輪子,曠日持久不說,水平和質量也令人懷疑。於是乎上網找了下對策。
網上大部分都是在app.Config配置里設置useUnsafeHeaderParsing:
<?xml version="1.0"?>
<configuration>
<system.net>
<settings>
<httpWebRequest useUnsafeHeaderParsing="true" />
</settings>
</system.net>
</configuration>
這個方法證明可行,但是想了下,很多朋友都很不喜歡一個小小的程序因為這個事帶上個配置文件,總感覺心里毛毛的。要是在程序里解決多好。於是乎又花了點時間,在一個國外的論壇里找到了解決方案,用了反射,直接操作System.Net.Configuration.SettingsSectionInternal類下的私有字段。雖然反射會帶來性能上的影響,但是這里貌似沒有更好的辦法,因為不能操作一個封裝好的私有變量。
public static bool SetAllowUnsafeHeaderParsing20(bool useUnsafe) { //Get the assembly that contains the internal class System.Reflection.Assembly aNetAssembly = System.Reflection.Assembly.GetAssembly(typeof(System.Net.Configuration.SettingsSection)); if (aNetAssembly != null) { //Use the assembly in order to get the internal type for the internal class Type aSettingsType = aNetAssembly.GetType("System.Net.Configuration.SettingsSectionInternal"); if (aSettingsType != null) { //Use the internal static property to get an instance of the internal settings class. //If the static instance isn't created allready the property will create it for us. object anInstance = aSettingsType.InvokeMember("Section", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.NonPublic, null, null, new object[] { }); if (anInstance != null) { //Locate the private bool field that tells the framework is unsafe header parsing should be allowed or not System.Reflection.FieldInfo aUseUnsafeHeaderParsing = aSettingsType.GetField("useUnsafeHeaderParsing", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); if (aUseUnsafeHeaderParsing != null) { aUseUnsafeHeaderParsing.SetValue(anInstance, useUnsafe); return true; } } } } return false; }
這個方法一定要在HttpWebRequest開始響應之前設置,否則會沒有任何效果。
