Winform 使用HttpWebRequest 模拟发送json数据的记录

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;

就可以了。为了兼容安全协议的更新。所有就全写上了

以此记录,以防后错。

原文地址:https://www.cnblogs.com/PingPo/p/9178009.html