Can we call JSON POST API from VB.NET Windows App? - vb.net

Here I am always getting "The remote server returned an error: (500) Internal Server Error.". Even the API is correct and working nicely through POSTMAN and in other languages also. Please guide me so solve this issue. I am attaching the function which is calling the API directly.
Private Function SendRequest() As String
Dim response As String
Dim request As WebRequest
Dim encoding As New System.Text.ASCIIEncoding
Dim uri = ""
Dim Tran = "15"
Dim Amount As Integer = 1000
Dim ReferenceID = "015bfa15-15ec-4dc7-903c-053ffacb6688"
Dim POS = "57290070"
Dim Store = "RESTSIM00000001"
Dim Chain = "J#P-Reg"
Dim JSONString = "{""tran"":""" & Tran & """,""amount"":""" & Amount & """,""reference"":""" & ReferenceID & """,""pos"":""" & POS & """,""store"":""" & Store & """,""chain"":""" & Chain & """}"
Dim jsonDataBytes() As Byte = encoding.GetBytes(JsonConvert.SerializeObject(JSONString))
request = WebRequest.Create(uri)
request.ContentLength = jsonDataBytes.Length
request.ContentType = "application/json"
request.Method = "POST"
Using requestStream = request.GetRequestStream
requestStream.Write(jsonDataBytes, 0, jsonDataBytes.Length)
requestStream.Close()
Using responseStream = request.GetResponse.GetResponseStream
Using reader As New StreamReader(responseStream)
response = reader.ReadToEnd()
End Using
End Using
End Using
Return response
End Function

Related

Creating new tasks with the Wrike API and VB.net

I'm having trouble creating new Wrike tasks using VB.net and the Wrike API. I however, am able to connect to Wrike to GET a list of folders so I know I'm able to successfully authenticate.
Link to task creation docs:
https://developers.wrike.com/documentation/api/methods/create-task
The only required field is "Title"
Dim accessToken As String = API_Token
Dim apiVersion As String = "v4"
Dim ApiBaseUrl As String = "https://www.wrike.com"
Dim folderID As String = "Some Folder ID Here"
Dim address As String = ApiBaseUrl & "/api/" & apiVersion & "/folders/" & folderID & "/tasks"
Dim result As String
Dim task_str_ As String = "importance=Normal&description=Test task description&dates={""start"":""2019-07-24"",""due"":""2019-07-30""}&title=Task Created With VS&status=Active"
Try
Dim request As HttpWebRequest = TryCast(WebRequest.Create(address), HttpWebRequest)
request.Headers.Add("Authorization", "Bearer " & accessToken)
request.Method = "PUT"
request.ContentType = "application/json"
Using requestWriter2 As New StreamWriter(request.GetRequestStream())
requestWriter2.Write(task_str_)
End Using
Dim webResp As WebResponse = request.GetResponse()
Using reader = New StreamReader(webResp.GetResponseStream)
result = reader.ReadToEnd()
End Using
TextBox1.Text = (result)
Catch ex As Exception
TextBox1.Text = ex.ToString
End Try
Here is the error I'm receiving:
System.Net.WebException: The remote server returned an error: (400) Bad Request
Once I made the suggested changes, everything works good.
Dim accessToken As String = API_Token
Dim apiVersion As String = "v4"
Dim ApiBaseUrl As String = "https://www.wrike.com"
Dim folderID As String = "Some Folder ID Here"
Dim address As String = ApiBaseUrl & "/api/" & apiVersion & "/folders/" & folderID & "/tasks"
Dim result As String
Dim task_str_ As String = "importance=Normal&description=Test task description&dates={""start"":""2019-07-24"",""due"":""2019-07-30""}&title=Task Created With VS&status=Active"
Try
Dim request As HttpWebRequest = TryCast(WebRequest.Create(address), HttpWebRequest)
request.Headers.Add("Authorization", "Bearer " & accessToken)
request.Method = "POST"
request.ContentLength = task_str_.Length
request.ContentType = "application/x-www-form-urlencoded"
Using requestWriter2 As New StreamWriter(request.GetRequestStream())
requestWriter2.Write(task_str_)
End Using
Dim webResp As WebResponse = request.GetResponse()
Using reader = New StreamReader(webResp.GetResponseStream)
result = reader.ReadToEnd()
End Using
TextBox1.Text = (result)
Catch ex As Exception
TextBox1.Text = ex.ToString
End Try

Neo4j 2.3.0-M01 cypher query from VB.NET failing

Recently installed new version of Neo4j on Windows 7 Prof PC. Able to create nodes using API batch inserts. Cypher queries from web interface work but now fail from VB.NET code at the line after the comment 'retrieve results of query, which will be in JSon. This ran okay on the previous Neo4j version (2.2.x)
Public Shared Function DBQuery(URI As String, PostString As String) As DataView
'runs query and returns JSon results as a dataview
'Uses POST method to access Neo4j Server API
Dim S As String = ""
Dim HttpWReq As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create(URI)
HttpWReq.Method = "POST"
HttpWReq.ContentType = "application/json"
HttpWReq.Accept = "application/json"
Dim B1() As Byte = System.Text.Encoding.Unicode.GetBytes(PostString, 0, Len(PostString))
'POST query
'http://blog.micic.ch/net/using-neo4j-graph-db-with-c-net
HttpWReq.Connection = "Open"
HttpWReq.ContentLength = B1.Length
Dim newStream As IO.Stream = HttpWReq.GetRequestStream()
'this method closes stream before calling getResponse
Using newStream
newStream.Write(B1, 0, B1.Length)
End Using
'retrieve results of query, which will be in JSon
Dim HttpWResp As System.Net.HttpWebResponse = CType(HttpWReq.GetResponse(), System.Net.HttpWebResponse)
HttpWReq.KeepAlive = False
HttpWReq.Timeout = 15000000
Dim E As System.Text.Encoding = System.Text.Encoding.GetEncoding(HttpWResp.CharacterSet)
Dim SR As IO.StreamReader = New IO.StreamReader(HttpWResp.GetResponseStream, encoding:=E)
S = SR.ReadToEnd 'JSon result
Return JSonToDV(S)
End Function
Documentation for v2.3.0 indicates the need for a different conf file setting, but this is not working. The documentation is at http://neo4j.com/docs/2.3.0-M01/server-configuration.html . The neo4j-server.properties file originally had no entry for org.neo4j.server.database.location=data/graph.db. Adding the suggested line (org.neo4j.server.database.location="C:/Data/Neo4j/UMLS/graph.db") and then the database failed to start. Would appreciate suggested solutions.
The problem was not with Neo4j 2.3.0 but with the VB.NET code. The corrected code, which works is:
Public Shared Function DBQuery(URI As String, PostString As String, method As EnumLib.WebServiceMethod) As DataView
'Used for individual API calls; see BulkUpload for other method
'Uses POST method to access Neo4j Server API
Dim ID As Long = 0
Dim HttpWReq As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create(URI)
Select Case method
Case EnumLib.WebServiceMethod.POST
HttpWReq.Method = "POST"
Case EnumLib.WebServiceMethod.GET
HttpWReq.Method = "GET"
End Select
HttpWReq.ContentType = "application/json"
HttpWReq.Accept = "application/json"
Dim B1() As Byte = System.Text.Encoding.UTF8.GetBytes(PostString, 0, Len(PostString))
'http://blog.micic.ch/net/using-neo4j-graph-db-with-c-net
HttpWReq.Connection = "Open"
Dim S As String = ""
Try
HttpWReq.ContentLength = B1.Length
Dim newStream As IO.Stream = HttpWReq.GetRequestStream()
'this method closes stream before calling getResponse
Using newStream
newStream.Write(B1, 0, B1.Length)
End Using
Dim HttpWResp As System.Net.HttpWebResponse = CType(HttpWReq.GetResponse(), System.Net.HttpWebResponse)
Dim E As System.Text.Encoding = System.Text.Encoding.GetEncoding(HttpWResp.CharacterSet)
Dim SR As IO.StreamReader = New IO.StreamReader(HttpWResp.GetResponseStream, encoding:=E)
S = SR.ReadToEnd
Catch ex As System.Net.WebException
MsgBox("Message: " & vbLf & ex.Message)
Dim RS As IO.StreamReader = New IO.StreamReader(ex.Response.GetResponseStream)
Dim SS As String = RS.ReadToEnd
PostReturnString = "WebException Error: " & ex.Message & vbLf & vbLf & ex.Status & vbLf & vbLf & SS
' MsgBox("Status: " & vbLf & ex.Status & vbLf & vbLf & SS)
End Try
Return JSonToDV(S)
End Function

Prestashop - Unable to upload a new image product with the prestashop 1.6 webservice

I'm trying to upload a new image for a product with the prestashop webservice through a vb .net application, but I get the following error message:
"Unable to save this image".
The URL used to upload the image is this: http://localhost/prestashop/api/images/products/1
And the source code of the function that make the request is this:
Public Sub executeAddImage(ByVal resource As String, ByVal id As String, ByVal imageToAdd As Image)
Dim response As String = Nothing
Try
Dim ms As New MemoryStream()
imageToAdd.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg)
Dim byteArray As Byte() = ms.ToArray()
Dim requestUrl As String = Me.WebServiceURL & "/" & resource & "/" & id
MsgBox(requestUrl)
Dim webRequest As HttpWebRequest = DirectCast(System.Net.WebRequest.Create(requestUrl), HttpWebRequest)
webRequest.Method = WebServicePrestashop.CRUDMethod.Create
'webRequest.ContentType = "image/jpeg"
webRequest.ContentType = "application/x-www-form-urlencoded"
webRequest.Credentials = New NetworkCredential(Me.LoginName, WebServicePrestashop._password)
webRequest.ContentLength = byteArray.Length
MsgBox(byteArray.Length)
' Get the request stream
Using dataStream As Stream = webRequest.GetRequestStream()
dataStream.Write(byteArray, 0, byteArray.Length)
End Using
' Get the response
Using webResponse As HttpWebResponse = DirectCast(webRequest.GetResponse(), HttpWebResponse)
If webResponse.StatusCode = HttpStatusCode.OK Then
Using reader As New StreamReader(webResponse.GetResponseStream(), Encoding.UTF8)
Dim imageNew As Image = Image.FromStream(webResponse.GetResponseStream())
End Using
End If
End Using
Catch ex As WebException
MsgBox(ex.Message.ToString())
Dim reader As New StreamReader(ex.Response.GetResponseStream)
MsgBox(reader.ReadToEnd)
End Try
End Sub
I'm using the HTTP POST method, and the POST content is the bynary content of the new image.
How can I fix it?.
Here the solution.
I think the key is that I must write the body of the webrequest programatically adding to the stream of the webrequest the boundary (in binary array format), the Content-Type chain (in binary array format) and the content of the image to upload (in binary array format).
Public Sub executeAddImage(ByVal resource As String, ByVal id As String, ByVal imageToAdd As Byte())
Dim response As String = Nothing
Try
Dim requestUrl As String = "urlShop" & "/api/" & resource & "/" & id
MsgBox(requestUrl)
Dim webRequest As HttpWebRequest = DirectCast(System.Net.WebRequest.Create(requestUrl), HttpWebRequest)
webRequest.KeepAlive = True
webRequest.Credentials = New NetworkCredential(Me.LoginName, WebServicePrestashop._password)
webRequest.ContentLength = imageToAdd.Length
webRequest.Method = "POST"
webRequest.ContentType = "image/jpeg"
Dim boundary As String = "----" & DateTime.Now.Ticks.ToString("x", CultureInfo.InvariantCulture)
webRequest.ContentType = "multipart/form-data; boundary=" & boundary
Dim beginPostData = "--" & boundary & vbCrLf & "Content-Disposition: form-data; name=""image""; filename=""torrente.jpg""" & _
vbCrLf & "Content-Type: image/jpeg" & vbCrLf & vbCrLf
Dim boundaryBytes = System.Text.Encoding.ASCII.GetBytes(vbCrLf & "--" & boundary & "--" & vbCrLf)
Dim beginPostDataBytes = System.Text.Encoding.ASCII.GetBytes(beginPostData)
webRequest.ContentLength = beginPostData.Length + imageToAdd.Length + boundaryBytes.Length
' Get the request stream
Using dataStream As Stream = webRequest.GetRequestStream()
dataStream.Write(beginPostDataBytes, 0, beginPostDataBytes.Length)
dataStream.Write(imageToAdd, 0, imageToAdd.Length)
dataStream.Write(boundaryBytes, 0, boundaryBytes.Length)
End Using
' Get the response
Using webResponse As HttpWebResponse = DirectCast(webRequest.GetResponse(), HttpWebResponse)
If webResponse.StatusCode = HttpStatusCode.OK Then
Using reader As New StreamReader(webResponse.GetResponseStream())
response = reader.ReadToEnd()
MsgBox(response)
End Using
End If
End Using
Catch ex As WebException
MsgBox(ex.Message.ToString())
Dim reader As New StreamReader(ex.Response.GetResponseStream)
MsgBox(reader.ReadToEnd)
End Try
End Sub

Closure Compiler Service API

Trying to intergrate the closure compiler service into one of my applications and having some issues.
Error being returned is "(413) Request Entity Too Large." Sounds reasonable but I know for a fact the service accepts files larger then the one I am sending it.
Private _HttpWebRequest As HttpWebRequest
Private _Result As StringBuilder
Private Const ClosureWebServiceURL As String = "http://closure-compiler.appspot.com/compile?output_format=xml&output_info=compiled_code" &
"&output_info=warnings" &
"&output_info=errors" &
"&output_info=statistics" &
"&compilation_level=ADVANCED_OPTIMIZATIONS" &
"&warning_level=default" &
"&js_code={0}"
_Result = New StringBuilder
_HttpWebRequest = DirectCast(WebRequest.Create(String.Format(ClosureWebServiceURL, HttpUtility.UrlEncode(_Script))), HttpWebRequest)
_HttpWebRequest.Method = "POST"
_HttpWebRequest.ContentType = "application/x-www-form-urlencoded"
_HttpWebRequest.ContentLength = 0
Dim response As WebResponse = _HttpWebRequest.GetResponse()
Using responseStream As Stream = response.GetResponseStream
Dim encoding As Encoding = System.Text.Encoding.GetEncoding("utf-8")
Using readStream As New StreamReader(responseStream, encoding)
Dim read(256) As Char
Dim count As Integer = readStream.Read(read, 0, 256)
While count > 0
Dim str As New String(read, 0, count)
_Result.Append(str)
count = readStream.Read(read, 0, 256)
End While
End Using
End Using
Any ideas?
Move your request data over to the POST's RequestStream instead of using the querystring.
Private _HttpWebRequest As HttpWebRequest
Private _Result As StringBuilder
Private Const ClosureWebServiceURL As String = "http://closure-compiler.appspot.com/compile?"
Private Const ClosureWebServicePOSTData As String = "output_format=xml&output_info=compiled_code" &
"&output_info=warnings" &
"&output_info=errors" &
"&output_info=statistics" &
"&compilation_level=ADVANCED_OPTIMIZATIONS" &
"&warning_level=default" &
"&js_code={0}"
'//Build's a large javascript for testing
Dim _Script As String = ""
For I = 1 To 100
_Script &= "function hello_" & I & "(name) { alert('Hello, ' + name);}hello('New user');"
Next
'//Create the POST data
Dim Data = String.Format(ClosureWebServicePOSTData, HttpUtility.UrlEncode(_Script))
_Result = New StringBuilder
_HttpWebRequest = DirectCast(WebRequest.Create(ClosureWebServiceURL), HttpWebRequest)
_HttpWebRequest.Method = "POST"
_HttpWebRequest.ContentType = "application/x-www-form-urlencoded"
'//Set the content length to the length of the data. This might need to change if you're using characters that take more than 256 bytes
_HttpWebRequest.ContentLength = Data.Length
'//Write the request stream
Using SW As New StreamWriter(_HttpWebRequest.GetRequestStream())
SW.Write(Data)
End Using
Dim response As WebResponse = _HttpWebRequest.GetResponse()
Using responseStream As Stream = response.GetResponseStream
Dim encoding As Encoding = System.Text.Encoding.GetEncoding("utf-8")
Using readStream As New StreamReader(responseStream, encoding)
Dim read(256) As Char
Dim count As Integer = readStream.Read(read, 0, 256)
While count > 0
Dim str As New String(read, 0, count)
_Result.Append(str)
count = readStream.Read(read, 0, 256)
End While
End Using
End Using
Trace.WriteLine(_Result)

tcpclient vs httpwebrequest

I used a tcpclient to make a connection to a streaming API and for some reason it doesn't work with a 301 error, (something wrong with my credentials). However when I use a httpwebrequest to the same API and use the same credentials and that works. I am trying to figure out what I am doing wrong:
TCPclient connection:
Try
Dim bufferread(defaultSize) As Byte
url = "xxxxxxxxx.com"
Dim tclient As TcpClient = New TcpClient(url, "80")
' use a network stream to download the tcpClient stream
nstream = tclient.GetStream()
' check if we can write to the stream to add the relevant headers and credentials
If nstream.CanWrite Then
Dim headers As String
headers = "GET " & addedUrl & " HTTP/1.0" & Chr(13) & "" & Chr(10)
headers &= "Authorization: Basic " & userNamePassword & Chr(13) & "" & Chr(10)
headers &= Chr(13) & "" & Chr(10)
Dim sendBytes As [Byte]() = Encoding.UTF8.GetBytes(headers)
nstream.Write(sendBytes, 0, sendBytes.Length)
If nstream.CanRead Then
Dim timestamp As DateTime = DateTime.Now
Dim data As String
numbytesRead = 0
' start reading from the stream
Do....
httpwebrequest:
While Not responseData = Nothing
Try
' setup the webrequest and headers to send
url = "https://xxxxxxxxxxxx.com" & addedUrl
If Not parsingTools.refreshDate = Nothing Then
url = parsingTools.refreshDate
End If
Dim poststring As String = ""
webrequest = TryCast(System.Net.WebRequest.Create(url), HttpWebRequest)
webrequest.Method = "GET"
webrequest.UserAgent = "xxxxxxxxxx"
webrequest.Referer = "xxxxxxxxxxxxx"
webrequest.Timeout = 20000
webrequest.KeepAlive = True
webrequest.Credentials = New System.Net.NetworkCredential ("xxxxxxxxxxxxx", "yyyyyyyyyyyyyy")
'get the responsestream
responseStream = webrequest.GetResponse().GetResponseStream()
'check if stream is readable
If responseStream.CanRead Then
HTTP 301 is not an error, it's a redirect. HttpWebRequest can handle redirects transparently but if you are doing all the HTTP implementation yourself with TcpClient then you need to parse and follow the redirect manually.