Hei,
yritän saada haettua internetpalvelimelta tietoja Visual Basic 2010:llä, jotta saan hyödynnettyä niitä Windows Form Application tyyppisessä ohjelmassani.
Tunnistautumisessa käytetään => HTTP Headerseja
PHP:llä on olemassa esimerkki tiedon hakemisesta:
$headers = array( 'Content-type: application/x-www-form-urlencoded; charset=UTF-8', 'Server-API-Key: ??????????????????????????????????????', 'External-Customer-ID: ??????????????????????????????????????' ); $context = stream_context_create(array( 'http' => array( 'method' => 'GET', 'header' => implode("\r\n", $headers), 'ignore_errors' => true ) )); $jsonResponse = file_get_contents('http://www.server.com/api/musikant?from=1950&to=1959®ion=europe', false, $context); if ($jsonResponse) { $responseArray = json_decode($Response, true); print_r($responseArray); } else { echo 'No data :('; }
Minulla ei ole aikaisempaa kokemusta API:n hyödyntämisestä, joten siihen olen tutustunut erilaisien YouTube videoiden yms nettijulkaisujen kautta.
Mutta ongelmani ei ole ratkennut.
Server API ja CustomerID on tarkistettu ja on oikein, joten niissä vika ei ole.
Olen surffannut netissä ja sieltä löytyneistä esimerkeistä kasannut alla olevan koodin.
Olenko unohtanut jotain oleellista koodista kun käytetään HTTP –kyselyitä ja/vai missä menee pieleen?
Osaisiko joku kenties neuvoa fiksuimmat sanat google hakuun? (REST, Headers, http calls yhdistettynä visual basic 2010 ei ole tuottanut toimivaa ratkaisua :(
Servervirhe tulee kohdassa
response = request.GetResponse
Meneekö tunnistautumisen koodit jonnekin väärään?
Tässä koko koodi:
Imports System.Net Imports System.IO Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click TextBox1.Text = Request("http://www.server.com/api/") End Sub Function Request(URL As String) As String Dim responseData As String = "" Dim request As HttpWebRequest = WebRequest.Create(URL & "/musikant?from=1950&to=1959®ion=europe") request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8" request.Headers.Add("Server-API-Key:") request.Headers.Add("??????????????????????????????????????:") request.Headers.Add("External-Customer-ID:") request.Headers.Add("??????????????????????????????????????:") request.Method = WebRequestMethods.Http.Get Dim response As WebResponse ' Try response = request.GetResponse ' TÄHÄN SAAN SERVERERRORIA 401 ja/tai 400 If (CType(response, HttpWebResponse).StatusDescription) = HttpStatusCode.OK Then Dim responseStream As Stream = request.GetRequestStream Dim data As Stream = response.GetResponseStream response.Close() End If ' Catch ex As Exception 'TextBox1.Text = ex.ToString 'End Try Return responseData End Function End Class
Ainakin tuo otsikoiden asettaminen näyttää ihan kummalliselta. Lisäät neljä otsikkoa, joilla ei ole mitään arvoja. Sinun pitäisi lisätä kaksi otsikkoa ja niiden arvot.
' EI NÄIN: request.Headers.Add("A:") request.Headers.Add("B:") request.Headers.Add("C:") request.Headers.Add("D:") ' VAAN NÄIN: request.Headers.Add("A: B") request.Headers.Add("C: D")
Kiitos Metabolix
Nyt ei tullut enää palvelimelta virhettä, vaan OK (200).
Virheilmoitus tuli nyt seuraavasta lauseesta
If (CType(response, HttpWebResponse).StatusDescription) = HttpStatusCode.OK Then
"Muunto merkkijonosta OK lajiksi Double ei ole kelvollinen." Poistin lauseen (korjaan myöhemmin), mutta
virheilmoitus tuli seuraavasta lauseesta stream = request.GetTequestStream lauseesta
"An unhandled exception of type 'System.Net.ProtocolViolationException' occurred in System.dll
Additional information: Tämän verb-tyypin sisältävää sisältöosaa ei voi lähettää."
Tällainen verb-tyyppiin viittaava virhe on tullut aikaisemissa kokeiluissa myös vastaan. Mistä se johtuu? Ovatko verb-tyypit GET ja POST -komentoja?
Pikainen googlaus antoi ymmärtää että sulla pitäis request.method POST, kun lähetät dataa tuolla tavalla. Auttaako? Nyt on siis GET.
Eli koitappa vaihtaa
request.Method = WebRequestMethods.Http.Get
arvoon
request.Method = WebRequestMethods.Http.Post
Voi olla kyllä väärin, ihan pikaisesti koitin etsiä apua.
Itse enemmänkin ehdottaisin, että otat tuon Content-Typen pois, kun kerran et ole itse lähettämässä mitään dataa (eli pyyntö on GET eikä POST). Tosin en tiedä VB.NETin kiemuroita tässä asiassa.
Tuossa edellisessä virheessä veikkaisin, että StatusDescription on teksti ja OK-vakio taas sisältää vastaavan luvun. Ehkä sinun kannattaisi lukea käyttämäsi luokan dokumentaatiosta, mikä on oikea tapa statuksen tarkistukseen. Varmaan luokassa on jokin numeerinen jäsen (esim. Status tai StatusCode), jota voi suoraan verrata HttpStatusCode.OK-vakioon.
Kiitos Quirzo ja Metabolix uhraamastanne ajasta.
Muutin arvon GET -> POST
Virheilmoituksessa palaan takaisin edelliselle riville
response = request.GetResponse
Nyt virheilmoitus on
"Etäpalvelin palautti virheen: (400) Virheellinen pyyntö."
Kun katson request.Headers - sisältää seuraavat tiedot:
{Content-Type: application/x-www-form-urlencoded;charset=UTF-8 Server-API-Key: ??????????????????????????????????????????? External-Customer-ID: ?????????????????????????????????????? Host: www.server.com Connection: Keep-Alive }
Ilmeisesti host ja connection tekstit eivät saisi olla mukana?
request.uri -muuttuja - sisältää "http://www.server.com/api/musikant?from=1950&to=1959®ion=europe"
Minne ja miten lisätään GET -komento, jos request.Method, ei tule tekstiksi komentoon?
Request.Uri.Query on "?from=1950&to=1959®ion=europe" vaikka mielestäni "musikant" olisi ensimmäinen osa querya? Nyt musikant on osa path :ia
PHP koodiin liittyen on tällainen ohje:
Probably the simplest way to do HTTP calls with PHP is to use the file_get_contents() function. Of course there are also many other ways of making HTTP requests with PHP. It is just important to set the correct headers and not add any unnecessary overhead into the requests (e.g. HTML form stuff, multipart boundaries etc.)
ContentTypeen en nyt pääse korjailemaan kun olen kiinni edellisessä lauseessa :)
Olen melko vakuuttunut, että pyyntö on virheellinen siksi, että juuri itse vaihdoit metodiksi POST etkä GET. Kokeile mieluummin minun neuvoani, eli ota turha Content-Type pois, kun et ole lähettämässä mitään.
Varmaan sinun kannattaisi perehtyä hieman HTTP:hen ylipäänsä, jotta ei tarvitsisi arvailla virheiden syitä ja eri rivien merkityksiä. Host ja Connection ovat usein tarpeellisia otsikoita, ja varmasti vika ei ole niissä.
Vaihdon .Method tyyppiä:
GET antaa virheen "Tämän verb-tyypin sisältävää sisältöosaa ei voi lähettää."
POST antaa virheen "Etäpalvelin palautti virheen: (400) Virheellinen pyyntö."
sama virhe tulee kun poistaa rivin
request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8"
Perehdyn HTTP:hen ja palaan sitten tähän ongelmaan :)
Kiitos ajastanne :)
Ongelmahan taitaa olla siinä, että kutsut turhaan metodia GetRequestStream, jota tulisi kutsua vain silloin, kun on tarkoitus lähettää dataa.
Aivan kuten Metabolix jo sanoi, sinun ei pitäisi kutsua GetRequestStream metodia ollenkaan. Korjasin tässä ketjussa mainitut virheet koodistasi:
Function Request(URL As String) As String Dim responseData As String = "" Dim _request As HttpWebRequest = WebRequest.Create(URL & "/musikant?from=1950&to=1959®ion=europe") _request.Headers.Add("Server-API-Key: ??????????????????????????????????????") _request.Headers.Add("External-Customer-ID: ??????????????????????????????????????") _request.Method = WebRequestMethods.Http.Get Dim response As WebResponse 'Try response = _request.GetResponse() If (CType(response, HttpWebResponse).StatusCode) = HttpStatusCode.OK Then Using stream As Stream = response.GetResponseStream() Using reader As StreamReader = New StreamReader(stream) 'Lue stream responseData = reader.ReadToEnd() End Using End Using End If 'Catch ex As Exception 'TextBox1.Text = ex.ToString 'End Try Return responseData End Function
Kiitos Shamppa!
Kiitos myös Metabolix.
Aihe on jo aika vanha, joten et voi enää vastata siihen.