[c#] 服务器提交了协议冲突. Section=ResponseHeader Detail=CR...的解决方案总结

  今天在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;
        }
View Code

    这个方法一定要在HttpWebRequest开始响应之前设置,否则会没有任何效果。

posted on 2014-04-17 19:58  凌晨的搜索者  阅读(7972)  评论(1编辑  收藏  举报

导航