Setting multiple headers within httpclient on vb.net - vb.net

I am working on sending data to Spiff (https://app.getguru.com/card/iXpEBagT/How-to-send-data-to-Spiffs-API) but I'm having trouble getting the headers they want added. From the linked site here is their example:
curl -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -H 'Signature: t=1606767397,v1=DIGEST' -d '{"Id":"Thor","nickname":"Strongest Avenger"}' https://app.spiff.com/_webhook/mapping/123
So using VB.Net (Core 6) I'm attempting to do this with a HttpClient but keep getting a Status Code 400: Bad Response. Here is my sample code:
Public Async Function SendRequest(uri As Uri, data As String, signature As String) As Task(Of JsonObject)
Dim httpClient = New HttpClient()
httpClient.DefaultRequestHeaders.Accept.Add(New MediaTypeWithQualityHeaderValue("application/json"))
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Signature", signature)
Dim content = New StringContent(data, Encoding.UTF8, "application/json")
Dim response = New HttpResponseMessage
response = Await httpClient.PutAsync(uri, content)
response.EnsureSuccessStatusCode()
End Function
I'm guessing the BadRequest is due to the extra Signature header but I can't figure out what I'm doing wrong. I'm using the default request headers since the program executes, sends the data, then ends so I have no need to keep the httpclient around or reuse it. I tried using a WebRequest but on top of being depreciated I had the same issues. I thought maybe I'm messing up the signature as they use HMAC verification but I'm pretty sure that is correct also based on their documentation:
Private Sub SendDataButton_Click(sender As Object, e As EventArgs) Handles SendDataButton.Click
Dim myKey As String = HMACKeyTextBox.Text
Dim myUnixTime As Long = New DateTimeOffset(Date.Now.ToUniversalTime).ToUnixTimeSeconds
Dim myData as String = "{""PrimaryKey"":""2""}"
Dim myPreDigestString = $"{myUnixTime}.{myData}"
Dim myDigest As String = GetHMACSHA256Hash(myPreDigestString, myKey)
Dim myURI As New Uri(URITextBox.Text)
Dim mySignature As String = $"t={myUnixTime},v1={myDigest}"
Dim result_post = SendRequest(myURI, myData, mySignature)
End Sub
Which is based on some other posts on here. Am I adding the headers wrong or does this look correct? The test data is what they are expecting from me for testing, a single record setting a PrimaryKey. I should be getting back a 200 OK.

Related

How to create Http request with header and body format x-www-form-urlencoded and get the cookies value in vb.NET

I'm trying to make an http request with the following attributes
Header - contains a key 'Referer' with a set value
Body format is x-www-form-urlencoded
Body contains multiple keyes 'type', 'encpwd', 'user', 'pwd' & 'admsid'
In the response from the request, I need to obtain values in the cookies. I'm able to do it via Postman get the cookies, however I need to write a function/method to achieve this and return the cookies values which will be required to authenticate in future API calls.
From the internet, I found a sample code as below
Dim client As RestSharp.RestClient = New RestSharp.RestClient(inEndpoint)
client.Timeout = 10000
client.CookieContainer = New System.Net.CookieContainer
Dim request As RestSharp.RestRequest = New RestRequest(RestSharp.Method.Post)
request.AddHeader("Referer", strReferer)
Dim response As IRestResponse = client.Execute(request)
responsecode=response.StatusCode
responsecontent=response.Content
Dim cookies =client.CookieContainer.GetCookieHeader(response.ResponseUri)
cookiecontainer=cookies.ToString
Console.WriteLine("cookieJar "+ cookies.ToString)
Console.WriteLine("response Uri "+response.ResponseUri.ToString)
But when I'm trying this code in Visual Studio (I have installed RestSharp package already), I'm getting lots of error as below:
client.Timeout = 10000 -- Timeout is not a member of RestClient
client.CookieContainer = New System.Net.CookieContainer -- Property 'CookieContainer' is 'Read-Only'
Dim request As RestSharp.RestRequest = New RestRequest(RestSharp.Method.Post) -- Type 'RestRequest' is not defined
request.AddHeader("Referer", strReferer) -- 'AddHeader' is not a member of 'RestRequest'
Dim response As IRestResponse = client.Execute(request) -- Type 'IRestResponse' is not defined
I'm quite new to https request, please help me where I'm making mistake. Also I don't know/find how to add the body parameters with x-www-form-urlencoded format, everywhere it's mentioned in JSON, but this API service only accepts this format for Body.
Thanks for the help in advance.
I've tried the below code
Dim client As RestClient = New RestClient(endPoint)
Dim request As RestRequest = New RestRequest(Method.Post)
request.AddHeader("Referer", strReferer)
request.AddParameter("application/x-www-form-urlencoded", "type=" + strType + "&encpwd= " + strEncPwd + "&user=" + strUser + "&pwd=" + strPwd + "&admsid=" + stradmsID, ParameterType.RequestBody)
Dim response = client.Execute(request)
It generates exception "cannot send a content-body with this verb-type."
Please help
The below code ran successfully.
Dim client = New RestClient(endPoint)
Dim request = New RestRequest()
request.Method = Method.Post
request.AddHeader("Referer", strReferer)
request.AddHeader("Content-Type", "application/x-www-form-urlencoded")
request.AddParameter("type", strType)
request.AddParameter("encpwd", strEncPwd)
request.AddParameter("user", strUser)
request.AddParameter("pwd", strPwd)
request.AddParameter("admsid", stradmsID)
Dim response = client.Execute(request)
Dim cookies = client.CookieContainer.GetCookieHeader(response.ResponseUri)
Console.WriteLine("cookieJar " + cookies.ToString)
Console.WriteLine(response.Content)
Hope it will help someone. Thanks

How to convert \ using newtonsoft.json.linq.serializeobject in vb.net httprequest?

I have a JSON object created using Newtonsoft JObject but I get a bad request error when I try to submit it if any of the properties have spaces, slashes, etc.
updatestring = "date=2/14/2019"
Dim jobjattr As New Newtonsoft.Json.Linq.JObject(
New Newtonsoft.Json.Linq.JProperty("description", "test"),
New Newtonsoft.Json.Linq.JProperty("source", updatestring)
)
Dim jobjdat As New Newtonsoft.Json.Linq.JObject(
New Newtonsoft.Json.Linq.JProperty("type", "synch_log"),
New Newtonsoft.Json.Linq.JProperty("id", "6278042e-ed64-0418-a651-5c574dc4f12b"),
New Newtonsoft.Json.Linq.JProperty("attributes", jobjattr)
)
Dim jobj As New Newtonsoft.Json.Linq.JObject(New Newtonsoft.Json.Linq.JProperty("data", jobjdat))
Dim jsonserializersettings As New Newtonsoft.Json.JsonSerializerSettings
jsonserializersettings.StringEscapeHandling = Newtonsoft.Json.StringEscapeHandling.EscapeNonAscii
Dim stringReq = Newtonsoft.Json.JsonConvert.SerializeObject(jobj, jsonserializersettings)
Dim byteData As Byte() = System.Text.Encoding.UTF8.GetBytes(stringReq)
httprequest.ContentLength = byteData.Length
Dim postreqstream As System.IO.Stream = .GetRequestStream()
postreqstream.Write(byteData, 0, byteData.Length)
postreqstream.Close()
incoming jobj = {"data":{"type":"synch_log","id":"6278042e-ed64-0418-a651-5c574dc4f12b","attributes":{"description":"test","source":"date=2/14/2019"}}}
after serialzation byteData still = {"data":{"type":"synch_log","id":"6278042e-ed64-0418-a651-5c574dc4f12b","attributes":{"description":"test","source":"date=2/14/2019"}}}
I would expect the / to be escaped.
any text string works fine
I have also tried jsonserializer settings as Default and EscapeHtml but with the same result.
Other characters cause the same eror. "datetoday" posts correctly but "date=today" and "date today" result in a 400 bad request error
The closest answer I have found is that maybe the object is being double escaped but I can't see how that would be.
Thank you everyone. Brian, you led me in the right direction. I failed to mention that it is an API call to SuiteCRM but your question got me thinking to look on the server side and it turns out there is an unresolved bug with the V8 API. I just assumed it was my code.
github bug report

How to add extra x-signature header with WebClient?

This is my current code.
Public Shared Function downloadString1(url As String, post As String, signature As String) As String
Dim wc = New CookieAwareWebClient
Dim result = wc.UploadString(url, post)
Return result
End Function
I need to insert post, url, and I should add x signature header I think
Now with wc.UploadString, I can do posts. But how do I add that extra x-signature header with WebClient?
This is the API instruction for yobit
https://yobit.net/en/api/

VB.NET POST multiple files and parameters

I need to make a POST request to a server.
this request must have multiple parameters, like this :
name
number
host
and multiples files
file1
file2
file3
How can I do that in VB.NET. I tried WebRequest object, but there's no simple way to do that.
thanks
Use Webclient instead :
For values :
' Create a value collection
Dim myNameValueCollection As New NameValueCollection()
' Set up POST variables
myNameValueCollection.Add("name", someName)
myNameValueCollection.Add("number", someNumber)
...
Using wc As New System.Net.WebClient()
wc.UploadValues(remoteUrl, myNameValueCollection)
End Using
And for files simply :
Using wc As New System.Net.WebClient()
wc.UploadFile(remoteUrl, yourfile)
End Using
I didn't check if it will work, but I would try something like:
' post request with some parameters inside query string
uriPath = String.Format("{0}{1}?func=xxx&uid={2}", url, fileName, id)
reqUri = New Uri(uriPath)
webReq = CType(WebRequest.Create(reqUri), HttpWebRequest)
webReq.Method = "Post"
' webReq.Timeout = 10000
webReq.KeepAlive = False
webReq.ContentType = "application/x-www-form-urlencoded"
' HERE is a place to attach your files
' try to run it at loop for each file
form = "name=" & fileName
webReq.ContentLength = form.Length
Dim sw As New StreamWriter(webReq.GetRequestStream, System.Text.Encoding.ASCII)
sw.Write(form)
' here write/send the file content
sw.Flush()
sw.Close()
sw.Dispose()
' reading response
Using res As WebResponse = webReq.GetResponse
Dim st As Stream = res.GetResponseStream()
Dim rd As New StreamReader(st)
status = rd.ReadLine()
If I remember well POST request of application/x-www-form-urlencoded type is sent
in form of:
--- params separator
name=fileName
file content
--- params separator
name=fileName1
file1 content

WebClient encoding problems is vb.net

In my vb.net application I am interacting with a webservice written by another group. This interaction involved verifying an account number. The way the other group wrote their webservice is I am supposed to hit a specific url, retrieve a sessionid number and then use that number for subsequent requests. The problem I am having is that when I pass the sessionid it needs to be contained in { } brackets. for example: "http://server/acctverify/Verification.groovy;jsessionid=${123456789}"
The problem lies in when I pass the above URL it gets encoded to something like this:
http://server/acctverify/Verification.groovy;jsessionid=$%7B123456789%7D
with the {}'s replaced.
I don't understand why this is happening nor how to fix it.
Code I am running:
Dim client As WebClient = New WebClient
Dim Sessionuri As Uri = New Uri(VerifyInit)
Dim sessionID As String = client.DownloadString(Sessionuri)
Dim FinalUri As Uri = New Uri(VerifyPost & "{" & sessionID & "}?acctnumber=")
Dim FinalResults As String = client.DownloadString(FinalUri)
MessageBox.Show(FinalResults)
Thanks in advance for any help.
There is a deprecated constructor for the Uri class which will prevent URIs from being encoded when the dontEscape parameter of the constructor is True.
Like this:
Dim client As WebClient = New WebClient
Dim Sessionuri As Uri = New Uri(VerifyInit)
Dim sessionID As String = client.DownloadString(Sessionuri)
Dim FinalUri As Uri = New Uri(VerifyPost & "{" & sessionID & "}?acctnumber=", true)
Dim FinalResults As String = client.DownloadString(FinalUri)
MessageBox.Show(FinalResults)
This constructor is deprecated for good reason: the URI you're trying to create is not a legal URI. The { and } characters must be encoded. But if you're using a non-compliant server that only accepts unencoded characters, the constructor above should work.