Visual Basic - HTTPClient and API Request Issue - json

Good morning,
As a returning developer (I've been in management for a long time!), I've been tasked with developing a module for our proprietary financial system (Visual Basic/ SQL Server) that will read large .CSV files containing customer information, convert them into JSON format, then submit them to an external party for processing via that company's API.
The conversion part was easy and I'm almost ready to go with it, but I can't establish connectivity to the external API.
There are two parts to the process: -
Submit login details (obfuscated here) {"username": "MadeUpUser","password": "Y66***uYj6%%YY"} and receive a Bearer Token from the API
Submit JSON format customer info to API endpoint, using Bearer Token, receive confirmation
I've submitted both the login creds and my JSON-format data to the API via Postman and it works perfectly, however, when I try to login via my VB app using the HTTPClient class, I'm getting the follow exception (copied from the Exception class properties) :
**HResult = -2146233088
StackTrace = " at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context)" & vbCrLf & " at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar)"
InnerException = {"The request was aborted: Could not create SSL/TLS secure channel."}**
It's clearly something I'm doing wrong programmatically or something I'm not doing and any help or advice offered will be greatly appreciated.
The code: (AddLogEntry() is a Sub I created to log events to a text file)
Private Async Function PostAsync(ByVal JSONString As String, EndPoint As String) As Task
Dim APIuri As New Uri(EndPoint)
Try
With ZincClient
.BaseAddress = APIuri
.DefaultRequestHeaders.Accept.Clear()
.DefaultRequestHeaders.Accept.Add(New Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"))
End With
Dim content As New Net.Http.StringContent(JSONString, System.Text.Encoding.UTF8, "application/json")
Dim response As Net.Http.HttpResponseMessage = Await ZincClient.PostAsync(APIuri, content)
Dim result As String = Await response.Content.ReadAsStringAsync()
Catch ex As Exception
AddLogEntry("ERROR! - " & ex.Message)
End Try
Return
End Function

Related

Request to send json with token returns token validation error

When sending the request as a JSON, I get the error "Can't check the token validity." Previously, I obtained the token, which is stored in a variable. The statusCode: OK {200}.
What I observe with the error that is displayed is that the json cannot be sent because the token is not being validated. However, if I do the tests in Postman with the token and the JSON, the result is correct. I am using the RestSharp/106.15.0.0 library, which is the same one with which I obtained the token.
I have tried adding other lines of code, like
request2.AddBody(MyJson)
request2.AddHeader("Cache-Control", "no-cache")
I have carried out the tests in postman which are satisfactory
The code in VB.NET 2015 that I have developed is the following:
Dim client = New RestClient(Var_URLWS)
Dim request2 = New RestRequest(Method.POST)
request2.AddHeader("Content-Type", "application/json")
request2.AddHeader("Authorization", "Mybearer " & MyToken)
request2.AddJsonBody(MyJson, "application/json")
Dim response2 As RestResponse = client.Execute(request2)

HTTP-GET via SSIS

I have some ethernet device which collect data and it's possible to download it via data export interface: HTTP-GET query returns the data in [Content-Type: text/plain Charset: utf-8]
I saw this: How to make an HTTP request from SSIS? - it rather doesn't work for me (C# is a little Chinese for me) and it's about how to fetch this data to variable into SSIS
In your SSIS package add a C# Script Task
Edit the Script Task
At the top with the other using statements add using System.Net;
in Main use the following code snippet to make a GET request (Note: Change "https://somewhere.com/contacts/get" to your actual endpoint.)
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://somewhere.com/contacts/get");
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
using(HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using(Stream stream = response.GetResponseStream())
using(StreamReader reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}

Apache HTTP Client Fluent

Hi I want to use Apache HTTP Client Fluent to create a request to download a file. I need to add Autorization Basic Auth to the request to pass in a username and password which I can't find a good example of how to do.
I can see a addHeader method but can't find good examples of how to construct it. Thanks!
So far the code i have is:
String auth = username + ":"+ token
byte[] encodedBytes = Base64.encodeBase64(auth.getBytes());
String encodedAuth = new String(encodedBytes)
URL downloadFileURL = new URL (urlbuild)
Executor executor = Executor.newInstance();
executor.execute(Request.Get(downloadFileURL.toURI())
.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + encodedAuth )
.connectTimeout(1000))
.saveContent(new File(mobileAppPath + System.getProperty("file.separator") + mobileApp.name));
the problem was due to Java trying to validate the SSL certificate i used Java code below to trust all hosts before executing the request.
https://www.javatips.net/api/java.security.cert.x509certificate

How do I get the body from an HttpWebResponse using Visual Basic (VS2017)

I am having a hell of a time with this project I am working on and could really use your help. I'll try to keep this as concise as possible.
Basically, I have a UI setup that collects user information and sends REST API calls to my call control system. Currently it is working in regards to adding lines, trunks etc.
The problem is I want to see the body of the response coming back from the server. If I have the exception handling look for an OK status code and turn an indicator green, it performs as I have asked.
But I cannot get it to give me the full body of the response like it does when I send the call in POSTMAN.
Here is the response I get back in POSTMAN and would like to get back when I make the API call in VB. I get a Status Code 400 with this in the body.
{
"hint": "The specified Pattern (2952) is already in use by the line owner.",
"details": "Conflicting Pattern",
"code": "P0001",
"message": "invalid_parameter" }
I have tried every combination of search criteria I could find on this site and nothing seems to be working for me. I just don't know what I am doing wrong. Here is a sample of how the request/response is set up now.
Try
'//Setup HTTP connection and modify headers
Dim APIRequest As HttpWebRequest = HttpWebRequest.Create("https://" & CMIP.Text & "/api/v1/" & Custom_Endpoint_URL.Text)
APIRequest.Method = "POST"
APIRequest.Headers.Add("Authorization", "Bearer " + LatestToken.Text)
APIRequest.ContentType = "application/json"
'WebCall.Headers.Add("Prefer", "return=representation") 'Only used for testing purposes
'//Prepare JSON request
Dim bytearray As Byte() = System.Text.Encoding.UTF8.GetBytes(Custom_Body.Text)
APIRequest.ContentLength = bytearray.Length
'//Bypass self-signed cert issue
ServicePointManager.ServerCertificateValidationCallback = AddressOf AcceptAllCertifications
'//Load JSON payload into datastream
Dim datastream As Stream = APIRequest.GetRequestStream()
datastream.Write(bytearray, 0, bytearray.Length)
''//Response
Dim response As WebResponse = APIRequest.GetResponse
Dim responsestream As Stream = response.GetResponseStream
Dim responsereader As New StreamReader(responsestream)
Dim responsereadstring As String = responsereader.ReadToEnd
'//Send response to results window
Response_Box.Text = responsereadstring
Catch ex As WebException
End Try
I wanted to figure this out on my own but I have been at this for a few days now and I'm at the point I am banging my head against the wall.
The HttpWebRequest.GetResponse method throws a WebException when the response has a status code in the 4xx or 5xx range. Based on the information in your question, your API call is returning a status code of 400, so that would trigger the exception. Your Catch block is completely empty, so you are silently ignoring this case. (That is why you should never leave your Catch blocks empty-- you'll never know that something is failing.)
It turns out that the WebException class has a Response property on it (as well as Status), so you can get the data from there. You just need to fill in the Catch block:
Catch ex As WebException
Dim responsestream As Stream = ex.Response.GetResponseStream
Dim responsereader As New StreamReader(responsestream)
Dim responsereadstring As String = responsereader.ReadToEnd
Response_Box.Text = responsereadstring
End Try

WinRT use HttpClient to call Web API based URL with token

We are building a WinRT app which gets data from server which is Web API based & so it gives data in json and/or XML format.
When app user logs in for the first time using his credentials(username,password), the response that comes from server is a success bit & a TOKEN, which should be used in successive URL requests.
I am using httpclient for sending requests
using (HttpClient httpClient1 = new HttpClient())
{
string url = "http://example.com/abc/api/process1/GetLatestdata/10962f61-4865-4e7a-a121-3fdd968824b5?employeeid=6";
//The string 10962f61-4865-4e7a-a121-3fdd968824b5 is the token sent by the server
var response = await httpClient1.GetAsync(new Uri(url));
string content = await response.Content.ReadAsStringAsync();
}
Now the response that i get is with status code 401 "unauthorised".
And the xml i get in response is "Unauthorised User".
Is there anything i need to change in appManifest??
I've checked this, but cant we use httpclient without credentials??
Your Capabilities are enough. You don't even need Internet (Client) because it's included in Internet (Client & Server).
You do not have credentials for WinRT HttpClient, in your linked post they referr to System.Net.Http.HttpClientHandler.
Maybe you can use the HttpBaseProtocolFilter to add the credentials?
using (var httpFilter = new HttpBaseProtocolFilter())
{
using (var httpClient = new HttpClient(httpFilter))
{
httpFilter.ServerCredential...
}
}
I don't know your security mechanism, I'm using a HttpClient and my session-key is in a cookie. But I think your client code looks fine.