我是一名初学者 C# 开发人员,我有点卡住了。
我有一个项目,我需要在发出 HTTP 请求时保留相同的会话 ID cookie。请求工作正常,我在 API 中创建了我需要的东西(它是一个货币兑换 API)。问题是,当我创建购买付款时,比如说 100 英镑,我会进入需要授权付款的屏幕。在这里,我的汇率有效期为 1.5 分钟。当时间结束时,费率会刷新。要锁定费率,我需要授权付款。当我授权时,我会进入屏幕等待付款。这里的汇率现在已锁定,但问题是汇率与我锁定的不同。该网站的所有者告诉我,这是因为创建付款和授权的请求上的会话 ID 不同。
这是来自 API 文档:
API 连接可以通过 cURL 等 HttpsRequest 组件建立。如果 cURL 库在所需语言版本中不可用,则替代方案应提供如下:
- 所有 cURL 查询/请求/数据传输都应仅使用 HTTPS 协议。
- 所有敏感信息必须通过POST方式发送;
- SSL 证书和 SSL 主机验证。它将防止 DNS 黑客攻击。参见 CURLOPT_SSL_VERIFYHOST 和 CURLOPT_SSL_VERIFYPEER
- 会话和 cookie 支持;
我找到的示例代码是在 PHP 中使用 Curl。这是我使用 LibCurlNet 想出的:
public class Http
{
string _xmlResponse = string.Empty;
private static Easy easy;
private static Easy.WriteFunction wf = null;
public string PerformRequest(string xml, string queryString, string url)
{
try
{
_xmlResponse = string.Empty;
Curl.GlobalInit((int)CURLinitFlag.CURL_GLOBAL_ALL);
easy = new Easy();
wf = new Easy.WriteFunction(OnWriteData);
easy.SetOpt(CURLoption.CURLOPT_URL, url);
easy.SetOpt(CURLoption.CURLOPT_WRITEFUNCTION, wf);
easy.SetOpt(CURLoption.CURLOPT_COOKIEFILE, HttpContext.Current.Request.MapPath("~/cookies.txt"));
easy.SetOpt(CURLoption.CURLOPT_COOKIEJAR, HttpContext.Current.Request.MapPath("~/cookies.txt"));
easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYPEER, true);
easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYHOST, true);
easy.SetOpt(CURLoption.CURLOPT_CAINFO, HttpContext.Current.Request.MapPath("~/ssl.crt"));
easy.SetOpt(CURLoption.CURLOPT_HEADER, 0);
easy.SetOpt(CURLoption.CURLOPT_FOLLOWLOCATION, true);
easy.SetOpt(CURLoption.CURLOPT_USERAGENT, "xxx Web XML API");
easy.SetOpt(CURLoption.CURLOPT_BUFFERSIZE, 65536);
easy.SetOpt(CURLoption.CURLOPT_POSTFIELDS, CleanXML(xml));
easy.Perform();
easy.Cleanup();
Curl.GlobalCleanup();
}
catch (Exception ex)
{
return ex.Message;
}
return _xmlResponse;
}
public Int32 OnWriteData(Byte[] buf, Int32 size, Int32 nmemb,
Object extraData)
{
_xmlResponse = _xmlResponse + System.Text.Encoding.UTF8.GetString(buf);
return size * nmemb;
}
private string CleanXML(string xml)
{
char[] sep = Environment.NewLine.ToArray();
string[] lines = xml.Split(sep);
StringBuilder sb = new StringBuilder();
foreach (string line in lines)
{
sb.Append(line.Trim());
}
return sb.ToString();
}
}
问题是 cookie.txt 会在我创建的每个连接中更新会话 ID。
带有 HttpWebRequest 的代码:
public class HttpV2
{
static CookieCollection cookie = new CookieCollection();
string responseFromServer;
public string GetHttpResponse(string Url, string requestBody)
{
//WebRequest request = WebRequest.Create(Url);
HttpWebRequest request = HttpWebRequest.CreateHttp(Url);
X509Certificate Cert = X509Certificate.CreateFromCertFile(@"D:\www_root\xxxxxxxxxxx\xxxxx\ssl.crt");
request.ClientCertificates.Add(Cert);
request.Method = "POST";
//HttpContext context = HttpContext.Current;
request.CookieContainer = new CookieContainer();
request.UserAgent = "TranferMate Web XML API";
if (cookie != null)
{
request.CookieContainer.Add(cookie);
}
byte[] byteArray = Encoding.UTF8.GetBytes(requestBody);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
#region Get the response.
using (WebResponse response = request.GetResponse())
{
if (requestBody.Contains("<FORCE_REFRESH>1</FORCE_REFRESH>"))
{
cookie = ((HttpWebResponse)response).Cookies;
}
if (((HttpWebResponse)response).StatusCode == HttpStatusCode.OK)
using (Stream stream = response.GetResponseStream())
{
if (stream != null)
{
using (StreamReader reader = new StreamReader(stream))
{
responseFromServer = reader.ReadToEnd();
reader.Close();
}
stream.Close();
}
}
response.Close();
}
#endregion
return responseFromServer;
}
}