这几天给系统做第三方集成, 需要调用另一个软件的一个接口, 通过 HTTP 的方式调用,调用代码也挺简单的:
string serviceUrl = string.Format("{0}/{1}", this.BaseUrl, path); HttpWebRequest request = null; Stream reqStream = null; request = (System.Net.HttpWebRequest)WebRequest.Create(serviceUrl); request.Method = "POST"; request.Accept = "*/*"; request.ContentType = "application/json;charset=UTF-8"; byte[] postData = Encoding.UTF8.GetBytes(param); reqStream = request.GetRequestStream(); reqStream.Write(postData, 0, postData.Length); using (var response = (HttpWebResponse)request.GetResponse()) { Stream myResponseStream = response.GetResponseStream(); StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("UTF-8")); string retString = myStreamReader.ReadToEnd(); myStreamReader.Close(); myResponseStream.Close(); return retString; }
代码也没有什么特别的,但是当代码执行到 request.GetResponse() 时,程序是不报错, 也不往下执行了,就一直卡在这里,服务器端也没有接收到请求(服务端是没有问题的),找了一上午,各种属性都设置了一遍,都没有效果,最后突然想到好像少了给 request 设置一个 ContentLength 属性, 马上加上 request.ContentLength = postData.Length, 再测试就好了。
这个问题找这么久, 是因为刚开始在我本地做测试的时候是没有问题, 一切都正常, 部署到服务器上后发现调用不通, 所以刚开始以为是服务器这边有什么端口限制什么的,所以一直在叫服务器管理人员查网络设置,后来为了测试方便,在本地创建了一个 WINFORM 程序来测试,发现在 WINFORM 程序里测试的时候也不行了,再运行之前的写的测试程序,又可以, 比较了一下两个 .NET 版本,之前使用的是 .NET FRAMEWORK 4.7, WINFORM 使用的是 .NET FRAMEWORK 3.5。
在 .net framework 4.7 应该对这个属性做了处理, 但是在 3.5 里, 没有这个属性, 就没有任何反应,这个也太坑了点, 抛出一个异常也好啊!
-----
今天(2020-03-18)在处理一个项目的接口, 又发生超时的问题, ContentLength 属性也加了, 都没用, 使用 postman 请求没问题, 网址使用浏览器也可以访问, 但是就是使用 .net 代码请求有问题, 这次在 .NET 4.8 下面测试都不行,最后经测试,发现还需要设置一个属性:
request.ServicePoint.Expect100Continue = false;
好吧, 终于可以请求了!