HTTP客户端在VB.Net中对网站api.netatmo.com的GET请求总是返回错误。

huangapple go评论129阅读模式
英文:

HTTP Client GET in VB.Net for the site api.netatmo.com always returns an error

问题

抱歉,以下是代码部分的翻译:

  1. Public Class ClassHttpPostNetAtmo
  2. ReadOnly myClientHttp As HttpClient
  3. ReadOnly parametres As New Dictionary(Of String, String)
  4. Dim builder As UriBuilder
  5. Dim query As Specialized.NameValueCollection
  6. ReadOnly dateUnix As New DateTime(1970, 1, 1, 0, 0, 0, 0)
  7. Public Sub New()
  8. myClientHttp = New HttpClient()
  9. End Sub
  10. Public Sub ClearPostParametres()
  11. parametres.Clear()
  12. End Sub
  13. Public Sub AddPostParametre(ByVal key As String, ByVal value As String)
  14. parametres.Add(key, value)
  15. End Sub
  16. Public Async Function PostHttp(ByVal RequestUri As String) As Task(Of String)
  17. Dim content As New FormUrlEncodedContent(parametres)
  18. Dim response As HttpResponseMessage = Await myClientHttp.PostAsync(RequestUri, content)
  19. Dim responseString As String = Await response.Content.ReadAsStringAsync()
  20. Return responseString
  21. End Function
  22. Public Async Function RefreshToken(ByVal vRequestUri As String, ByVal vRefresh_token As String, ByVal vClient_id As String, ByVal vClient_secret As String) As Task(Of Dictionary(Of String, String))
  23. ClearPostParametres()
  24. AddPostParametre("grant_type", "refresh_token")
  25. AddPostParametre("refresh_token", vRefresh_token)
  26. AddPostParametre("client_id", vClient_id)
  27. AddPostParametre("client_secret", vClient_secret)
  28. Dim responseString As String = Await PostHttp(String.Concat(vRequestUri, "/oauth2/token"))
  29. Dim paramRep As New Dictionary(Of String, String)
  30. Dim str() As String = responseString.Replace("{", "").Replace("}", "").Split(",")
  31. For Each strPar As String In str
  32. Dim par() As String = strPar.Split(":")
  33. paramRep.Add(par(0).Replace("""", ""), par(1).Replace("""", ""))
  34. Next
  35. Return paramRep
  36. End Function
  37. Public Sub ClearGetParameter(ByVal vRequestUri As String)
  38. builder = New UriBuilder(vRequestUri) With {
  39. .Port = -1
  40. }
  41. query = HttpUtility.ParseQueryString(builder.Query)
  42. End Sub
  43. Public Sub AddGetParametre(ByVal key As String, ByVal value As String)
  44. If value IsNot Nothing Then
  45. If key = "type" Then
  46. Dim tvalue() As String = value.Split(",")
  47. For Each strVal As String In tvalue
  48. query.Add(key, strVal)
  49. Next
  50. Else
  51. query.Add(key, value)
  52. End If
  53. End If
  54. End Sub
  55. Public Async Function GetHttp() As Task(Of String)
  56. builder.Query = query.ToString()
  57. Dim url As String = builder.ToString()
  58. Dim response As HttpResponseMessage = Await myClientHttp.GetAsync(url)
  59. If response.ReasonPhrase = "ok" Then
  60. Dim responseString As String = Await response.Content.ReadAsStringAsync()
  61. Return responseString
  62. Else
  63. Throw New Exception(String.Concat("Erreur Http GET : ", response.ReasonPhrase, " Status code = ", response.StatusCode))
  64. End If
  65. End Function
  66. Public Async Function GetWeatherData(ByVal vRequestUri As String, ByVal vDeviceId As String, vDateBegin As DateTime, ByVal vDateEnd As DateTime, Optional ByVal vModuleId As String = Nothing, Optional ByVal vScale As String = "30min", Optional ByVal vType As String = "temperature", Optional ByVal vLimit As String = "1024", Optional ByVal vOptimize As String = "false", Optional ByVal vRealTime As String = "true") As Task
  67. ClearGetParameter(String.Concat(vRequestUri, "/api/getmeasure"))
  68. AddGetParametre("device_id", vDeviceId)
  69. AddGetParametre("module_id", vModuleId)
  70. AddGetParametre("scale", vScale)
  71. AddGetParametre("type", vType)
  72. AddGetParametre("date_begin", CType(((vDateBegin.Subtract(dateUnix)).TotalSeconds), Integer).ToString())
  73. AddGetParametre("date_end", CType(((vDateEnd.Subtract(dateUnix)).TotalSeconds), Integer).ToString())
  74. AddGetParametre("limit", vLimit)
  75. AddGetParametre("optimize", vOptimize)
  76. AddGetParametre("real_time", vRealTime)
  77. Dim responseString As String = Await GetHttp()
  78. End Function
  79. End Class

希望这有助于您的问题解决。如果您需要更多帮助,请随时提问。

英文:

Yet the url generated is exactly the same as the one generated by the NetAtmo documentation :
This is the url generated by my program :

> https://api.netatmo.com/api/getmeasure?device_id=70%3Aee%3A50%3A12%3A4d%3A12&module_id=02%3A00%3A00%3A12%3A86%3A30&scale=30min&type=temperature&date_begin=1690468462&date_end=1690469662&limit=1024&optimize=false&real_time=true

This the Netamo from the page https://dev.netatmo.com/apidocumentation/weather#getmeasure :

> https://api.netatmo.com/api/getmeasure?device_id=70%3Aee%3A50%3A12%3A4d%3A12&module_id=02%3A00%3A00%3A12%3A86%3A30&scale=30min&type=temperature&date_begin=1690465917&date_end=1690467117&limit=1024&optimize=false&real_time=true

And this command is working:

> curl -X GET "https://api.netatmo.com/api/getmeasure?device_id=70%3Aee%3A50%3A12%3A4d%3A12&scale=30min&type=temperature&date_begin=1690468462&date_end=1690469662&limit=1024&optimize=false&real_time=true" -H "accept: application/json" -H "Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxx|xxxxxxxxxxxxxxxxxxxxxxxx"

the bearer is changed. What to do on httpClient.Get to have the same ?
It seems that application/json is already there, however the authorization is not necessary it seems to me.

if I replace the URL with the one I generate and the CURL command works, it is therefore in the HttpClient.AsyncGet that there is a problem

The code is :

  1. Public Class ClassHttpPostNetAtmo
  2. ReadOnly myClientHttp As HttpClient
  3. ReadOnly parametres As New Dictionary(Of String, String)
  4. Dim builder As UriBuilder
  5. Dim query As Specialized.NameValueCollection
  6. ReadOnly dateUnix As New DateTime(1970, 1, 1, 0, 0, 0, 0)
  7. Public Sub New()
  8. myClientHttp = New HttpClient()
  9. End Sub
  10. Public Sub ClearPostParametres()
  11. parametres.Clear()
  12. End Sub
  13. Public Sub AddPostParametre(ByVal key As String, ByVal value As String)
  14. parametres.Add(key, value)
  15. End Sub
  16. Public Async Function PostHttp(ByVal RequestUri As String) As Task(Of String)
  17. Dim content As New FormUrlEncodedContent(parametres)
  18. Dim response As HttpResponseMessage = Await myClientHttp.PostAsync(RequestUri, content)
  19. Dim responseString As String = Await response.Content.ReadAsStringAsync()
  20. Return responseString
  21. End Function
  22. Public Async Function RefreshToken(ByVal vRequestUri As String, ByVal vRefresh_token As String, ByVal vClient_id As String, ByVal vClient_secret As String) As Task(Of Dictionary(Of String, String))
  23. ClearPostParametres()
  24. AddPostParametre("grant_type", "refresh_token")
  25. AddPostParametre("refresh_token", vRefresh_token)
  26. AddPostParametre("client_id", vClient_id)
  27. AddPostParametre("client_secret", vClient_secret)
  28. Dim responseString As String = Await PostHttp(String.Concat(vRequestUri, "/oauth2/token"))
  29. Dim paramRep As New Dictionary(Of String, String)
  30. Dim str() As String = responseString.Replace("{", "").Replace("}", "").Split(",")
  31. For Each strPar As String In str
  32. Dim par() As String = strPar.Split(":")
  33. paramRep.Add(par(0).Replace("""", ""), par(1).Replace("""", ""))
  34. Next
  35. Return paramRep
  36. End Function
  37. Public Sub ClearGetParameter(ByVal vRequestUri As String)
  38. builder = New UriBuilder(vRequestUri) With {
  39. .Port = -1
  40. }
  41. query = HttpUtility.ParseQueryString(builder.Query)
  42. End Sub
  43. Public Sub AddGetParametre(ByVal key As String, ByVal value As String)
  44. If value IsNot Nothing Then
  45. If key = "type" Then
  46. Dim tvalue() As String = value.Split(",")
  47. For Each strVal As String In tvalue
  48. query.Add(key, strVal)
  49. Next
  50. Else
  51. query.Add(key, value)
  52. End If
  53. End If
  54. End Sub
  55. Public Async Function GetHttp() As Task(Of String)
  56. builder.Query = query.ToString()
  57. Dim url As String = builder.ToString()
  58. Dim response As HttpResponseMessage = Await myClientHttp.GetAsync(url)
  59. If response.ReasonPhrase = "ok" Then
  60. Dim responseString As String = Await response.Content.ReadAsStringAsync()
  61. Return responseString
  62. Else
  63. Throw New Exception(String.Concat("Erreur Http GET : ", response.ReasonPhrase, " Status code = ", response.StatusCode))
  64. End If
  65. End Function
  66. Public Async Function GetWeatherData(ByVal vRequestUri As String, ByVal vDeviceId As String, vDateBegin As DateTime, ByVal vDateEnd As DateTime, Optional ByVal vModuleId As String = Nothing, Optional ByVal vScale As String = "30min", Optional ByVal vType As String = "temperature", Optional ByVal vLimit As String = "1024", Optional ByVal vOptimize As String = "false", Optional ByVal vRealTime As String = "true") As Task
  67. ClearGetParameter(String.Concat(vRequestUri, "/api/getmeasure"))
  68. AddGetParametre("device_id", vDeviceId)
  69. AddGetParametre("module_id", vModuleId)
  70. AddGetParametre("scale", vScale)
  71. AddGetParametre("type", vType)
  72. AddGetParametre("date_begin", CType(((vDateBegin.Subtract(dateUnix)).TotalSeconds), Integer).ToString())
  73. AddGetParametre("date_end", CType(((vDateEnd.Subtract(dateUnix)).TotalSeconds), Integer).ToString())
  74. AddGetParametre("limit", vLimit)
  75. AddGetParametre("optimize", vOptimize)
  76. AddGetParametre("real_time", vRealTime)
  77. Dim responseString As String = Await GetHttp()
  78. End Function
  79. End Class

The call is here :

  1. Imports ClassLibraryHttpPostNetAtmo
  2. Imports LibraryDivers
  3. Public Class FrmTestMyLibraryNetAtmo
  4. Dim ClientId As String
  5. Dim ClientSecret As String
  6. Dim myNetAtmo As New ClassHttpPostNetAtmo
  7. Dim AccessToken As String
  8. Dim RefreshToken As String
  9. Private Sub FrmTestMyLibraryNetAtmo_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
  10. End Sub
  11. Private Async Sub BtnTest_Click(sender As Object, e As EventArgs) Handles BtnTest.Click
  12. If (My.Settings.AccessToken Is Nothing OrElse My.Settings.AccessToken = "") Or
  13. (My.Settings.RefreshToken Is Nothing OrElse My.Settings.RefreshToken = "") Or
  14. (My.Settings.DateRefreshToken < Now) Then
  15. ClientId = ClassDivers.Decode(My.Settings.ClientId, My.Settings.EncodeNumber)
  16. ClientSecret = ClassDivers.Decode(My.Settings.ClientSecret, My.Settings.EncodeNumber)
  17. Dim par As Dictionary(Of String, String) = Await myNetAtmo.RefreshToken(My.Settings.RequestUri, My.Settings.RefreshToken, ClientId, ClientSecret)
  18. AccessToken = par("access_token")
  19. RefreshToken = par("refresh_token")
  20. My.Settings.AccessToken = par("access_token")
  21. My.Settings.RefreshToken = par("refresh_token")
  22. My.Settings.DateRefreshToken = Now.AddSeconds(par("expire_in")).AddMinutes(-10)
  23. My.Settings.Save()
  24. End If
  25. Await myNetAtmo.GetWeatherData(My.Settings.RequestUri, "70:ee:50:12:4d:12", Now.AddMinutes(-20), Now, vModuleId:="02:00:00:12:86:30")
  26. End Sub
  27. End Class

Well I'm 74 years old and I've never done any web, I don't even know the difference between HTTP GET and HTTP POST.
The HTTP POST to get a refresh token worked fine.
The HTTP POST on the other hand gets stuck.
Well I doubt that this request on NetAtmo has little chance of succeeding but as I don't know how to make it work, I try anyway.

I tried to do an HTTP POST, same result, since I have the same url as the one generated by NetAtmo, I don't understand why it doesn't work and I don't know what to try.
It seems to me that it is the protocol generated by the HTTP client that seems faulty, but why, I don't know.
In any case, it is not an access token problem, because in this case we have the message in clear.

It works great your answer search, I have to try with System.Net.WebClient instead of HtppClient.

I was offered the link:
https://stackoverflow.com/questions/92522/http-get-in-vb-net
which allows to make an HTTP GET with WebClient, but it is obsolete, you have to use HttpClient

答案1

得分: 0

我找到了解决方案:
我只需添加这个参数即可正常工作:

  1. AddGetParametre("access_token", vAccessToken)

非常感谢所有回答这个问题的人。

这是正确的代码:

  1. Public Class ClassHttpPostNetAtmo
  2. ' ... (以下省略,未显示完整代码)
  3. End Class

请注意,我已经将代码中的特殊字符(例如")保留在翻译中,以保持代码的完整性。

英文:

I FIND THE SOLUTION :
I have just to add this parameter to work:

  1. AddGetParametre("access_token", vAccessToken)

Think you very much for all people who answer to this question.

This is the good code:

  1. Public Class ClassHttpPostNetAtmo
  2. ReadOnly myClientHttp As HttpClient
  3. ReadOnly parametres As New Dictionary(Of String, String)
  4. Dim builder As UriBuilder
  5. Dim query As Specialized.NameValueCollection
  6. ReadOnly dateUnix As New DateTime(1970, 1, 1, 0, 0, 0, 0)
  7. Public Property AccessToken As String
  8. Public Sub New()
  9. myClientHttp = New HttpClient()
  10. End Sub
  11. Public Sub ClearPostParametres()
  12. parametres.Clear()
  13. End Sub
  14. Public Sub AddPostParametre(ByVal key As String, ByVal value As String)
  15. parametres.Add(key, value)
  16. End Sub
  17. Public Async Function PostHttp(ByVal RequestUri As String) As Task(Of String)
  18. Dim content As New FormUrlEncodedContent(parametres)
  19. Dim response As HttpResponseMessage = Await myClientHttp.PostAsync(RequestUri, content)
  20. Dim responseString As String = Await response.Content.ReadAsStringAsync()
  21. Return responseString
  22. End Function
  23. Public Async Function RefreshToken(ByVal vRequestUri As String, ByVal vRefresh_token As String, ByVal vClient_id As String, ByVal vClient_secret As String) As Task(Of Dictionary(Of String, String))
  24. ClearPostParametres()
  25. AddPostParametre("grant_type", "refresh_token")
  26. AddPostParametre("refresh_token", vRefresh_token)
  27. AddPostParametre("client_id", vClient_id)
  28. AddPostParametre("client_secret", vClient_secret)
  29. Dim responseString As String = Await PostHttp(String.Concat(vRequestUri, "/oauth2/token"))
  30. Dim paramRep As New Dictionary(Of String, String)
  31. Dim str() As String = responseString.Replace("{", "").Replace("}", "").Split(",")
  32. For Each strPar As String In str
  33. Dim par() As String = strPar.Split(":")
  34. paramRep.Add(par(0).Replace("""", ""), par(1).Replace("""", ""))
  35. Next
  36. Return paramRep
  37. End Function
  38. Public Sub ClearGetParameter(ByVal vRequestUri As String)
  39. builder = New UriBuilder(vRequestUri) With {
  40. .Port = -1
  41. }
  42. query = HttpUtility.ParseQueryString(builder.Query)
  43. End Sub
  44. Public Sub AddGetParametre(ByVal key As String, ByVal value As String)
  45. If value IsNot Nothing Then
  46. If key = "type" Then
  47. Dim tvalue() As String = value.Split(",")
  48. For Each strVal As String In tvalue
  49. query.Add(key, strVal)
  50. Next
  51. Else
  52. query.Add(key, value)
  53. End If
  54. End If
  55. End Sub
  56. Public Async Function GetHttp() As Task(Of String)
  57. builder.Query = query.ToString()
  58. Dim url As String = builder.ToString()
  59. myClientHttp.DefaultRequestHeaders.Accept.Clear()
  60. Dim response As HttpResponseMessage = Await myClientHttp.GetAsync(url)
  61. Dim str = Await response.Content.ReadAsStringAsync()
  62. If response.ReasonPhrase = "OK" Then
  63. Return str
  64. Else
  65. Throw New Exception(String.Concat("Erreur Http GET : ", response.ReasonPhrase, " Status code = ", response.StatusCode, vbCrLf, response.RequestMessage.RequestUri.OriginalString))
  66. End If
  67. End Function
  68. ' ,humidity,co2,pressure,noise,rain,windstrength,windangle
  69. Public Async Function GetWeatherData(ByVal vRequestUri As String, ByVal vDeviceId As String, vDateBegin As DateTime, ByVal vDateEnd As DateTime, Optional ByVal vModuleId As String = Nothing, Optional ByVal vScale As String = "max", Optional ByVal vType As String = "temperature", Optional ByVal vLimit As String = "1024", Optional ByVal vOptimize As String = "false", Optional ByVal vRealTime As String = "true") As Task
  70. ClearGetParameter(String.Concat(vRequestUri, "/api/getmeasure"))
  71. AddGetParametre("device_id", vDeviceId)
  72. AddGetParametre("module_id", vModuleId)
  73. AddGetParametre("scale", vScale)
  74. AddGetParametre("type", vType)
  75. AddGetParametre("date_begin", CType(((vDateBegin.Subtract(dateUnix)).TotalSeconds), Integer).ToString())
  76. AddGetParametre("date_end", CType(((vDateEnd.Subtract(dateUnix)).TotalSeconds), Integer).ToString())
  77. AddGetParametre("limit", vLimit)
  78. AddGetParametre("optimize", vOptimize)
  79. AddGetParametre("real_time", vRealTime)
  80. AddGetParametre("access_token", AccessToken)
  81. Dim responseString As String = Await GetHttp()
  82. End Function
  83. Public Async Function GetStationsData(ByVal vRequestUri As String, ByVal vDeviceId As String) As Task
  84. ClearGetParameter(String.Concat(vRequestUri, "/api/getstationsdata"))
  85. AddGetParametre("device_id", vDeviceId)
  86. AddGetParametre("get_favorites", "false")
  87. AddGetParametre("access_token", AccessToken)
  88. Dim responseString As String = Await GetHttp()
  89. End Function
  90. Imports ClassLibraryHttpPostNetAtmo
  91. Imports LibraryDivers
  92. Public Class FrmTestMyLibraryNetAtmo
  93. Dim ClientId As String
  94. Dim ClientSecret As String
  95. Dim myNetAtmo As New ClassHttpPostNetAtmo
  96. Dim AccessToken As String
  97. Dim RefreshToken As String
  98. Private Sub FrmTestMyLibraryNetAtmo_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
  99. End Sub
  100. Private Async Sub BtnTest_Click(sender As Object, e As EventArgs) Handles BtnTest.Click
  101. If (My.Settings.AccessToken Is Nothing OrElse My.Settings.AccessToken = "") Or
  102. (My.Settings.RefreshToken Is Nothing OrElse My.Settings.RefreshToken = "") Or
  103. (My.Settings.DateRefreshToken < Now) Then
  104. ClientId = ClassDivers.Decode(My.Settings.ClientId, My.Settings.EncodeNumber)
  105. ClientSecret = ClassDivers.Decode(My.Settings.ClientSecret, My.Settings.EncodeNumber)
  106. Dim par As Dictionary(Of String, String) = Await myNetAtmo.RefreshToken(My.Settings.RequestUri, My.Settings.RefreshToken, ClientId, ClientSecret)
  107. AccessToken = par("access_token")
  108. RefreshToken = par("refresh_token")
  109. My.Settings.AccessToken = par("access_token")
  110. My.Settings.RefreshToken = par("refresh_token")
  111. My.Settings.DateRefreshToken = Now.AddSeconds(par("expire_in")).AddMinutes(-10)
  112. My.Settings.Save()
  113. End If
  114. Try
  115. myNetAtmo.AccessToken = My.Settings.AccessToken
  116. Await myNetAtmo.GetStationsData(My.Settings.RequestUri, "70:ee:50:12:4d:12")
  117. ' Await myNetAtmo.GetWeatherData(My.Settings.RequestUri, "70:ee:50:12:4d:12", Now.AddMinutes(-20), Now, vModuleId:="02:00:00:12:86:30")
  118. Catch ex As Exception
  119. MessageBox.Show(String.Concat(ex.Message, vbCr, ex.StackTrace))
  120. End Try
  121. End Sub
  122. End Class

huangapple
  • 本文由 发表于 2023年7月28日 02:46:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76782631.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定