Add json object into http request as body in vb.net - json

I've one API in vb.net and i want to make HTTP request to another API from one of my methods. I've created an instance of WebClient class and added my headers but the problem is i could not add my json object as body into HTTP request. Here is my code.
Dim webc As New WebClient
webc.Headers.Add("Content-Type: application/json")
webc.Headers.Add("Authorization: " + testHeader)
webc.Headers("x-iyzi-rnd") = random_string
Dim url = "https://sandbox-api.iyzipay.com/"
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
Dim html As Byte() = webc.DownloadData(url)
Dim utf As UTF8Encoding = New UTF8Encoding()
Dim response As String = utf.GetString(html)

Related

Vb.Net Get Resposnes form called API using WebClient

Currently, I am developing a web service which going to be called post JSON. It works fine and I got my records posted without any issue.
My issue is to display the response. I used UploadData to send .. Do I need to use download data to receive? What if I need to show in the response in MessageBox.
Note that I am expecting a response in JSON format as well. Let me know at least the concept ? First I guess, I need to receive the response and I will deserialize it.
Here is my current code. Working fine but I can't show the response.
Public Function postData(ByVal JsonBody As String) As Boolean
Dim webClient As New WebClient()
Dim resByte As Byte()
Dim resString As String
Dim reqString() As Byte
Try
Dim APIusername As String = "XXXXX"
Dim APIPassword As String = "XXXXX"
webClient.Headers("content-type") = "application/json"
webClient.Credentials = New System.Net.NetworkCredential(APIusername, APIPassword)
reqString = Encoding.Default.GetBytes(JsonBody)
resByte = webClient.UploadData(Me.urlToPost, "post", reqString)
resString = Encoding.Default.GetString(resByte)
Console.WriteLine(resString)
' Here I need to show the responses
webClient.Dispose()
Return True
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
Return False
End Function
I have used http request instead of web client and it works.

How should this HTTP request for oAuth token be formatted?

In a VB .net environment, I am making the following call, trying to implement the authorize step of an OAuth process to connect to an Accelo API (a time-entry and billing type of app). I'm trying to get an access token:
Dim jsonstring = "{'Content-Type':'Application/x-www-Form-urlencoded',
'authorization':'Basic MDBhM...GbG5oLlZB'}"
Dim data = Encoding.UTF8.GetBytes(jsonstring)
Dim result_post = SendRequest(New Uri("https://ourinfo.api.accelo.com/oauth2/v0/token"), data, "application/json", "POST")
with the function defined as this:
Private Function SendRequest(uri As Uri, jsonDataBytes As Byte(), contentType As String, method As String) As String
Dim req As WebRequest = WebRequest.Create(uri)
req.ContentType = contentType
req.Method = method
req.ContentLength = jsonDataBytes.Length
Dim stream = req.GetRequestStream()
stream.Write(jsonDataBytes, 0, jsonDataBytes.Length)
'stream.Close()
Dim response = req.GetResponse().GetResponseStream()
Dim reader As New StreamReader(response)
Dim res = reader.ReadToEnd()
reader.Close()
response.Close()
Return res
End Function
and I keep receiving an error on this line:
Dim response = req.GetResponse().GetResponseStream()
Saying
"System.Net.WebException: 'The remote server returned an error: (400) Bad Request.'"
It seems to me like a syntax error or something in the way my calling method is formed or the format of the parameters passed. I got the HTTP request code suggestion/format from here:
How to POST a JSON to a specific url using VB.NET?
and I'm using the Accelo API to set the content-type and authorization "basic" part where the string is encoded in Base 64. This is a service application so i'm supposed to be able to get the token in 1-step (no user confirmation is required). I already have a "token" from when I registered, but the API still indicates I should do this code. i'm following this:
https://api.accelo.com/docs/?_ga=2.218971609.1390377756.1568376911-2053161277.1565440093#service-applications
Can anyone tell me what exactly I'm doing wrong here? I'm confused and this is the first time I'm trying to implement OAuth.
There is some example code in the API documentation that looks like this:
POST /oauth2/v0/token HTTP/1.1
Host: planet-express.api.accelo.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic {client_credentials}
grant_type=client_credentials
scope=read(staff)
And I'm not sure the difference between the = and : syntax purposes. I was not able to search and find any answers to whether I'm calling everything correctly. Should I be passing the scope and grant_type in the JSON string, or setting it as a property on "req" object in the "SendRequest" function? I know that the grant_type is supposedly required but how do I set it?
What's the token I received initially when I registered, if I'm supposed to get a token this way?
I got it working with the help of a colleague. Apparently I was confusing header data and the json "data,"and I was not formatting the data correctly either. I should have been looking at the WebResponse too, not only the WebRequest. I changed my code to the following, which works now:
Sub SendRequestGetAccess()
Dim req As WebRequest = WebRequest.Create(uri)
req.Method = "POST"
req.Headers.Add("Authorization", "Basic " & "MDB....")
req.ContentType = "Application/x-www-Form-urlencoded"
req.ContentLength = jsonDataBytes.Length
Dim stream = req.GetRequestStream()
stream.Write(jsonDataBytes, 0, jsonDataBytes.Length)
stream.Close()
Dim response As WebResponse = req.GetResponse()
Console.WriteLine((CType(response, HttpWebResponse)).StatusDescription)
Dim dataStream = response.GetResponseStream()
Dim reader As StreamReader = New StreamReader(dataStream)
Dim responseFromServer As String = reader.ReadToEnd()
Console.WriteLine(responseFromServer)
reader.Close()
dataStream.Close()
response.Close()
'Dim firstItem = jsonResult.Item("data").Item(0).Value(Of String)("token")
Dim j As Object = New JavaScriptSerializer().Deserialize(Of Object)(responseFromServer)
Dim _itemvalue = j("itemkey")
End Sub
And I had to use dashes instead of colons in my json data:
Dim jsonstring = "grant=creds" & "&scope=read"
Dim data = Encoding.UTF8.GetBytes(jsonstring)
SendRequestGetAccess(New Uri("https...site.com/oauth2/v0/token"), data)

500 Internal Error when sending a POST request to Api

So my goal is to send a HttpRequest to api, it returns a 500 internal server error.
According to them, other companies are succesfully using this Api, so it should work in theory. I send the json example string I use to test if it works, they confirmed it is correct. So what could cause the Error?
Public Function SendStringToHttpServer(dataString As String, uriString As String, credentials As NetworkCredential) As String
Dim resultInfo As String
Dim request As HttpWebRequest = CType(WebRequest.Create(uriString), HttpWebRequest)
request.Credentials = credentials
request.Timeout = 6000
request.Method = "POST"
Dim byteArray As Byte() = Encoding.UTF8.GetBytes(dataString)
request.ContentType = "application/json"
request.ContentLength = byteArray.Length
Try
Dim dataStream As Stream = request.GetRequestStream()
dataStream.Write(byteArray, 0, byteArray.Length)
dataStream.Close()
Dim response As HttpWebResponse = CType(request.GetResponse(), HttpWebResponse)
dataStream = response.GetResponseStream()
Dim reader As New StreamReader(dataStream)
Dim responseFromServer As String = reader.ReadToEnd()
reader.Close()
response.Close()
Catch ex As Exception
Debug.WriteLine(ex.Message)
End Try
Return "done"
End Function
Note: I saw there are some similiar threads, like this. But I use it exactly the same way, so it SHOULD work but doesn't -.-
(Beside the fact that i have strict on and therefore cast explicitly)
EDIT: About the authentification methods: This works definitly, since if I use wrong username or password in the credenitals I get a 403: authorized Error and not a 500.
Furthermore the read request works just fine. Read request is very similiar just a basic HttpRequest which only requires the url and credentials.
EDIT 2: So I read that it can be tied to HttpRequest automaticlly adding and "Expect:100-continue" to the header.I prevent this now
ServicePointManager.Expect100Continue = False
But it still gives a 500 Error.

Parsing html table containing images to datatable attribute

i used the following code to parse html table inner text to datatable (using Html-Agility-Pack):
Imports System.Net
Public Sub ParseHtmlTable(byval HtmlFilePath as String)
Dim webStream As Stream
Dim webResponse = ""
Dim req As FileWebRequest
Dim res As FileWebResponse
' REQUEST PAGE (We are requesting Google Finance Page with NSE:RENUKA Stock Info
req = WebRequest.Create("file:///" & HtmlFilePath)
req.Method = "GET" ' Method of sending HTTP Request(GET/POST)
res = req.GetResponse ' Send Request
webStream = res.GetResponseStream() ' Get Response
Dim webStreamReader As New StreamReader(webStream)
Dim htmldoc As New HtmlAgilityPack.HtmlDocument
htmldoc.LoadHtml(webStreamReader.ReadToEnd())
Dim nodes As HtmlAgilityPack.HtmlNodeCollection = htmldoc.DocumentNode.SelectNodes("//table/tbody/tr")
Dim dtTable As New DataTable("Table1")
Dim Headers As List(Of String) = nodes(0).Elements("th").Select(Function(x) x.InnerText.Trim).ToList
For Each Hr In Headers
dtTable.Columns.Add(Hr)
Next
For Each node As HtmlAgilityPack.HtmlNode In nodes
Dim Row = node.Elements("td").Select(Function(x) x.InnerText.Trim).ToArray
dtTable.Rows.Add(Row)
Next
dtTable.WriteXml("G:\1.xml", XmlWriteMode.WriteSchema)
End Sub
How to parse an html table containing images to a Datatable and saving images as binary or saving their links using VB.net
I found the answer finally. images look like:
<img src="img.jpg"/>
We can use
.SelectNodes("./img").Attributes("src").Value()
To return the image path on the node containing it

Curl command to html or vb.net

I am trying to access the smartsheet API. They have a sample code provided in curl to access it.
To access your Sheet list, construct an HTTPS request using your favorite programming or scripting language. Here is an example using the curl from a linux command line:
curl https://api.smartsheet.com/1.0/sheets \
-H "Authorization: Bearer 0da6cf0d-848c-4266-9b47-cd32a6151b1f" \
-H "Assume-User: john.doe%40smartsheet.com"
How do I do that in vb.net or from a html form?
This is a rather large subject but at it's most simple you could try this...
Imports System.Net
and then...
Dim wHeader As WebHeaderCollection = New WebHeaderCollection()
wHeader.Clear()
wHeader.Add("Authorization: Bearer 0da6cf0d-848c-4266-9b47-cd32a6151b1f")
wHeader.Add("Assume-User: john.doe%40smartsheet.com")
Dim sUrl As String = "https://api.smartsheet.com/1.0/sheets"
Dim wRequest As HttpWebRequest = DirectCast(System.Net.HttpWebRequest.Create(sUrl), HttpWebRequest)
'wRequest.ContentType = "application/json" ' I don't know what your content type is
wRequest.Headers = wHeader
wRequest.Method = "GET"
Dim wResponse As HttpWebResponse = DirectCast(wRequest.GetResponse(), HttpWebResponse)
Dim sResponse As String = ""
Using srRead As New StreamReader(wResponse.GetResponseStream())
sResponse = srRead.ReadToEnd()
End Using
I'm unfamiliar with the smartsheet API but you can use this as a start point.
If you are using a Proxy you will need to add...
Dim wProxy As IWebProxy = WebRequest.GetSystemWebProxy()
wProxy.Credentials = System.Net.CredentialCache.DefaultCredentials
and specify the proxy when you make the request...
wRequest.Proxy = wProxy
To create a web request in VB.Net, you can use the HttpWebRequest class.
The -H argument in curl creates an extra header. To add headers to a HttpWebRequest you simply add them to the WebHeaderCollection Headers.
Example:
Dim myHttpWebRequest = CType(WebRequest.Create("https://api.smartsheet.com/1.0/sheets"), HttpWebRequest)
myHttpWebRequest.Headers.Add("Authorization: Bearer 0da6cf0d-848c-4266-9b47-cd32a6151b1f")
myHttpWebRequest.Headers.Add("Assume-User: john.doe%40smartsheet.com")
Dim myHttpWebResponse = CType(myHttpWebRequest.GetResponse(), HttpWebResponse)
use the example and it worked perfectly for me, some changes. I leave you the example.
Dim wHeader As WebHeaderCollection = New WebHeaderCollection()
wHeader.Clear()
wHeader.Add("Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9")
wHeader.Add("Assume-User: g.n.moran%gmail.com")
Dim wRequest As HttpWebRequest = DirectCast(System.Net.HttpWebRequest.Create(url), HttpWebRequest)
wRequest.Headers = wHeader
wRequest.Method = "POST"
Dim byteArray As Byte() = Encoding.UTF8.GetBytes(json)
wRequest.ContentType = "application/json"
wRequest.ContentLength = byteArray.Length
Dim dataStream As Stream = wRequest.GetRequestStream()
dataStream.Write(byteArray, 0, byteArray.Length)
dataStream.Close()
dataStream.Dispose()
ServicePointManager.Expect100Continue = False
Dim wResponse As HttpWebResponse = DirectCast(wRequest.GetResponse(), HttpWebResponse)
oerror.Codigo = CType(wResponse, HttpWebResponse).StatusCode
oerror.Descripcion = CType(wResponse, HttpWebResponse).StatusDescription
Dim responseFromServer As String = ""
dataStream = wResponse.GetResponseStream()
Dim reader As New StreamReader(dataStream)
Using srRead As New StreamReader(wResponse.GetResponseStream())
responseFromServer = srRead.ReadToEnd()
End Using