使用C#的HttpWebRequest在.NET 4.5版本中无法工作

6
我正在开发一个使用C#编写的项目,该项目向服务器发送XML并接收XML响应。
在安装了.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 方法,而且所有的参数都不为 null。有人知道哪里有问题吗?为什么在 4.0 版本上能够工作,但是在 4.5 版本上却不能工作呢?我是否忘记设置某些东西了?
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"/>


2
你能展示一下你的代码吗? - glautrou
你能给我们展示一下你的.Config文件吗? - asafrob
不确定在 .net 4 中如何工作。你能否尝试使用 GetResponse() 而不是 BeginGetRespone? - Nilesh
您在 System.DomainNameHelper.IdnEquivalent(String hostname) 处遇到了 NullReferenceException。请参见 如何使 HttpClient 中继流量显示在 Fidder 或 Charles 中?。这是在将 .NET 4 更新为 .NET 4.5 后立即发生的,还是在设置代理的不同机器上发生的? - CodeCaster
@CodeCaster 当我在运行我的程序的电脑上更新了 .Net Framework 时,就会出现这种情况。当安装版本4.0时,它可以正常工作。 - user2621742
4个回答

9

说实话,既然你现在的目标是 .NET 4.5,我建议你考虑使用 HttpClient 而不是 HttpWebRequest。

HttpClient


4
没给他点踩,因为这不是对他问题的回答,只是一个推荐使用其他东西的建议,这些建议应该作为真正答案的评论或附注。 - Rand Random
6
好的,我会尽力进行翻译:我认为有关备选方案的良好建议肯定可以作为答案。 HttpClient 是使用 HTTP 资源的新推荐方式...这不就是一个答案吗? - Jammer
2
让我明确一下 - 这只是我的观点。我不是那个给出负评的人,只是认为如果一个人一开始没有提供关于负评的评论,他永远不会这样做。它不能被视为答案,因为它并没有提供答案,只是提供了另一种解决方法 - 就像有人问你“嘿,为什么我的苹果味道不好?”然后你回答“吃香蕉。”这只是一个替代方案,如果你的苹果味道不好,就吃其他东西,所以如果你遇到 HttpWebRequest 的问题,只需使用 HttpClient。 - Rand Random

6

奇怪的是,之前没有一个严肃的答案被发布...

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

这就是Jammer建议使用HttpClient作为替代方案的原因,因为它似乎是微软为其制定的替代方案。

看起来需要花费一些精力来修改您的代码,但我认为这是最好的选择。


4
这篇文章特别提到了构造函数,但你仍然可以通过 WebRequest.Create 创建一个实例。 - NStuke

1

我在IdnEquivalent中遇到了同样奇怪的问题。当我在调试时同时运行Fiddler网络调试器时,问题仍然存在。但是,在关闭它后问题消失了。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接