HttpWebRequest req = HttpWebRequest.Create(serviceUrl) as HttpWebRequest; --serviceUrl 要访问的http地址
req.ContentLength = fparRequestJsonBytes.Length; ----如果要发送数据,需要指定长度,fparRequestJsonBytes为数据的字节数据形式
//req.ContentType = "application/x-www-form-urlencoded";
req.ContentType = "application/json";
req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
req.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
req.Method = "POST";
req.KeepAlive = false;
req.Timeout = timeoutcount;
req.ProtocolVersion = HttpVersion.Version10;
req.UserAgent = "Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0";
req.AllowAutoRedirect = false;
//如果需要使用代理访问
WebProxy proxy = new WebProxy("10.245.34.231:3128",false);
//WebProxy proxy1 = new WebProxy()
req.Proxy = proxy;
//如果需要使用证书,pfx为证书全名称
X509Certificate2 cert = new X509Certificate2();
cert.Import(pfx, "", X509KeyStorageFlags.PersistKeySet);
req.ClientCertificates.Add(cert);
ServicePointManager.CheckCertificateRevocationList = false;
//指定安全协议,这里写上了所有的协议。
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11|SecurityProtocolType.Tls|SecurityProtocolType.Tls12|SecurityProtocolType.Ssl3;
ServicePointManager.DefaultConnectionLimit = 512;
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(RemoteCertificateValidate); //RemoteCertificateValidate方法返回true
//写入信息流
try
{
reqStream = req.GetRequestStream();
}
catch (System.Net.WebException ex)
{
MessageBox.Show(ex.ToString());
req.Abort();
}
// send web request
reqStream.Write(fparRequestJsonBytes, 0, fparRequestJsonBytes.Length);
reqStream.Flush();
reqStream.Close();
// get response
Stream respStream = req.GetResponse().GetResponseStream();
StreamReader sr = null;
string respXml = null;
try
{
sr = new StreamReader(respStream, Encoding.UTF8);
respXml = sr.ReadToEnd();
//这里是取出返回的json字符串的值。json格式 {"root": {"message": "Internal Database Error", "code": 12154}}
object obj = JsonConvert.DeserializeObject(respXml);
Newtonsoft.Json.Linq.JObject js = obj as Newtonsoft.Json.Linq.JObject;//把上面的obj转换为 Jobject对象
Newtonsoft.Json.Linq.JToken model = js["root"];//取Jtoken对象 通过Jobject的索引获得到
string code = model["code"].ToString();
//然后根据code判断服务器返回是否成功。省略
}
catch (WebException webEx)
{
using (StreamReader exSr = new StreamReader(webEx.Response.GetResponseStream(), Encoding.UTF8))
{
string respExMessage = exSr.ReadToEnd();
//Console.WriteLine("Got response message within exception: " + respExMessage);
}
throw;
}
finally
{
if (sr != null) sr.Close();
if (srXml != null) srXml.Close();
}
总结:在使用HttpWenRequest过程中,如果报错 :System.Net.WebException: 基础连接已经关闭: 发送时发生错误。 ---> System.IO.IOException: 由于远程方已关闭传输流,身份验证失败。
总结网上的解决方法,可能是如下配置问题;
1、ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
2、request.ProtocolVersion = HttpVersion.Version10;
3、ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
4.req.UserAgent = "Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0"; //这里是用的火狐
在试过上面所有方法之后,还是浏览器可以正常发送访问,应用程序一直报上面的错。
最后发现原因是:
IE浏览使用的是TSL1.1 的安全协议(一个一个试过,勾选TSL1.0 浏览器也不能访问,勾选TSL1.1能访问);
参照SecurityProtocolType枚举对应的安全协议。更改ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;
就可以了。为了兼容安全协议的更新。所有就全写上了
以此记录,以防后错。