POST a Multi-Part Form to Bamboo API
I suspect that at the very least your Content-Length: 520
will be wrong. That content length was only applicable to their example.
Anyway, I haven't written VB.Net in a long, long time, but from a quick test a modified version of this code works against one of my REST services, so it should work in your case, with perhaps some minor tweaking.
My test console project used .Net 4.6.1, but will likely run with some of the earlier .Net Frameworks.
Imports System.IO
Imports System.Net.Http
Module Module1
Sub Main()
Call UploadFileToWebsite(14, "no", "D:\Temp\file.pdf")
Console.WriteLine("Please wait for a response from the server and then press a key to continue.")
Console.ReadKey()
End Sub
Public Sub UploadFileToWebsite(category As Integer, share As String, file As String)
Dim message = New HttpRequestMessage()
Dim content = New MultipartFormDataContent()
content.Add(New StringContent(category.ToString()), "category")
content.Add(New StringContent(share), "share")
Dim filestream = New FileStream(file, FileMode.Open)
Dim fileName = System.IO.Path.GetFileName(file)
content.Add(New StreamContent(filestream), "file", fileName)
message.Method = HttpMethod.Post
message.Content = content
message.RequestUri = New Uri("https://api.bamboohr.com/api/gateway.php/company")
Dim client = New HttpClient()
client.SendAsync(message).ContinueWith(
Sub(task)
'do something with response
If task.Result.IsSuccessStatusCode Then
Console.WriteLine("Uploaded OK.")
Else
Console.WriteLine("Upload Failed.")
End If
End Sub)
End Sub
End Module
On an unrelated note, you can also use vbCrLf
instead of vbCr & vbLf
.
Used the php example on their GitHub and copied it over to VB.NET. It's a little messy, but it works. Here is the relevant code:
Public Function sendRequestMPF(ByVal req As BambooHTTPRequest, ByVal fileLocation As String) As BambooHTTPResponse
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 Or SecurityProtocolType.Ssl3
Dim request As HttpWebRequest = WebRequest.Create(req.url)
request.Method = req.method
request.Host = "api.bamboohr.com"
Dim boundary = "----BambooHR-MultiPart-Mime-Boundary----"
Try
request.ContentType = "multipart/form-data; boundary=" + boundary
request.ContentLength = req.contents.Length
Catch ex As Exception
End Try
Dim iCount As Integer = req.headers.Count
Dim key As String
Dim keyvalue As String
Dim i As Integer
For i = 0 To iCount - 1
key = req.headers.Keys(i)
keyvalue = req.headers(i)
request.Headers.Add(key, keyvalue)
Next
Dim enc As System.Text.UTF8Encoding = New System.Text.UTF8Encoding()
Dim bytes() As Byte = {}
Dim pdfBytes() As Byte = {}
Dim lBytes() As Byte = {}
Dim fBytes() As Byte = {}
Dim s As New MemoryStream()
If (req.contents.Length > 0) Then
bytes = enc.GetBytes(req.contents)
s.Write(bytes, 0, bytes.Length)
pdfBytes = File.ReadAllBytes(fileLocation)
s.Write(pdfBytes, 0, pdfBytes.Length)
Dim postHeader = vbCrLf + vbCrLf + "--" + boundary + "--" + vbCrLf
Dim postHeaderBytes() As Byte = enc.GetBytes(postHeader)
lBytes = enc.GetBytes(postHeader)
s.Write(postHeaderBytes, 0, postHeaderBytes.Length)
fBytes = s.ToArray()
request.ContentLength = fBytes.Length
End If
request.AllowAutoRedirect = False
If Not basicAuthUsername.Equals("") Then
Dim authInfo As String = basicAuthUsername + ":" + basicAuthPassword
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo))
request.Headers("Authorization") = "Basic " + authInfo
End If
If req.contents.Length > 0 Then
Dim outBound As Stream = request.GetRequestStream()
outBound.Write(fBytes, 0, fBytes.Length)
End If
Dim resp As BambooHTTPResponse
Try
Dim webresponse As HttpWebResponse = request.GetResponse()
resp = New BambooHTTPResponse(webresponse)
resp.responseCode = webresponse.StatusCode
resp.headers = webresponse.Headers
Catch e As WebException
Console.WriteLine(e.Message)
If (e.Status = WebExceptionStatus.ProtocolError) Then
resp = New BambooHTTPResponse(DirectCast(e.Response, HttpWebResponse).StatusCode)
Else
resp = New BambooHTTPResponse(0)
End If
End Try
Return resp
End Function
Public Function buildMultiPart(ByVal params As NameValueCollection, ByVal boundary As String, ByVal contentType As String, ByVal name As String, ByVal fileName As String)
Dim data = ""
For Each key In params.AllKeys
data += "--" + boundary + vbCrLf
data += "Content-Disposition: form-data; name=""" + key + """"
data += vbCrLf + vbCrLf
data += params(key) + vbCrLf
Next
data += "--" + boundary + vbCr + vbLf
data += "Content-Disposition: form-data; name=""" + name + """;" + " filename=""" + fileName + """" + vbCrLf
data += "Content-Type: " + contentType + vbCrLf
data += vbCrLf
'data += fileData + vbCrLf + vbCrLf
'data += "--" + boundary + "--" + vbCrLf
Return data
End Function
Public Function uploadEmployeeFile(ByVal employeeId As Integer, ByVal fileName As String, ByVal fileLocation As String)
Dim request As New BambooHTTPRequest()
request.url = String.Format("{0}/v1/employees/{1}/files/", Me.baseUrl, employeeId)
request.method = "POST"
Dim boundary = "----BambooHR-MultiPart-Mime-Boundary----"
Dim params = New NameValueCollection
params.Add("category", "13")
params.Add("fileName", fileName)
params.Add("share", "no")
request.contents = buildMultiPart(params, boundary, "application/pdf", "file", fileName)
Return http.sendRequestMPF(request, fileLocation)
End Function
The rest of the code needed can be found on their GitHub https://github.com/BambooHR