I'm trying to upload a file to a .NET Core API using VBA code from a Word template. When the API receives the request, the file has a length of 0 and therefore any file I send to it becomes useless. I've uploaded files successfully to the same API using an Angular client instead of VBA, so I believe the problem lies within my VBA code. I've tested it with both .txt and .pdf files and the result is the same, 0 length file is received in the API (the end goal is to be able to upload a PDF file).
Do you see what's wrong with the code I'm using? Please see below. Any help is greatly appreciated.
Sub UploadBinary()
Const path = "C:\Users\REDACTED\VBA Upload Test\"
Const fileName = "testfile.txt"
Const CONTENT = "text/plain"
Const URL = "https://localhost:44327/api/fileUpload"
' generate boundary
Dim BOUNDARY, s As String, n As Integer
For n = 1 To 16: s = s & Chr(65 + Int(Rnd * 25)): Next
BOUNDARY = s & CDbl(Now)
Dim part As String, ado As Object
Dim header As String
' read file
Dim FILE, FILESIZE
Set ado = CreateObject("ADODB.Stream")
ado.Type = 1 'binary
ado.Open
ado.LoadFromFile path & fileName
ado.Position = 0
FILESIZE = ado.Size
FILE = ado.Read
ado.Close
Debug.Print "filesize", FILESIZE
part = "--" & BOUNDARY & vbCrLf
part = part & "Content-Disposition: form-data; name=""file""; filename=""" & fileName & """" & vbCrLf
part = part & "Content-Type: " & CONTENT & vbCrLf
part = part & "Content-Length: " & FILESIZE & vbCrLf & vbCrLf & vbCrLf
part = part & "--" & BOUNDARY & "--" & vbCrLf
header = "Content-Type" & ": " & "multipart/form-data; boundary=" & BOUNDARY
Debug.Print (header)
Debug.Print (part)
' combine part, fl , end
ado.Open
ado.Position = 0
ado.Type = 1 ' binary
ado.Write ToBytes(part)
ado.Write FILE
ado.Write ToBytes(vbCrLf & "--" & BOUNDARY & "---")
ado.Position = 0
Debug.Print ado.Size
'ado.savetofile "c:\tmp\debug.bin", 2 ' overwrite
' send request
'With CreateObject("WinHttp.WinHttpRequest.5.1")
With CreateObject("MSXML2.ServerXMLHTTP")
.Open "POST", URL, False
.SetRequestHeader "Content-Type", "multipart/form-data; boundary=" & BOUNDARY
.Send ado.Read
ado.Close
Debug.Print .ResponseText
End With
End Sub
Function ToBytes(str As String) As Variant
Dim ado As Object
Set ado = CreateObject("ADODB.Stream")
ado.Open
ado.Type = 2 ' text
ado.Charset = "_autodetect"
ado.WriteText str
ado.Position = 0
ado.Type = 1
ToBytes = ado.Read
ado.Close
End Function