为什么我的 VB.NET WebRequest 会突然停止工作?

Why would my VB.NET WebRequest suddenly stop working?

不久前,我在 VB.NET 中编写了一个程序来使用 Betfair Exchange API。它已经完美运行了几个月,但在星期二的一夜之间它停止了工作。我仍然可以登录,但从星期三开始我无法从服务器获取任何其他信息。

Betfair 正在调查,但根据他们的说法,似乎没有其他人遇到同样的问题 - 虽然我不确定有多少人会使用 VB.NET。

下面是我用来从 API 获取数据的函数。就像我说的那样,它在周二晚上开始工作,但从周三早上开始就没有了。这里有什么“不完美”或“可以更好”的东西吗,或者我可以尝试一些替代代码?还是我的电脑上发生了什么导致了这个问题?

程序在“dataStream = request.GetRequestStream()”行失败。错误是“从传输流中收到意外的 EOF 或 0 字节。”

如果有人能提供任何建议,我将不胜感激。谢谢!

Public Function CreateRequest(ByVal postData As String, Optional ByVal accountsApi As Boolean = False)
    Dim Url As String = "https://api.betfair.com/exchange/betting/json-rpc/v1"
    If accountsApi Then Url = "https://api.betfair.com/exchange/account/json-rpc/v1"
    Dim request As WebRequest = Nothing
    Dim dataStream As Stream = Nothing
    Dim response As WebResponse = Nothing
    Dim strResponseStatus As String = ""
    Dim reader As StreamReader = Nothing
    Dim responseFromServer As String = ""
    Try
        request = WebRequest.Create(New Uri(Url))
        request.Method = "POST"
        request.ContentType = "application/json-rpc"
        request.Headers.Add(HttpRequestHeader.AcceptCharset, "ISO-8859-1,utf-8")
        request.Headers.Add("X-Application", appKey)
        request.Headers.Add("X-Authentication", sessToken)
        Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData) ' Data to post such as ListEvents, ListMarketCatalogue etc
        request.ContentLength = byteArray.Length ' Set the ContentLength property of the WebRequest.
        dataStream = request.GetRequestStream() ' Get the request stream.
        dataStream.Write(byteArray, 0, byteArray.Length) ' Write the data to the request stream.
        dataStream.Close() ' Close the Stream object.
        response = request.GetResponse() ' Get the response.
        strResponseStatus = CType(response, HttpWebResponse).StatusDescription ' Display the status below if required
        dataStream = response.GetResponseStream() ' Get the stream containing content returned by the server.
        reader = New StreamReader(dataStream) ' Open the stream using a StreamReader for easy access.
        responseFromServer = reader.ReadToEnd() ' Read the content.
        reader.Close() : dataStream.Close() : response.Close()
    Catch ex As Exception
        MsgBox("CreateRequest Error" & vbCrLf & ex.Message, MsgBoxStyle.Critical, " Error")
    End Try
    Return responseFromServer
End Function

我会检查提供商最近是否已弃用 TLS 1.0(事实上,他们之前应该已经弃用了)。

如果是这样,您的代码需要强制使用 TLS 1.1+:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

这只需设置一次,通常在(静态)类型初始化器或类似的初始化器中。

而且我 100% 同意 Andrew Mortimer 的观点,即您应该尽可能使用 Using 块。我还建议将所有字符串值移动到变量或常量中以清理并保持它们的可维护性。例如:

Const ContentType As String = "application/json-rpc"
...
request.ContentType = ContentType

更新

我刚刚在他们的网站上发现了这条公告:

https://forum.developer.betfair.com/forum/developer-program/announcements/33563-tls-1-0-no-longer-supported-from-1st-december-all-betfair-api-endpoints

如果允许您在此项目中使用外部依赖项,我建议使用 RestSharp nuget 包,它非常适合创建 API 请求并获得响应,而无需使用变得混乱的 httpclient。

Link: https://restsharp.dev/