【问题标题】:HttpWebRequest in c# do not work with .net 4.5c# 中的 HttpWebRequest 不适用于 .net 4.5
【发布时间】:2013-08-13 08:08:43
【问题描述】:

我正在开发一个将 xml 发送到服务器并接收 xml 作为响应的 c# 项目。
安装 .Net Framework 4.0 后运行良好。
安装 .Net Framework 4.5 后会抛出此异常:

System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.  
bei System.DomainNameHelper.IdnEquivalent(String hostname)  
bei System.Uri.get_IdnHost()  
bei System.Net.HttpWebRequest.GetSafeHostAndPort(Uri sourceUri, Boolean addDefaultPort, Boolean forcePunycode)  
bei System.Net.HttpWebRequest.GenerateProxyRequestLine(Int32 headersSize)  
bei System.Net.HttpWebRequest.SerializeHeaders()  
bei System.Net.HttpWebRequest.EndSubmitRequest()  
bei System.Net.HttpWebRequest.CheckDeferredCallDone(ConnectStream stream)  
bei System.Net.HttpWebRequest.BeginGetResponse(AsyncCallback callback, Object state)  
bei Fahrzeugverwaltungsserver.OutsideWorld.MAN_Integrationsserver.RawCommunication.ISServer.doPostAndGet()`  

我使用BeginGetResponse方法,所有参数都不为空。
有谁知道怎么回事?
为什么它适用于 4.0 而不适用于 4.5?
我忘记设置什么了吗?

编辑 1

private void doPostAndGet()
    {
        try
        {
            //caching  
            inform(SystemIcons.Information, Translations.ISServer_postAndGet_0);  
            Trace.TraceInformation("OUT:\n" + Beautify(InputXML));  

            string c = cache.Get(InputXML.OuterXml);
            if (c != null)
            {
                XmlDocument docl = new XmlDocument();
                docl.LoadXml(c);
                inform(SystemIcons.Information, Translations.ISServer_postAndGet_1);
                printInDocument(docl, "Aus Cache.");
                this.doc = docl;
            }

            //Read access information:
            UriBuilder urib = new UriBuilder("http", MANHaendlerdaten.IS_host, 9005, MANHaendlerdaten.IS_path);

            urib.UserName = MANHaendlerdaten.IS_user;
            urib.Password = MANHaendlerdaten.IS_password;

            String proxyUser = MANHaendlerdaten.IS_proxy_user;
            String proxyPassword = MANHaendlerdaten.IS_proxy_password;

            // create credentials for request's header:
            var proxy =
            Convert.ToBase64String(
            Encoding.UTF8.GetBytes(proxyUser + ":" + proxyPassword));

            var user =
            Convert.ToBase64String(
            Encoding.UTF8.GetBytes(urib.UserName + ":" + urib.Password));

            //set proxy when needed:
            try
            {
                WebRequest.DefaultWebProxy = new WebProxy(MANHaendlerdaten.IS_proxy_ip, MANHaendlerdaten.IS_proxy_port);
                if (WebRequest.DefaultWebProxy == null)
                    Trace.WriteLine(String.Format("WebRequest.DefaultWebProxy ist null. {0}, {1}", MANHaendlerdaten.IS_proxy_ip, MANHaendlerdaten.IS_proxy_port));
            }
            catch (Exception e)
            {
                Trace.TraceError("1\n" + e.ToString());
                Debug.WriteLine(Translations.ISServer_postAndGet_3);
                WebRequest.DefaultWebProxy = null; //speed up further request by avoiding proxy-auto-detect
                //pass when no proxy specified
            }

            // System.Net.ServicePointManager.Expect100Continue = false //this is a nasty one if not set to false            

            client = (HttpWebRequest)WebRequest.Create(urib.Uri);

            //Encodings:
            client.Headers.Add("Accept-Encoding", "deflate");

            client.ContentType = "text/xml; charset=UTF-8";

            client.Accept = "text/xml; charset=UTF-8";

            client.Headers.Add("SOAPAction", "\"\"");

            //Authentification:        
            client.Headers.Add("Proxy-Authorization", "Basic " + proxy);

            client.Headers.Add("Authorization", "Basic " + user);


            //Connection and Protocol:
            client.Host = urib.Host;

            client.UserAgent = Translations.FullServiceName;

            client.ProtocolVersion = HttpVersion.Version10;

            client.KeepAlive = true;

            client.Method = WebRequestMethods.Http.Post;

            client.Timeout = 60000;

            client.Proxy = new WebProxy(MANHaendlerdaten.IS_proxy_ip, MANHaendlerdaten.IS_proxy_port);

            if (client.Proxy == null)
                Trace.WriteLine(String.Format("client.Proxy ist null. {0}, {1}", MANHaendlerdaten.IS_proxy_ip, MANHaendlerdaten.IS_proxy_port));

            client.ReadWriteTimeout = 60000;


            //accept cookies within this ISServer-instance
            if (this.cookieCont == null)
            {
                this.cookieCont = new CookieContainer();
            }

            client.CookieContainer = cookieCont;


            inform(SystemIcons.Information, Translations.ISServer_postAndGet_7);

            //Post request:
            using (Stream to_request = client.GetRequestStream())
            {
                InputXML.Save(to_request);
                to_request.Flush();
            }


            RequestState myRequestState = new RequestState();
            myRequestState.request = client;


            webrequestresponse = false;
            IAsyncResult asyncResult = client.BeginGetResponse(new AsyncCallback(FinishWebRequest), myRequestState);
            while (webrequestresponse == false)
            {
                Thread.Sleep(100);
            }
        }
        catch (Exception e)
        {
            Trace.TraceError(e.ToString());
            throw e;
        }
}  

编辑 2
在我的配置文件中,我主要使用 appsettings 进行个人设置。点赞:
<add key="DATABASE_CONNECTION" value="FIREBIRD"/>

【问题讨论】:

  • 你能告诉我们你的代码吗?
  • 你能给我们看看你的 .Config 文件吗?
  • 不确定这在 .net 4 中是如何工作的。您可以尝试使用 GetResponse() 代替 BeginGetRespone 吗?
  • 您在System.DomainNameHelper.IdnEquivalent(String hostname) 有一个NullReferenceException。另见How to make HttpClient relay traffic show up in Fidder or Charles?。将 .NET 4 更新到 .NET 4.5 后会立即发生这种情况,还是它是设置了代理的另一台机器?
  • @CodeCaster 当我在运行我的程序的 PC 上更新 .Net Framework 时会发生这种情况。安装 4.0 版后,它工作正常。

标签: c# .net httpwebrequest


【解决方案1】:

说实话,您现在的目标是 .NET 4.5,我会考虑使用 HttpClient 而不是 HttpWebRequest。

HttpClient

【讨论】:

  • 没有投反对票 - 这并不是对他问题的真正答案,只是建议使用其他东西,这样的东西应该是真正答案的评论或旁注。
  • 我认为关于替代选择的好建议绝对可以作为答案。 HttpClient 是新的推荐使用 HTTP 资源的方式……这不是一个答案吗?
  • 说清楚——这只是我对此事的看法。我不是那个投反对票的人,只是相信当这个人一开始没有就投反对票发表评论时,他永远不会。它不能被认为是一个答案,因为它没有提供答案,只是一个替代方案——就像有人问你“嘿,为什么我的苹果味道不好?”你回答“吃横幅”。它只是没有直接的答案,但是如果你的苹果味道不好,可以替代他的问题,吃点别的,所以如果你遇到 HttpWebRequest 的问题,只需使用 HttpClient。
【解决方案2】:

奇怪的是没有一个严肃的答案已经发布......

HttpWebRequest 在 .NET 4.5 及更高版本中已过时,因此无法编译,这在 msdn site 中注明

这就是为什么 Jammer 说要使用 HttpClient 作为替代品,因为它似乎是微软为它制作的替代品。

看起来这将是一个努力来改变你的代码,但我会说这一切都是为了最好的

【讨论】:

  • 链接的msdn文章特别注意构造函数,您仍然可以通过WebRequest.Create创建实例。
【解决方案3】:

我在 IdnEquivalent 中遇到了同样奇怪的问题。当我在调试会话期间启动 Fiddler Web 调试器时,问题仍然存在。关闭后问题就消失了。

【讨论】:

    【解决方案4】:

    如前所述,HttpWebRequest 现在已经过时了。你试过 HttpRequest 吗?在这里找到:https://msdn.microsoft.com/en-us/library/system.web.httprequest(v=vs.110).aspx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-16
      • 2011-10-09
      • 1970-01-01
      • 2013-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多